docs(zh-CN): sync Chinese docs with latest upstream changes

This commit is contained in:
neo
2026-03-21 12:55:58 +08:00
parent 0af0fbf40b
commit e73c2ffa34
85 changed files with 11028 additions and 747 deletions

View File

@@ -0,0 +1,101 @@
---
paths:
- "**/*.java"
---
# Java 安全
> 本文档在 [common/security.md](../common/security.md) 的基础上,补充了 Java 相关的内容。
## 密钥管理
* 切勿在源代码中硬编码 API 密钥、令牌或凭据
* 使用环境变量:`System.getenv("API_KEY")`
* 生产环境密钥请使用密钥管理器(如 Vault、AWS Secrets Manager
* 包含密钥的本地配置文件应放在 `.gitignore`
```java
// 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
* 对用于原生查询的任何输入进行验证和清理
```java
// 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`
* 在使用文件路径和用户提供的字符串前,对其进行清理
* 对于验证失败的输入,应拒绝并提供清晰的错误信息
```java
// 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 错误
* 在处理器边界将异常映射为安全、通用的客户端消息
* 在服务器端记录详细错误;向客户端返回通用消息
```java
// 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`