SQL 인젝션(SQL Injection) 은 웹 애플리케이션에서 사용자의 입력값이 SQL 쿼리에 안전하게 처리되지 않을 때 발생하는 보안 취약점입니다. 공격자는 이 취약점을 이용해 쿼리를 조작하여 인증을 우회하거나, 데이터를 조작하거나, 테이블 자체를 삭제할 수도 있습니다.
예를 들어, 로그인 검증 시 아래와 같은 코드를 사용한다고 가정해 보겠습니다.
public boolean login(String username, String password) {
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
try (Connection conn = DriverManager.getConnection("url");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
return rs.next();
} catch (SQLException e) {
throw new RuntimeException("Database error", e);
}
}
사용자가 로그인 폼에 아래와 같이 입력한다면
username: admin' --
password: (아무거나)
생성되는 쿼리는 다음과 같이 변형됩니다.
SELECT * FROM users WHERE username = 'admin' -- ' AND password = '1q2w3e4r!';
-- 이후는 주석 처리되므로, 비밀번호 조건은 무시되어 admin 사용자에 대한 정보가 반환됩니다. 이처럼 공격자는 SQL 쿼리를 조작하여 인증을 우회하거나 데이터베이스의 정보를 탈취할 수 있습니다.
이 외에도 공격자는 다음과 같은 페이로드를 사용할 수 있습니다.
- ' OR '1'='1: 항상 참이 되는 조건
- ' UNION SELECT * FROM accounts --: 다른 테이블의 정보 조회
- '; DROP TABLE users; --: 테이블 삭제
SQL 인젝션을 방지하는 방법은 무엇인가요?
- PreparedStatement를 사용하면 place holder(?)에 값을 바인딩하고 내부적으로 이스케이프 처리하기 때문에 SQL 인젝션을 방지할 수 있습니다.
String sql = "SELECT * FROM users WHERE username = ? AND password = ?"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, username); pstmt.setString(2, password);- JPA, Hibernate와 같은 ORM 프레임워크를 사용하면 SQL 쿼리를 직접 작성하지 않고도 데이터베이스와 상호작용할 수 있습니다.
- 사용자 입력에 대해 공격에 사용되는 SQL 구문의 포함 여부를 검증합니다.
- 웹 애플리케이션에서 사용하는 데이터베이스 계정에 최소한의 권한만 부여합니다.
- SQL 오류나 예외 메시지를 사용자에게 직접 노출하지 않도록 합니다.
LIST
'Spring & Backend' 카테고리의 다른 글
| ✅ 클라이언트 사이드 라우팅(Client-Side Routing) 동작 과정 (2) | 2025.08.21 |
|---|---|
| 최종적 일관성이란 무엇인가요? (0) | 2025.08.21 |
| HTTP의 ETag에 대해서 설명해주세요. (0) | 2025.08.19 |
| 테스트 격리란 무엇인가요? (0) | 2025.08.19 |
| NoSQL 데이터베이스의 유형에는 어떤 것들이 있나요? (10) | 2025.08.18 |
