常见漏洞修复代码
SQL 注入漏洞修复代码 预编译处理
public class UserDao {
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static final String DATABASE_URL = "jdbc:mysql://localhost:3306/myDB";
public List<User> getUsers(String userName, String password) {
List<User> users = new ArrayList<>();
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
// 使用 try-with-resources 语句自动关闭资源
try (Connection conn = this.createConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
//设置参数值,参数索引从1开始
pstmt.setString(1, userName);
pstmt.setString(2, password);
//执行查询
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
User user = new User();
// 设置 user 的值 ...
users.add(user);
}
} catch (SQLException e) {
// Log error
}
return users;
}
private Connection createConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection(DATABASE_URL, USERNAME, PASSWORD);
} catch (Exception e) {
// Log error
return null;
}
}
}
XSS 漏洞修复代码 HTML 实体编码
import org.apache.commons.text.StringEscapeUtils;
public class XSSPrevention {
public String secureOutput(String unsafeInput){
if(unsafeInput == null || unsafeInput.length() == 0) {
// 如果为空,就不需要编码
return unsafeInput;
}
String safeOutput = StringEscapeUtils.escapeHtml4(unsafeInput);
return safeOutput;
}
}
文件上传漏洞修复代码
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class FileUploadHandler {
private static final long MAX_FILE_SIZE = 10 * 1024 * 1024; // 可配置的文件大小限制
private static final String UPLOAD_DIRECTORY = "/path/to/uploads"; // 可配置的上传目录
private static final Set<String> ALLOWED_EXTENSIONS = new HashSet<>(Arrays.asList(".jpg", ".png"));
public void handleFileUpload(MultipartFile file) {
if (validateFile(file)) {
// 生成文件名
String extension = getFileExtension(file);
String filename = UUID.randomUUID().toString() + extension;
// 存储路径
Path filePath = Paths.get(UPLOAD_DIRECTORY, filename);
// 上传文件
try {
file.transferTo(filePath);
} catch (IOException e) {
throw new RuntimeException("文件读写异常", e);
}
}
}
public boolean validateFile(MultipartFile file) {
try {
// 检查文件是否为空
if (file.isEmpty()) {
throw new IllegalArgumentException("文件不能为空");
}
// 检查文件的大小
if (file.getSize() > MAX_FILE_SIZE) {
throw new IllegalArgumentException("文件过大");
}
// 检查文件的扩展名
String extension = getFileExtension(file);
if (!ALLOWED_EXTENSIONS.contains(extension)) {
throw new IllegalArgumentException("不支持的文件扩展名");
}
// 检查文件的MIME类型
String mimeType = file.getContentType();
if (!mimeType.startsWith("image/")) {
throw new IllegalArgumentException("文件必须是图像");
}
// 检查文件的内容, 确认其实际为一个图像
BufferedImage image = ImageIO.read(file.getInputStream());
if (image == null) {
throw new IllegalArgumentException("文件内容不符合图像格式");
}
return true;
} catch (IOException e) {
throw new RuntimeException("无法验证文件", e);
}
}
public String getFileExtension(MultipartFile file) {
String name = file.getOriginalFilename();
return name.substring(name.lastIndexOf("."));
}
}
SSRF 漏洞修复代码
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;
public class UrlValidator {
private final Predicate<String> hostFilter; // 允许访问的主机列表
private final Predicate<String> pathFilter; // 允许的URL路径列表
private static final Set<String> ALLOWED_PROTOCOLS = new HashSet<>(Arrays.asList("http", "https")); // 允许的协议
private static final Logger LOG = Logger.getLogger(UrlValidator.class.getName());
public UrlValidator(Predicate<String> hostFilter, Predicate<String> pathFilter) {
this.hostFilter = hostFilter;
this.pathFilter = pathFilter;
}
public boolean isSafe(String urlString) {
try {
// 验证URL格式
URL url = new URL(urlString);
// 验证协议
if (!ALLOWED_PROTOCOLS.contains(url.getProtocol())) {
LOG.log(Level.WARNING, "无效的协议: " + url.getProtocol());
return false;
}
// 验证主机名
if (!hostFilter.test(url.getHost())) {
LOG.log(Level.WARNING, "主机名不在白名单: " + url.getHost());
return false;
}
// 验证路径
if (!pathFilter.test(url.getPath())) {
LOG.log(Level.WARNING, "路径不在白名单: " + url.getPath());
return false;
}
return true;
} catch (Exception e) {
LOG.log(Level.WARNING, "无法解析URL: " + urlString, e);
return false;
}
}
}
// 使用举例
public class UrlHandler {
private final UrlValidator urlValidator; // 注入UrlValidator
public UrlHandler(UrlValidator urlValidator){
this.urlValidator = urlValidator;
}
public void processUrl(String urlString){
if (urlValidator.isSafe(urlString)) {
// 发送请求
} else {
throw new IllegalArgumentException("非法的URL: " + urlString);
}
}
}
条件竞争漏洞修复代码
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class BankAccount {
private volatile double balance; // 账户余额
private final Lock lock = new ReentrantLock();
public BankAccount(double balance) {
this.balance = balance;
}
// 提现功能
public void withdraw(double amount) {
lock.lock(); // 获得锁
try {
if (balance < amount) {
System.out.println("余额不足,无法提现!");
return;
}
balance -= amount;
System.out.println("提现成功,提现金额:" + amount + ",剩余余额:" + balance);
} finally {
lock.unlock(); // 释放锁
}
}
// 获取余额
public double getBalance() {
return balance;
}
}
原文始发于微信公众号(利刃信安攻防实验室):【修复代码】常见漏洞修复代码
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论