개념 사전 · 개념

SQL 인젝션

SQL Injection · SQLi · 에스큐엘 인젝션

은 외부 입력이 의 데이터가 아니라 쿼리 문법으로 해석될 때 생기는 취약점이다. 값 과 구조의 을 분리하면 입력이 쿼리 구조를 바꾸는 경로를 차단할 수 있다.

밑줄 용어에 마우스를 올리거나, 키보드로 선택하거나, 터치하면 설명을 볼 수 있습니다.

01무엇이고, 어떤 일을 하나

  • 문자열 연결 지점에서 데이터와 명령의 경계를 찾는다.
  • DB 계정 권한과 애플리케이션 권한의 차이를 분석한다.
  • 매개변수화 후에도 정상 검색 의미와 권한 제한이 유지되는지 검증한다.

02어떤 순서로 동작하나

  1. 요청값 수신

    서버가 GET·POST·세션 등 실제 입력 위치를 읽고 필요한 정규화와 형식 검증을 수행한다.

  2. 쿼리 구조 결정

    개발자가 고정한 구조를 선택한다. 문자열 연결 방식은 외부 값이 문법에 들어갈 수 있는 지점이다.

  3. 매개변수 전달

    prepare/execute 등 드라이버가 지원하는 인터페이스로 값을 전달한다. 값 을 테이블명·정렬 구문에 대신 쓰지 않는다.

  4. DB 권한으로 실행

    DB가 애플리케이션 계정의 권한 안에서 문장을 처리한다. 가 DB의 모든 권한을 자동으로 우회하는 것은 아니다.

  5. 행과 응답 처리

    결과 행을 업무 규칙에 맞게 사용하고 안전하게 출력한다. 단순히 행이 있다는 이유만으로 비밀번호 검증을 대신하지 않는다.

03먼저 알아둘 용어와 구성요소

쿼리 구조를 준비하고 값은 별도 매개변수로 전달하는 방식.
입력을 문법이 아닌 값으로 연결하는 처리.
오류나 결과가 직접 보이지 않아도 조건에 따른 응답 차이로 영향을 추정하는 유형.
정렬 열처럼 값 이 불가능한 구조를 미리 정한 선택지에서 고르는 방식.
데이터 저장·조회·권한·을 관리하는 데이터베이스 시스템.
열·테이블 이름 등 구조의 일부로 값 매개변수와 처리 방식이 다르다.
값 뒤에도 패턴 검색에서 의미가 남는 %·_ 등의 문자.
LEARN THROUGH PRACTICE

DVWA의 문자열 결합 쿼리와 결과 열을 연결하기

입력→ 문자열→DB 결과→화면의 연결을 읽고, 매개변수 이 바꾸는 경계를 설명한다.

실습 구성과 전제

  • 격리된 의 폐기 가능한 데이터베이스를 사용한다.
  • 사진은 구형 · 코드다. 현재 서비스에 복사하지 않고 원리 비교 자료로만 읽는다.
  1. 입력이 SQL 문법 안으로 들어가는 위치를 찾는다

    • 소스에서 GET의 id를 읽은 뒤 WHERE user_id = '$id'에 그대로 넣는 흐름을 따라간다. 따옴표와 변수 값이 하나의 문자열로 합쳐진다.
    • mysql_query 계열은 구형 API다. 보안 교정은 다른 함수 이름으로 바꾸는 것만이 아니라 값과 쿼리 구조를 분리해야 한다.
    SQL Injection 실습 · 실습환경 (2)원본 크기로 보기 ↗
    • $_GET['id']가 SELECT 문자열에 연결되고 mysql_query로 실행된다.
    • 반복문은 결과 열 first_name·last_name을 화면에 출력한다. DB 결과의 두 열과 표시 위치를 연결할 수 있다.
    확인 기준

    문자열 결합 지점과 출력 지점을 각각 표시한다.

  2. 결과 열의 모양이 유지되는 이유를 읽는다

    • 교육 화면은 UNION으로 결합된 두 열이 기존 이름·성 표시 위치에 나타나는 사례다. 결과 집합의 열 수와 호환 가능한 형식이 맞아야 결합될 수 있다.
    • 조회에 사용하는 DB 계정의 권한이 넓으면 애플리케이션이 의도하지 않은 자료도 결과에 섞일 수 있다. 화면의 테스트 해시를 다시 배포하지 않는다.
    SQL Injection 실습 · 실습환경 (4)원본 크기로 보기 ↗
    • User ID 입력 뒤 여러 행이 표시되고 First name·Surname 위치에 계정명과 해시 형태의 값이 나타난다.
    • 표시 레이블은 여전히 이름·성이다. 화면 레이블이 데이터의 실제 의미나 안전성을 보증하지 않는다.
    확인 기준

    한 결과 화면만으로 데이터베이스 전체 권한이나 모든 공격 유형의 성공을 일반화하지 않는다.

  3. 정상 조회를 유지하면서 구조를 고정한다

    • 준비된 쿼리의 값 자리에 사용자 입력을 바인딩한다. 정렬 열처럼 바인딩할 수 없는 구조는 으로 고른다.
    • 정상 ID·존재하지 않는 ID·따옴표 포함 입력을 비교하고 오류 내용이나 다른 행이 노출되지 않는지 확인한다.
    cursor.execute('SELECT first_name, last_name FROM users WHERE user_id = %s', (user_id,))

    DB-API 드라이버가 %s 을 지원한다는 조건의 비교 코드. 문자열 포매팅으로 직접 치환하지 않는다.

    확인 기준

    정상 기능이 유지되고 입력이 쿼리 문법으로 해석되지 않아야 한다.

실습에서 확인한 동작 원리

  • UNION 결과는 기존 출력 열을 통해 보일 수 있다.
  • 과 DB 최소 권한은 서로 다른 방어층이다.
관련 개념·전체 실습 화면 이어서 읽기 →
동작·명령 참고 문서

04예제로 따라가기

  • 조회 구조: 가상 쿼리는 SELECT id FROM people WHERE name = ? 이고 값은 O'Reilly라고 가정한다.
  • 결과: 작은따옴표는 문자열 값의 일부로 전달된다. 사용자가 보낸 문자 때문에 WHERE 뒤의 구조가 새로 만들어지지 않는다.
  • 패턴 검색: 쿼리를 name LIKE ?로 바꾸고 A%를 전달하면 A로 시작하는 이름을 찾는다. 이는 정상 LIKE 의미이며 주입 성공의 증거가 아니다.
  • 리터럴 요구: 실제 A%라는 이름만 찾으려면 DB의 ESCAPE 문법과 애플리케이션 정책에 맞춰 패턴 특수 문자를 처리해야 한다.
  • 관찰 결과: 결과 행· 값·고정 쿼리 형태를 비교한다. 오류가 안 났다는 사실만으로 쿼리 구조가 안전하게 고정되었는지 알 수는 없다.

05혼동하기 쉬운 점과 확인 기준

  • API 혼용: 일부 조건은 바인딩하면서 정렬·검색 연산자·조건 조각을 외부 입력으로 연결하고 있지 않은지 최종 쿼리 구성을 본다.
  • 타입 변환: 문자열과 숫자의 자동 변환·NULL·빈 문자열이 DB별로 다르게 비교될 수 있다. 타입과 업무 규칙을 입력 검증에 명시한다.
  • 연결 설정: 문자셋·드라이버의 에뮬레이션 설정·다중 문장 허용 등 실제 연결 옵션을 확인한다. 다른 환경의 결과를 그대로 적용하지 않는다.

06상세 노트 · 실습 자료

헤더 구조, 설정 예시, 수치 계산과 수업 캡처는 아래 노트에서 이어집니다.

READ · OBSERVE · CONNECT

함께 보는 학습 자료

아래 공식 자료를 본문의 개념·예제와 함께 읽어 보세요. 자료별로 확인할 위치와 관찰할 내용을 적었습니다.

공식 가이드

OWASP: 값 바인딩과 SQL 구조의 경계

안전한 PreparedStatement 예제와 동적 테이블 이름 예제를 대조하여 값 이 가능한 부분을 구분한다.

읽으면서 확인할 것
  • 질의 틀과 setString 등 값 전달의 분리
  • 테이블·열·정렬 방향의 허용목록
  • 저장 프로시저 내부 동적 의 예외

공식 문서 · 표준

기초 개념과 동작 설명을 대조한 자료입니다. 제품 버전과 실제 설정에 따른 차이는 본문 및 원문에서 확인하세요.