安全编码规范
Java安全编码规范
1. 输入验证
不安全的输入验证
// 不安全的输入验证示例
public class UnsafeInputValidation {
public void processUserInput(String input) {
// 直接使用用户输入,没有验证
String sql = "SELECT * FROM users WHERE name = '" + input + "'";
executeQuery(sql);
}
public void displayUserInput(String input) {
// 直接输出用户输入,没有转义
response.getWriter().write(input);
}
}
安全的输入验证
// 安全的输入验证示例
public class SecureInputValidation {
// 使用预编译语句防止SQL注入
public void processUserInput(String input) {
String sql = "SELECT * FROM users WHERE name = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, input);
stmt.executeQuery();
}
// 使用OWASP HTML Sanitizer防止XSS
public void displayUserInput(String input) {
PolicyFactory policy = Sanitizers.FORMATTING.and(Sanitizers.BLOCKS);
String safeInput = policy.sanitize(input);
response.getWriter().write(safeInput);
}
// 使用正则表达式验证输入格式
public boolean validateEmail(String email) {
return email.matches("^[A-Za-z0-9+_.-]+@(.+)$");
}
// 使用白名单验证输入
public boolean validateInput(String input, Set<String> whitelist) {
return whitelist.contains(input);
}
}
2. 密码学使用
不安全的密码学使用
// 不安全的密码学使用示例
public class UnsafeCryptography {
// 使用不安全的MD5算法
public String hashPassword(String password) {
MessageDigest md = MessageDigest.getInstance("MD5");
return new String(md.digest(password.getBytes()));
}
// 使用ECB模式
public byte[] encryptData(byte[] data, Key key) {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
}
安全的密码学使用
// 安全的密码学使用示例
public class SecureCryptography {
// 使用安全的密码哈希算法
public String hashPassword(String password) {
return BCrypt.hashpw(password, BCrypt.gensalt(12));
}
// 使用安全的加密模式
public byte[] encryptData(byte[] data, Key key) {
// 生成随机IV
byte[] iv = new byte[16];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
// 使用CBC模式
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
// 组合IV和密文
byte[] encrypted = cipher.doFinal(data);
byte[] combined = new byte[iv.length + encrypted.length];
System.arraycopy(iv, 0, combined, 0, iv.length);
System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);
return combined;
}
// 安全的密钥生成
public Key generateKey() {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // 使用256位密钥
return keyGen.generateKey();
}
}
3. 异常处理
不安全的异常处理
// 不安全的异常处理示例
public class UnsafeExceptionHandling {
public void processData() {
try {
// 处理数据
} catch (Exception e) {
// 直接打印堆栈跟踪
e.printStackTrace();
// 暴露敏感信息
response.getWriter().write("Error: " + e.getMessage());
}
}
}
安全的异常处理
// 安全的异常处理示例
public class SecureExceptionHandling {
private static final Logger logger = LoggerFactory.getLogger(SecureExceptionHandling.class);
public void processData() {
try {
// 处理数据
} catch (SQLException e) {
// 记录详细日志
logger.error("Database error occurred", e);
// 返回通用错误信息
throw new ServiceException("A database error occurred");
} catch (IOException e) {
// 记录详细日志
logger.error("IO error occurred", e);
// 返回通用错误信息
throw new ServiceException("An IO error occurred");
} catch (Exception e) {
// 记录详细日志
logger.error("Unexpected error occurred", e);
// 返回通用错误信息
throw new ServiceException("An unexpected error occurred");
}
}
// 自定义异常类
public class ServiceException extends RuntimeException {
public ServiceException(String message) {
super(message);
}
}
}