SQL 인젝션에 대해서 알아보자 !
1. 개념
SQL 인젝션(SQL Injection)은 웹 애플리케이션에서 사용자 입력을 제대로 검증하지 않고 SQL 쿼리에 포함시킬 때 발생하는 보안 취약점. 공격자가 의도적으로 악의적인 SQL 구문을 삽입해서 데이터베이스를 조작, 조회, 변경, 또는 삭제할 수 있다.
2. 📌 어떻게 발생하나?
예를 들어 아래와 같은 코드가 있다고 해보면
SELECT * FROM users WHERE username = '$username' AND password = '$password';
만약 사용자가 입력한 값이
username: admin
password: ' OR '1'='1
이렇게 들어오면 최종 쿼리는 다음과 같이 된다.
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';
이 쿼리는 항상 참이 되는 조건을 포함하므로, 비밀번호를 몰라도 로그인에 성공한다.
3. 🔥 공격의 종류
종류 | 설명 |
인증 우회 | 위 예시처럼 로그인 우회를 시도함. |
데이터 유출 | UNION 등을 이용해 다른 테이블의 데이터까지 가져옴. |
데이터 변조 | UPDATE, DELETE, INSERT 구문을 삽입해 데이터를 바꿈. |
DB 정보 탐색 | information_schema를 조회해서 테이블 구조나 컬럼명을 알아냄. |
4. 💣 실제 예시
🔎 예시: 검색 기능에서 발생(php)
$keyword = $_GET['search'];
$sql = "SELECT * FROM products WHERE name LIKE '%$keyword%'";
여기에 검색어로 %' OR '1'='1을 넣으면
SELECT * FROM products WHERE name LIKE '%%' OR '1'='1%'
모든 제품이 검색되거나, 의도치 않은 정보가 노출될 수 있다.
5. ✅ 방어 방법
- Prepared Statements (매개변수 바인딩) 사용
언어별로 지원되는 바인딩 기능을 꼭 쓰는 편이 좋다.
PHP (PDO 예시)
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
Java (JDBC 예시)
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username = ? AND password = ?");
stmt.setString(1, username);
stmt.setString(2, password);
- ORM 사용
JPA, Hibernate, Django ORM, Sequelize 등 대부분의 ORM은 SQL 인젝션을 자동으로 방지함.
- 입력값 검증 및 이스케이핑
입력값에서 불필요한 특수문자를 필터링하거나, DB에 맞는 escape 처리를 추가함.
- 최소 권한 원칙
DB 계정에 최소한의 권한만 부여해서 피해를 줄일 수 있다. 예를 들어 웹 애플리케이션이 SELECT만 필요하다면 DELETE 권한은 주지 않는 식으로.
6. 🧪 탐지와 테스트
Burp Suite, sqlmap 같은 도구를 사용하면 SQL 인젝션 테스트를 자동화할 수 있다.
"'", "--", " OR 1=1" 같은 패턴을 입력해서 반응을 관찰하는 것도 흔한 방법.
끝
'개발 > ETC' 카테고리의 다른 글
SQL에서 NOT IN 쓰다 피본 적 있다면 꼭 알아야 할 내용 (30) | 2025.05.30 |
---|---|
템플릿 메소드 패턴 (86) | 2025.05.20 |
NoSQL DB 종류 알아보기 (39) | 2025.05.18 |
결합도 공부 (67) | 2025.05.08 |
이진 트리 공부 (74) | 2025.04.30 |