SQL 인젝션 방어 전략: OWASP와 CISA 권고사항 활용하기
작성자: 니콜 홀든 | 2024년 4월 29일
SQL 인젝션(SQL Injection, SQLi)은 사용자 입력이 SQL 명령과 분리되지 않을 때 발생할 수 있는 대표적인 데이터베이스 보안 위협입니다. 이 글에서는 OWASP와 미국 사이버보안 및 인프라 보안국(CISA)의 권고사항을 바탕으로 입력 검증, 데이터 이스케이핑, 매개변수화된 쿼리, 코드 리뷰, 최소 권한 원칙을 살펴봅니다. PostgreSQL과 EDB Postgres Advanced Server(EPAS)에서 활용할 수 있는 방어 기능도 함께 소개합니다.
SQL 인젝션의 위험성과 주요 사례
2024년 3월, CISA는 SQL 인젝션과 관련해 디자인부터 안전: 소프트웨어에서 SQL 인젝션 취약점 제거라는 권고문을 발표했습니다.
CISA에 따르면 SQL 인젝션 취약점은 사용자 입력을 SQL 명령에 직접 삽입해 공격자가 임의의 쿼리를 실행할 수 있게 하는 문제입니다. 데이터베이스 쿼리와 사용자 제공 데이터가 안전하게 분리되지 않을 때 이러한 취약점이 발생할 수 있습니다.
SQL 인젝션이 악용되면 공격자는 민감한 데이터에 무단으로 접근하거나 데이터베이스 내용을 변경할 수 있으며, 일부 환경에서는 서버에서 임의의 명령을 실행할 수도 있습니다. 그 결과 고객 정보 유출, 금전적 손실, 평판 훼손 및 규제 제재와 같은 심각한 피해가 발생할 수 있습니다.
1. 민감한 데이터 유출 및 인증 우회
공격자는 SQL 인젝션을 통해 사용자 이름이나 비밀번호 등 민감한 개인정보를 탈취할 수 있습니다. 로그인 시스템의 취약점을 악용해 정상적인 인증 절차를 거치지 않고 관리자 권한 획득을 시도할 수도 있습니다.
2. 데이터베이스 조작
공격자는 SQL 인젝션을 이용해 데이터를 삽입, 수정 또는 삭제하거나 전체 데이터베이스의 삭제를 시도할 수 있습니다.
3. 시스템 명령 실행
일부 데이터베이스 환경에서는 SQL 인젝션 취약점을 통해 운영체제 명령 실행이 가능할 수 있습니다. 공격자는 이를 악용해 악성 코드를 설치하거나 시스템 파일을 삭제하는 등의 명령을 시도할 수 있습니다.
실제 SQL 인젝션 사례
2017년 미국의 신용평가 회사 Equifax에서는 1억 4,300만 명의 고객 데이터가 유출됐습니다. 2014년 Yahoo 역시 약 5억 개의 사용자 계정이 노출되는 대규모 데이터 유출 사고를 겪었습니다.
SQL 인젝션 사례의 공통점
- 대부분 입력값 검증 부족이나 보안 설정 미비로 인해 발생합니다.
- 금융, 교육, IT 등 다양한 산업에서 발생하며 민감한 데이터 유출로 이어질 수 있습니다.
- 피해 규모가 크고 기업의 평판과 재무 상태에 심각한 영향을 줄 수 있습니다.
SQL 인젝션은 여전히 많은 조직에 심각한 위협으로 작용합니다. 이를 방지하려면 입력값 검증, 준비된 명령문, 매개변수화된 쿼리 및 최소 권한 원칙 등의 방어 전략을 함께 적용해야 합니다.
OWASP와 CISA가 권고하는 SQL 인젝션 방어 전략
CISA뿐만 아니라 OWASP(Open Worldwide Application Security Project)도 SQL 인젝션 방지를 위한 지침을 지속적으로 제공합니다. 입력 검증, 신뢰할 수 없는 데이터 이스케이핑, 준비된 명령문, 저장 프로시저 및 코드 리뷰는 SQL 인젝션과 그로 인한 피해를 방지하는 데 도움이 될 수 있습니다.
데이터베이스 요청을 보내는 서비스 계정과 애플리케이션에 최소 권한 원칙을 적용하면 SQL 인젝션 공격이 발생했을 때 피해 범위를 줄일 수 있습니다. EDB Postgres Advanced Server(EPAS) 사용자는 SQL Protect와 Privilege Analysis를 이러한 보안 관행과 함께 활용할 수 있습니다.
입력 검증
입력 검증을 SQL 인젝션 방지의 주된 수단으로 사용해서는 안 되지만, 데이터 흐름의 초기 단계에서 위험을 줄이는 데 활용할 수 있습니다.
OWASP는 입력 검증을 구문적 검증(syntactic validation)과 의미적 검증(semantic validation)으로 구분합니다. 구문적 검증은 구조화된 필드가 올바른 형식을 따르도록 하고, 의미적 검증은 해당 값이 특정 비즈니스 맥락에 적합한지 확인합니다.
PostgreSQL 체크 제약 조건 활용
언어별 입력 검증과 함께 데이터베이스를 설계할 때 체크 제약 조건(check constraints)을 사용하는 것도 추가적인 방어 계층이 될 수 있습니다.
PostgreSQL 문서에 따르면 체크 제약 조건은 특정 열의 값이 부울 표현식을 충족하도록 지정하는 일반적인 제약 조건입니다. 다음 예시는 제품 가격이 양수여야 한다는 조건을 적용합니다.
/* 양수 제품 가격을 요구하는 체크 제약 조건 추가 */
CREATE TABLE products (
productnum integer,
name text,
price numeric CHECK (price > 0)
);
기존 데이터베이스에서도 ALTER TABLE을 사용해 제약 조건을 관리할 수 있습니다. ADD table_constraint, ALTER CONSTRAINT, DROP CONSTRAINT 등의 하위 명령이 이를 지원합니다.
신뢰할 수 없는 데이터 이스케이핑
OWASP의 데이터 인코딩 및 이스케이핑 체크리스트는 이스케이핑을 SQL 인젝션 같은 공격을 방지하기 위해 데이터를 안전한 형식으로 처리하는 방법으로 설명합니다. 이스케이핑에는 검증된 라이브러리가 제공하는 함수를 사용하는 것이 좋습니다.
PostgreSQL libpq 이스케이핑 함수
PostgreSQL C 라이브러리인 libpq에는 명령 실행 함수와 함께 사용할 수 있는 내장 이스케이핑 함수가 포함되어 있습니다. PQescapeLiteral은 SQL 명령에 포함할 문자열을 이스케이핑할 때 사용합니다.
공식 libpq 문서에 따르면 이 함수는 SQL 명령에 데이터 값을 리터럴 상수로 삽입할 때 유용합니다. 따옴표나 백슬래시처럼 SQL 파서가 특별하게 해석할 수 있는 문자를 안전하게 처리합니다.
libpq는 이 밖에도 여러 이스케이핑 함수를 제공합니다. PQescapeByteaConn은 이진 데이터를 이스케이핑하는 데 사용되며, PQescapeIdentifier는 테이블 이름과 같은 SQL 식별자로 사용될 문자열을 이스케이핑합니다. 입력 검증과 마찬가지로 이스케이핑 로직을 직접 구현하기보다 용도에 맞는 내장 함수를 사용하는 것이 권장됩니다.
준비된 명령문과 매개변수화된 쿼리
CISA는 SQL 인젝션을 방어하는 주요 접근 방식으로 매개변수화된 쿼리를 권장합니다. 소프트웨어를 설계하고 개발할 때 준비된 명령문을 사용하는 매개변수화된 쿼리로 SQL 코드와 사용자 제공 데이터를 분리해야 한다는 내용입니다.
이러한 분리는 시스템이 사용자 입력을 실행 가능한 코드가 아닌 데이터로 처리하게 합니다. 따라서 악의적인 사용자 입력이 SQL 명령으로 해석될 위험을 줄일 수 있습니다.
- 매개변수화된 쿼리(parameterized query): SQL 문과 값을 분리해 전달하고, 값이 들어갈 위치에는 자리표시자를 사용하는 쿼리입니다.
- 준비된 명령문(prepared statement): 매개변수를 전달받아 실행할 수 있도록 미리 준비된 쿼리입니다.
- 저장 프로시저(stored procedure): 애플리케이션에서 자주 사용하는 쿼리 시퀀스를 데이터베이스에 저장한 명령 집합입니다.
준비된 명령문과 저장 프로시저는 SQL 인젝션 방어에 함께 활용할 수 있습니다. 저장 프로시저는 재사용 가능한 코드와 유지보수 편의성을 제공하며, 프로시저가 수행할 작업을 제어해 데이터베이스 객체를 보호하고 보안 관리를 단순화할 수 있습니다.
보안 코드 리뷰
코드 리뷰에는 단독 리뷰, 페어 프로그래밍, 소규모 팀 리뷰, 크로스 펑셔널 리뷰 등 다양한 방법을 적용할 수 있습니다. 어떤 방식을 선택하더라도 보안 코딩 요구사항을 기준으로 검토하면 SQL 인젝션 방어 관행을 일관되게 구현하는 데 도움이 됩니다.
코드 리뷰의 목표는 코드 품질을 높이고 팀의 협업을 촉진하는 것입니다. 동시에 보안 관행에 대한 책임을 특정 담당자에게만 맡기지 않고 팀 전체가 공유하도록 할 수 있습니다.
최소 권한 원칙
최소 권한 원칙(Principle of Least Privilege)은 사용자나 애플리케이션에 작업 수행에 필요한 최소한의 접근 권한만 부여하는 보안 원칙입니다. SQL 인젝션 공격의 영향을 제한하려면 데이터베이스 사용자와 애플리케이션에 SQL 쿼리 실행과 데이터 접근에 필요한 권한만 제공해야 합니다.
예를 들어 사용자가 특정 테이블의 데이터를 읽기만 해야 한다면 전체 데이터베이스에 대한 읽기·쓰기 권한 대신 해당 테이블의 읽기 전용 권한만 부여할 수 있습니다. 이렇게 하면 SQL 인젝션 공격이 발생하더라도 피해 범위를 제한할 수 있습니다.
최소 권한 원칙은 저장 프로시저와도 함께 적용할 수 있습니다. 특정 데이터베이스 작업을 저장 프로시저로 정의하고 해당 프로시저의 실행 권한만 부여하면 기본 테이블에 대한 직접 접근을 제한할 수 있습니다.
EDB SQL Protect와 Privilege Analysis
EDB Postgres Advanced Server(EPAS)는 앞서 설명한 SQL 인젝션 방어 관행과 함께 활용할 수 있는 도구와 기능을 제공합니다.
SQL Protect
SQL Protect는 들어오는 쿼리를 검사하고 서명을 사용해 잠재적인 공격을 식별합니다. 보호된 역할을 기반으로 쿼리를 모니터링하며, 공격 시도에 대한 통계와 기록도 제공합니다.
SQL Protect는 악성 쿼리가 탐지됐을 때 경고를 보내도록 구성할 수 있어 공격 시도에 대응하는 데 활용할 수 있습니다.
Privilege Analysis
Privilege Analysis는 EPAS v16에 도입된 기능으로, 불필요하게 부여된 권한을 식별하는 데 도움을 줍니다.
이 기능은 사용 중인 권한과 사용되지 않는 권한을 분석합니다. 관리자는 분석 결과를 바탕으로 각 사용자가 업무 수행에 필요한 권한과 접근 범위만 보유하고 있는지 확인할 수 있습니다.
결론
SQL 인젝션은 여전히 널리 발생할 수 있는 치명적인 취약점이지만, 이를 방지하기 위한 검증된 방법도 존재합니다. 매개변수화된 쿼리와 준비된 명령문을 중심으로 입력 검증, 신뢰할 수 있는 이스케이핑 함수, 코드 리뷰 및 최소 권한 원칙을 함께 적용해야 합니다.
CISA 권고문은 투명성과 소프트웨어 보안에 대한 책임을 포함해 보안 목표를 달성할 수 있는 조직 구조를 구축하는 일도 강조합니다. 향후 게시물에서는 거버넌스가 보안 관행을 지원하는 과정에서 마주하는 과제와 중요성, 새로운 보안 권고 및 규정에 관한 정보를 추가로 공유할 예정입니다.
SQL 인젝션 FAQ
SQL 인젝션은 얼마나 위험한 보안 위협인가요?
SQL 인젝션은 사용자 입력을 SQL 명령에 직접 삽입할 때 발생할 수 있는 보안 위협입니다. 공격자는 이를 악용해 민감한 정보에 접근하거나 데이터를 수정·삭제하고, 일부 환경에서는 시스템 명령 실행을 시도할 수 있습니다.
SQL 인젝션 방어에 가장 중요한 방법은 무엇인가요?
CISA는 SQL 코드와 사용자 제공 데이터를 분리하는 매개변수화된 쿼리와 준비된 명령문의 사용을 권장합니다. 입력 검증, 신뢰할 수 있는 이스케이핑 함수, 코드 리뷰, 최소 권한 원칙도 함께 적용해야 합니다.
입력 검증만으로 SQL 인젝션을 방지할 수 있나요?
입력 검증은 데이터 흐름의 초기 단계에서 위험을 줄이는 보조 방어 수단이지만, 단독으로 사용해서는 안 됩니다. 매개변수화된 쿼리와 준비된 명령문을 중심으로 여러 방어 계층을 함께 구성해야 합니다.
PostgreSQL에서는 신뢰할 수 없는 데이터를 어떻게 이스케이핑하나요?
PostgreSQL C 라이브러리인 libpq는 PQescapeLiteral, PQescapeByteaConn, PQescapeIdentifier 등의 내장 함수를 제공합니다. 용도에 맞는 내장 함수를 사용하고 이스케이핑 로직을 직접 구현하지 않는 것이 권장됩니다.
EDB EPAS는 SQL 인젝션 방어에 어떤 기능을 제공하나요?
EDB Postgres Advanced Server는 잠재적인 공격을 식별하고 모니터링하는 SQL Protect를 제공합니다. EPAS v16에 도입된 Privilege Analysis는 사용 중이거나 사용되지 않은 권한을 분석해 최소 권한 원칙을 적용하는 데 도움을 줍니다.
원문: Protecting Against SQL Injection
EDB 영업 기술 문의: 02-501-5113