导航菜单

安全编码规范

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);
    }
  }
}