SQL Injection 공격 원리와 데이터베이스 방어 전략

SQL Injection의 공격 방식과 침입 징후, 매개변수 바인딩·입력값 검증·최소 권한 기반 방어 전략을 정리한다.

2026-08-14 · 최초 발행 2025-05-29

입력값이 쿼리의 일부가 될 때 생기는 문제

SQL Injection은 웹 애플리케이션이 받은 파라미터를 변조해 SQL 쿼리를 재구성하고, 데이터베이스에 비정상적으로 접근하려는 공격 기법이다. 인증 우회, 데이터 유출·조작·삭제, 시스템 명령 실행이 목적이 될 수 있다.

문제의 출발점은 사용자 입력값이 적절한 검증 없이 SQL 쿼리에 직접 결합되는 구조다. 이 공격은 여전히 OWASP Top 10 웹 취약점 목록에서 높은 순위를 차지하며, 수많은 데이터 유출 사고의 원인이 되어왔다.

공격자는 자동화 도구와 스크립트로 취약점을 스캔하고 공격을 실행할 수 있다. 일반 요청과 비슷하게 보이는 경우가 있어 로그에서 식별하기 어렵고, 데이터베이스 내용의 삭제나 변조로 이어질 위험도 있다. 하나의 취약점으로 수천 개의 웹사이트를 동시에 공격할 가능성도 있다.

인증 우회와 오류 노출을 이용하는 방식

로그인 입력값으로 조건식을 바꾸는 인증 우회는 SQL Injection의 기본적인 형태다.

-- 원래 쿼리
SELECT * FROM users WHERE username='input_username' AND password='input_password';

-- 공격 예시: username 필드에 ' OR '1'='1 입력 시
SELECT * FROM users WHERE username='' OR '1'='1' AND password='input_password';

이 공격이 성공하면 '1'='1'은 항상 참이므로 첫 번째 사용자(주로 관리자)로 로그인된다.

오류 기반 주입은 데이터베이스가 반환하는 오류 메시지에서 구조 정보를 수집한다. 입력 필드에 ' 또는 " 같은 특수문자를 넣어 오류를 유도하고, 메시지에 드러난 테이블명·컬럼명·데이터베이스 종류를 활용한다.

-- 공격 예시: id 파라미터에 ' 입력 시
SELECT * FROM products WHERE id=''';

위 쿼리는 구문 오류를 발생시키며, 오류 메시지에 데이터베이스 정보가 포함될 수 있다.

응답 차이로 정보를 추론하는 Blind SQL Injection

오류 메시지나 직접적인 결과를 볼 수 없을 때는 조건의 참·거짓 또는 쿼리 실행 시간 차이를 이용한다. Boolean-based 방식은 조건 결과로 정보를 한 비트씩 추출하고, Time-based 방식은 실행 시간의 차이로 정보를 추출한다.

-- Boolean-based 예시
' OR (SELECT ASCII(SUBSTRING(username,1,1)) FROM users WHERE id=1) > 100 --

-- Time-based 예시
' OR IF((SELECT ASCII(SUBSTRING(username,1,1)) FROM users WHERE id=1) > 100, SLEEP(5), 0) --

다수 테이블을 겨냥하는 대량 삽입

Mass SQL Injection은 한 번의 공격으로 다수의 데이터베이스 테이블을 감염시키는 기법이다. 웹사이트의 모든 페이지에 악성 스크립트를 넣는 데 활용될 수 있으며, 방문자 개인정보 탈취나 악성코드 배포가 목적이 된다.

취약한 웹사이트 검색공격자대량 SQL Injection 공격다수 DB 테이블 감염악성 스크립트 삽입방문자 정보 탈취악성코드 배포

침입 흔적과 취약점 확인

침입 여부는 데이터베이스와 웹 로그를 함께 봐야 한다. 데이터베이스에서는 테이블 변경 사항, 예상치 못한 새 관리자 계정, 비정상적인 쿼리 로그를 검토한다.

웹 로그에서는 SQL 구문이 포함된 비정상적인 파라미터를 찾는다. ', ", ;, --, /**/ 등의 특수문자가 들어간 요청과 비정상적인 접근 패턴도 분석 대상이다.

취약점 점검은 수동과 자동 방식으로 나눌 수 있다. 수동 점검에서는 입력 필드에 ', ", ; 같은 특수문자를 넣고, OR 1=1처럼 SQL 쿼리 논리를 변경하는 구문을 테스트하며 오류 메시지를 분석한다. 자동 점검에는 SQLmap, OWASP ZAP, Burp Suite 등의 보안 테스트 도구와 자동화된 취약점 스캐너를 활용하고, 정기적인 보안 점검을 수행한다.

쿼리와 데이터를 분리하는 방어

매개변수 바인딩은 SQL 쿼리와 데이터를 분리해 처리하는 가장 효과적인 방어 방법이다.

// 취약한 코드
String query = "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'";

// 안전한 코드 (Java 예시)
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username=? AND password=?");
stmt.setString(1, username);
stmt.setString(2, password);

입력값은 허용된 문자와 패턴만 받는 화이트리스트 방식으로 검증하고, 특수문자를 이스케이프 처리하며, 길이도 제한한다.

// JavaScript 예시
function validateInput(input) {
  // 알파벳, 숫자만 허용
  return /^[a-zA-Z0-9]+$/.test(input);
}

서버 측에서는 웹 애플리케이션 방화벽(WAF)을 도입하고, ModSecurity 같은 오픈소스 필터나 SQL Injection 시그니처 기반 필터링을 적용할 수 있다.

데이터베이스 사용자에게는 필요한 최소한의 권한만 부여한다. 웹 애플리케이션 전용 DB 계정을 사용하고, 중요 데이터에 접근할 때는 추가 인증을 요구한다. 상세 오류 정보는 사용자에게 노출하지 않고, 사용자 정의 오류 페이지를 제공하며, 디버깅 정보는 로그에만 기록한다.

검증 실패검증 성공사용자 입력입력값 검증오류 메시지매개변수 바인딩SQL 쿼리 실행결과 반환로깅 모니터링

데이터 유출 사고에서 드러난 영향

Sony Pictures는 2011년 SQL Injection 취약점을 이용한 공격으로 100만 명 이상의 사용자 정보가 탈취되었다. 해시되지 않은 비밀번호, 이메일, 집 주소 등 민감한 정보가 포함되었다.

Yahoo에서는 2012년 약 45만 개의 사용자 계정 정보가 SQL Injection을 통해 유출되었다. 해시된 비밀번호와 이메일 주소가 공개되었다.

Heartland Payment Systems는 2008년 SQL Injection으로 1억 3천만 개의 신용카드 정보가 도난당한 대형 데이터 유출 사고를 겪었다. 당시 피해액은 약 1억 4천만 달러로 추산되었다.

지속적으로 점검해야 할 데이터베이스 접근 경로

SQL Injection은 단순한 형태로 시작할 수 있지만, 방어가 없으면 심각한 데이터 유출과 재정적 손실로 이어진다. 매개변수화된 쿼리, 입력값 검증, 최소 권한 원칙을 함께 적용하고 데이터베이스 접근 로직을 주기적으로 검토해야 한다.

SQL Injection웹 보안데이터베이스 보안입력값 검증보안 취약점