mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-30 13:43:26 +08:00
3.4 KiB
3.4 KiB
paths
| paths | |
|---|---|
|
Java 安全
本文档在 common/security.md 的基础上,补充了 Java 相关的内容。
密钥管理
- 切勿在源代码中硬编码 API 密钥、令牌或凭据
- 使用环境变量:
System.getenv("API_KEY") - 生产环境密钥请使用密钥管理器(如 Vault、AWS Secrets Manager)
- 包含密钥的本地配置文件应放在
.gitignore中
// BAD
private static final String API_KEY = "sk-abc123...";
// GOOD — environment variable
String apiKey = System.getenv("PAYMENT_API_KEY");
Objects.requireNonNull(apiKey, "PAYMENT_API_KEY must be set");
SQL 注入防护
- 始终使用参数化查询——切勿将用户输入拼接到 SQL 语句中
- 使用
PreparedStatement或你所使用框架的参数化查询 API - 对用于原生查询的任何输入进行验证和清理
// BAD — SQL injection via string concatenation
Statement stmt = conn.createStatement();
String sql = "SELECT * FROM orders WHERE name = '" + name + "'";
stmt.executeQuery(sql);
// GOOD — PreparedStatement with parameterized query
PreparedStatement ps = conn.prepareStatement("SELECT * FROM orders WHERE name = ?");
ps.setString(1, name);
// GOOD — JDBC template
jdbcTemplate.query("SELECT * FROM orders WHERE name = ?", mapper, name);
输入验证
- 在处理前,于系统边界处验证所有用户输入
- 使用验证框架时,在 DTO 上使用 Bean 验证(
@NotNull,@NotBlank,@Size) - 在使用文件路径和用户提供的字符串前,对其进行清理
- 对于验证失败的输入,应拒绝并提供清晰的错误信息
// Validate manually in plain Java
public Order createOrder(String customerName, BigDecimal amount) {
if (customerName == null || customerName.isBlank()) {
throw new IllegalArgumentException("Customer name is required");
}
if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("Amount must be positive");
}
return new Order(customerName, amount);
}
认证与授权
- 切勿自行实现认证加密逻辑——请使用成熟的库
- 使用 bcrypt 或 Argon2 存储密码,切勿使用 MD5/SHA1
- 在服务边界强制执行授权检查
- 清理日志中的敏感数据——切勿记录密码、令牌或个人身份信息
依赖项安全
- 运行
mvn dependency:tree或./gradlew dependencies来审计传递依赖项 - 使用 OWASP Dependency-Check 或 Snyk 扫描已知的 CVE
- 保持依赖项更新——设置 Dependabot 或 Renovate
错误信息
- 切勿在 API 响应中暴露堆栈跟踪、内部路径或 SQL 错误
- 在处理器边界将异常映射为安全、通用的客户端消息
- 在服务器端记录详细错误;向客户端返回通用消息
// Log the detail, return a generic message
try {
return orderService.findById(id);
} catch (OrderNotFoundException ex) {
log.warn("Order not found: id={}", id);
return ApiResponse.error("Resource not found"); // generic, no internals
} catch (Exception ex) {
log.error("Unexpected error processing order id={}", id, ex);
return ApiResponse.error("Internal server error"); // never expose ex.getMessage()
}
参考
关于 Spring Security 认证与授权模式,请参见技能:springboot-security。
关于通用安全检查清单,请参见技能:security-review。