SQL 인젝션 (SQL Injection, SQLi) 기초
SQL 인젝션은 웹 애플리케이션의 입력 필드(로그인 창, 검색 창 등)를 통해 공격자가 악의적인 SQL 구문을 서버로 보내 데이터베이스를 비정상적으로 조작하는 공격 기법입니다.
이 공격은 웹 애플리케이션과 데이터베이스 사이의 무결성과 기밀성을 위협합니다.
1. 작동 원리: 입력값과 코드의 혼동
SQL 인젝션은 사용자 입력값이 서버에서 실행되는 SQL 코드의 일부로 해석될 때 발생합니다.
① 취약한 코드 예시 (PHP/Python)
사용자 입력(user_id)을 아무런 검증 없이 바로 SQL 구문에 삽입하는 경우입니다.
// "user_id"는 사용자가 입력한 값
query = "SELECT * FROM users WHERE id = '" + user_id + "';"
② 공격 시나리오 (로그인 우회)
공격자가 ID 입력란에 다음과 같은 문자열을 입력합니다.
입력값: admin' OR '1'='1
서버에서 완성되는 SQL 구문은 다음과 같습니다.
SELECT * FROM users WHERE id = 'admin' OR '1'='1';
- 해석:
'1'='1'은 항상 참(True)이므로,id가admin이 아니더라도 이 SQL 조건문은 참이 됩니다. - 결과: 공격자는 비밀번호를 몰라도 관리자(admin) 계정으로 로그인에 성공합니다.
2. SQLi 공격의 위험성
- 인증 우회 (Authentication Bypass): 로그인 과정 무력화 (위 예시)
- 데이터 탈취:
UNION구문을 사용하여 다른 테이블의 모든 데이터(개인 정보, 비밀번호)를 외부로 유출. - 데이터 위변조 및 삭제:
UPDATE또는DROP TABLE명령을 주입하여 데이터베이스 내용을 변경하거나 파괴.
3. SQLi 방어 방법 (개발자 관점)
SQL 인젝션 방어의 핵심은 사용자 입력과 SQL 코드를 완전히 분리하는 것입니다.
- 준비된 구문 (Prepared Statements) 또는 매개변수화된 쿼리 (Parameterized Queries):
- 가장 효과적인 방어책입니다. SQL 구문과 사용자 입력 데이터를 분리하여 처리하도록 DBMS(데이터베이스 관리 시스템)에 지시합니다. DBMS는 입력값을 절대 코드로 해석하지 않고, 순수한 데이터로만 취급합니다.
- 입력 값 유효성 검사 (Input Validation):
- 입력 단계에서 허용된 문자만 있는지, 길이가 적절한지 등을 엄격하게 검사합니다.
- 최소 권한의 원칙:
- 웹 애플리케이션이 데이터베이스에 접속할 때, 필요한 최소한의 권한(예: SELECT만 허용)만 부여합니다.