Korean only
This page is available in Korean only. An English version will be added later.
03. SQL Injection
info
모든 실습은 00. 실습 원칙과 범위 에 따라 허가된 로컬 환경(01. 실습 환경 구축)에서만 수행한다.
1. 원리: 왜 생기는가
SQL Injection은 사용자 입력이 SQL 쿼리 문자열에 그대로 끼어들어, 데이터가 아니라 쿼리 구문의 일부로 해석될 때 발생한다.
안전: 입력은 "데이터"로만 전달 → 쿼리 구조가 고정
취약: 입력을 쿼리 문자열에 이어 붙임 → 입력이 구조를 바꿀 수 있음
// 취약: 입력을 문자열로 직접 연결
$sql = "SELECT * FROM users WHERE id = '" . $_GET['id'] . "'";
위 코드는 입력이 작은따옴표를 포함하면 쿼리 구조 자체가 바뀔 수 있다.
영향: 인증 우회, 데이터 유출·변조, 경우에 따라 시스템 명령 실행까지.
2. 실습 (로컬, 고수준)
DVWA의 SQL Injection 메뉴에서, 입력이 쿼리 구문에 영향을 주는지를 확인하는 수준으로 진행한다.
- 입력란에 작은따옴표(
') 하나를 넣었을 때 DB 오류 메시지가 뜨는지 본다. 오류가 뜬다면 입력이 쿼리에 그대로 들어가고 있다는 신호다. - 오류 메시지에 쿼리 구조나 DB 종류가 노출되는지 확인한다. (정보 노출 자체가 취약점)
warning
공개 문서에는 취약 여부 확인(오류 유발, 정보 노출 확인)까지만 기록한다. 실제 데이터 대량 추출이나 인증 우회를 재현하는 구체적 구문은 게시하지 않는다. 원리와 대응이 목적이다.
DVWA 난이도 비교
// Low: 입력을 그대로 연결 → 취약
$sql = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
// 안전: 파라미터화(Prepared Statement)
$stmt = $pdo->prepare('SELECT first_name, last_name FROM users WHERE user_id = ?');
$stmt->execute([$id]);
3. AI로 해석하기
- "이 DB 오류 메시지가 무엇을 의미하는지, 어떤 정보가 노출됐는지 설명해 줘"
- "이 코드에서 입력이 쿼리 구조에 영향을 줄 수 있는 지점은 어디인가?"
- "이 취약한 쿼리를 파라미터화 방식으로 바꾸면 어떻게 되는가?"
:::tip AI 활용 포인트 오류 메시지 해석과 취약 코드 → 안전 코드 리팩터링은 AI가 잘 돕는 영역이다. 단, AI가 제시한 안전 코드도 로컬에서 직접 동작과 안전성을 확인한 뒤 기록한다. :::
4. 대응
| 대응 | 설명 |
|---|---|
| 파라미터화 쿼리 / Prepared Statement | 입력을 데이터로만 전달. 가장 핵심이고 확실한 대응 |
| ORM 사용 | ORM의 파라미터 바인딩을 그대로 활용 (문자열 조합 쿼리 지양) |
| 최소 권한 | DB 계정에 필요한 권한만 부여 (유출·변조 피해 축소) |
| 오류 메시지 숨김 | 운영 환경에서 상세 DB 오류를 사용자에게 노출하지 않기 |
| 입력 검증 | 타입·형식 검증 (보조 수단) |
// 핵심: 파라미터화
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);
5. 점검 체크리스트
- 모든 쿼리가 파라미터화되어 있는가 (문자열 연결 쿼리 없음)
- DB 계정이 최소 권한으로 설정되어 있는가
- 운영 환경에서 상세 DB 오류가 노출되지 않는가
- ORM 사용 시 raw 쿼리에 입력을 직접 넣지 않았는가
참고
- OWASP: SQL Injection
- OWASP: SQL Injection Prevention Cheat Sheet