[JAVA]JAVA실무

[JAVA]보안취약점 조치 예시(기초) PMD

greeniti 2025. 3. 22. 13:04

보안 취약점이 포함된 Java 코드 예제와 PMD가 이를 탐지했을 때의 수정한 코드 예시 입니다. 

기초적인 내용이므로 참고만 하시기 바랍니다. 실무에서는 거의 조치되어 수정할 일이 없습니다. 

 


1. SQL Injection 취약점 수정

🔴 취약한 코드 (PMD 경고 발생)

public void vulnerableSQL(String userInput) {
    String query = "SELECT * FROM users WHERE username = '" + userInput + "'"; // 위험
    Statement stmt = connection.createStatement();
    ResultSet rs = stmt.executeQuery(query);
}

✅ 수정된 코드 (PreparedStatement 사용)

public void secureSQL(String userInput) throws SQLException {
    String query = "SELECT * FROM users WHERE username = ?";
    PreparedStatement pstmt = connection.prepareStatement(query);
    pstmt.setString(1, userInput);
    ResultSet rs = pstmt.executeQuery();
}

🔹 수정 이유:

  • PreparedStatement를 사용하면 SQL Injection 방지가 가능합니다.
  • PMD 규칙: security:AvoidUsingHardCodedSQL

2. 하드코딩된 비밀번호 제거

🔴 취약한 코드 (PMD 경고 발생)

public class HardcodedPassword {
    private static final String PASSWORD = "12345"; // 위험
}

✅ 수정된 코드 (환경 변수 사용)

public class SecurePassword {
    private static final String PASSWORD = System.getenv("DB_PASSWORD");
}

🔹 수정 이유:

  • 환경 변수에서 비밀번호를 가져와 하드코딩을 방지함.
  • PMD 규칙: security:HardCodedCredential

3. 취약한 암호화 알고리즘 수정

🔴 취약한 코드 (PMD 경고 발생)

import java.security.MessageDigest;

public class WeakHash {
    public static String hashPassword(String password) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5"); // 위험
        md.update(password.getBytes());
        return new String(md.digest());
    }
}

✅ 수정된 코드 (SHA-256 사용)

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class SecureHash {
    public static String hashPassword(String password) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(password.getBytes());
        return Base64.getEncoder().encodeToString(md.digest());
    }
}

🔹 수정 이유:

  • MD5는 취약하므로 SHA-256으로 변경.
  • PMD 규칙: security:InsecureCryptoAlgorithm

4. 불안전한 객체 역직렬화 수정

🔴 취약한 코드 (PMD 경고 발생)

import java.io.ObjectInputStream;
import java.io.FileInputStream;

public class UnsafeDeserialization {
    public static Object deserialize(String filename) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename)); // 위험
        return ois.readObject();
    }
}

✅ 수정된 코드 (ObjectInputFilter 적용)

import java.io.ObjectInputStream;
import java.io.FileInputStream;
import java.io.ObjectInputFilter;

public class SafeDeserialization {
    public static Object deserialize(String filename) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));
        ois.setObjectInputFilter(filterInfo -> 
            filterInfo.serialClass() != null && filterInfo.serialClass().getName().startsWith("com.safe"));
        return ois.readObject();
    }
}

🔹 수정 이유:

  • ObjectInputFilter를 사용하여 허용된 클래스만 역직렬화하도록 제한.
  • PMD 규칙: security:InsecureDeserialization

📌 결론

PMD는 코드 내 보안 취약점을 찾아내고, 이를 방지할 수 있도록 가이드합니다.
SQL Injection → PreparedStatement 사용
하드코딩된 비밀번호 → 환경 변수 사용
취약한 해시 알고리즘 → SHA-256 사용
불안전한 역직렬화 → ObjectInputFilter 적용