형식이 지정된 쿼리는 유지보수 및 디버깅이 어려울 수 있으며, 신뢰할 수 없는 값을 쿼리와 결합할 때 SQL Injection 위험을 증가시킬 수 있습니다. 하지만, 이 규칙은 {rule:javasecurity:s3649} 과는 달리 SQL Injection 을 감지하지 않으며, 복잡하고 형식이 지정된 쿼리를 강조하는 것이 목표입니다.
스스로에게 자문하세요
- 쿼리의 일부는 신뢰할 수 없는 값(사용자 입력과 같은)에서 가져옵니다.
- 쿼리가 코드의 다른 부분에서 반복 또는 중복됩니다.
- 애플리케이션은 서로 다른 유형의 관계형 데이터베이스를 지원해야 합니다.
이러한 질문에 예라고 답하는 경우 문제가 발생할 수 있습니다.
추천되는 안전한 코딩 관습
- parameterized queries, prepared statements, stored procedures 를 사용하고, 변수를 SQL 쿼리 파라미터에 바인딩합니다.
- 데이터에 액세스하기 위해 추상 계층이 필요한 경우 ORM 프레임워크 사용을 고려하세요.
민감한 코드의 예
public User getUser(Connection con, String user) throws SQLException {
Statement stmt1 = null;
Statement stmt2 = null;
PreparedStatement pstmt;
try {
stmt1 = con.createStatement();
ResultSet rs1 = stmt1.executeQuery("GETDATE()"); // 문제 없음; 하드코딩된 쿼리
stmt2 = con.createStatement();
ResultSet rs2 = stmt2.executeQuery("select FNAME, LNAME, SSN " +
"from USERS where UNAME=" + user); // 민감한 코드
pstmt = con.prepareStatement("select FNAME, LNAME, SSN " +
"from USERS where UNAME=" + user); // 민감한 코드
ResultSet rs3 = pstmt.executeQuery();
//...
}
public User getUserHibernate(org.hibernate.Session session, String data) {
org.hibernate.Query query = session.createQuery(
"FROM students where fname = " + data); // Sensitive
// ...
}
규칙을 준수한 해결책
public User getUser(Connection con, String user) throws SQLException {
Statement stmt1 = null;
PreparedStatement pstmt = null;
String query = "select FNAME, LNAME, SSN " +
"from USERS where UNAME=?"
try {
stmt1 = con.createStatement();
ResultSet rs1 = stmt1.executeQuery("GETDATE()");
pstmt = con.prepareStatement(query);
pstmt.setString(1, user); // 좋은 코드; PreparedStatements 은 인풋을 escape 처리합니다.
ResultSet rs2 = pstmt.executeQuery();
//...
}
}
public User getUserHibernate(org.hibernate.Session session, String data) {
org.hibernate.Query query = session.createQuery("FROM students where fname = ?");
query = query.setParameter(0,data); // Good; Parameter binding escapes all input
org.hibernate.Query query2 = session.createQuery("FROM students where fname = " + data); // 민감한 코드
// ...
참고
- OWASP Top 10 2021 Category A3 - Injection
- OWASP Top 10 2017 Category A1 - Injection
- MITRE, CWE-89 - Improper Neutralization of Special Elements used in an SQL Command
- MITRE, CWE-564 - SQL Injection: Hibernate
- MITRE, CWE-20 - Improper Input Validation
- MITRE, CWE-943 - Improper Neutralization of Special Elements in Data Query Logic
- CERT, IDS00-J. - Prevent SQL injection
- SANS Top 25 - Insecure Interaction Between Components
- Derived from FindSecBugs rules Potential SQL/JPQL Injection (JPA), Potential SQL/JDOQL Injection (JDO), Potential SQL/HQL Injection (Hibernate)
If you like SONARKUBE, don’t forget to give me a star.