현재 선택한 정보보안 과정

정보보안기사 필기 이론 학습

이론 목록으로 돌아가기

SQL 삽입과 안전한 질의

문자열 결합과 매개변수 바인딩의 차이, Blind 유형과 대응을 이해합니다.

예상 읽기 4

1. SQL 삽입의 성립 조건

SQL 삽입(SQL Injection)은 외부 입력을 데이터로 처리하지 않고 SQL 문자열 구조에 결합하여 DB가 코드 일부로 해석하게 만드는 취약점이다. 입력에 작은따옴표가 있다는 사실보다 질의 구조와 값이 분리되어 있는지가 중요하다.

PYTHON코드 영역 안에서 좌우로 이동할 수 있습니다.
# 취약한 문자열 결합 예시
sql = "SELECT id, name FROM member WHERE name = '" + name + "'"
cur.execute(sql)

외부 값이 로그인 폼에만 들어오는 것은 아니다. 검색어·URL·쿠키·헤더 등 SQL 생성에 도달하는 입력도 대상이 된다. 영향은 실제 질의와 DB 계정 권한에 따라 정보 노출·변경·삭제 등으로 달라진다.

2. 매개변수 바인딩

Prepared Statement·Parameterized Query는 SQL 구조를 정의하고 외부 값은 별도 매개변수로 전달한다.

PYTHON코드 영역 안에서 좌우로 이동할 수 있습니다.
# Python sqlite3 예시: cur는 준비된 DB 커서
name = "O'Reilly"
cur.execute(
    "SELECT id, name FROM member WHERE name = ?",
    (name,)
)

작은따옴표가 포함된 정상 이름도 하나의 값으로 처리한다. 이를 위해 이름에서 작은따옴표를 제거할 필요가 없다. 괄호 안 (name,)은 원소가 하나인 튜플이며 ?에 대응하는 값을 전달한다.

DB API마다 ?, :name, $1 등 표기가 다르다. 특정 기호를 사용했는지보다 API를 통해 구조와 값을 분리했는지를 확인한다. 값을 먼저 문자열에 넣고 그 문자열을 prepare하면 원인이 남는다.

3. 식별자와 정렬 방향은 허용 목록으로 선택한다

일반적으로 테이블·열 이름, ASC·DESC 같은 SQL 구조는 값 매개변수처럼 바인딩할 수 없다. 외부 문자열을 바로 연결하지 않고 개발자가 정한 후보로 매핑한다.

PYTHON코드 영역 안에서 좌우로 이동할 수 있습니다.
sort_map = {"name": "name ASC", "newest": "created_at DESC"}
order_clause = sort_map.get(user_sort)
if order_clause is None:
    raise ValueError("허용되지 않은 정렬 기준")
sql = "SELECT id, name FROM member ORDER BY " + order_clause
cur.execute(sql)

최종 질의에 들어가는 것은 사용자가 임의로 만든 SQL이 아니라 고정된 두 후보 중 하나다. 일반 검색 조건의 값은 계속 매개변수 바인딩을 사용한다.

4. 관찰 방식에 따른 공격 유형

유형구분 기준
UNION 기반다른 조회 결과가 원래 결과에 결합되어 응답에 노출
오류 기반DB 오류에서 구조·데이터 단서를 획득
Boolean 기반 Blind페이지·성공 여부 등 반응 차이로 참·거짓 추론
Time 기반 Blind조건에 따른 응답시간 차이로 추론

UNION 기반과 오류 기반은 같은 요청·응답 경로에서 결과를 확인하는 In-band의 대표 형태다. Blind는 값을 직접 출력하지 않아도 반응으로 알아내는 방식이다. 따라서 오류 페이지를 숨겼다고 SQL 삽입이 사라지는 것은 아니다.

5. 저장 프로시저·ORM의 한계

저장 프로시저도 내부에서 입력을 연결하여 동적 SQL로 실행하면 취약할 수 있다. ORM도 raw SQL이나 질의 문자열에 입력을 직접 붙이면 안전하지 않다.

입력 형식·길이·범위 검증은 필요하지만 바인딩을 대체하지 않는다. 이스케이프나 금지 문자열 목록은 DBMS·문맥 차이와 누락이 있으므로 근본 대응으로만 의존하지 않는다.

6. 예방과 피해 제한을 구분한다

통제역할
매개변수 질의·고정 질의 구조입력이 SQL 문법이 되는 원인 제거
최소 DB 권한취약점 발생 시 접근·변경 피해 제한
일반화된 외부 오류구조·데이터 단서 노출 감소
안전한 내부 로그진단·반복 이상 시도 추적
WAF일부 공격 패턴의 추가 탐지·차단

조회만 필요한 응용 계정에 계정 생성·권한 변경·테이블 삭제 권한을 주지 않는다. 로그에도 비밀번호·세션·DB 접속 비밀값을 남기지 않는다. WAF·오류 숨김·최소 권한만 적용한 채 위험한 문자열 결합을 유지하지 않는다.

스스로 확인하기

개념 확인 문제

문제를 누르면 바로 아래에서 정답과 해설을 확인할 수 있습니다.

01정렬 열 이름을 값 매개변수 하나로 바인딩하면 되는가?
정답 및 해설

일반적으로 열 이름·정렬 방향은 값처럼 바인딩할 수 없다. 외부 선택값을 개발자가 정한 고정 식별자·정렬식 목록에 매핑하고 일반 조건 값은 바인딩한다.

02DB 오류 메시지를 숨기면 SQL 삽입이 제거되는가?
정답 및 해설

아니다. 정보 노출은 줄지만 Boolean·시간 차이로 결과를 추론하는 Blind가 가능할 수 있다. 질의 구조와 값을 분리하는 근본 수정이 필요하다.