SQL 삽입 공격 (SQL Injection) 완벽 가이드

1. SQL 삽입 공격이란?

SQL 삽입(SQL Injection)은 웹 애플리케이션 등에서 사용자 입력값을 데이터베이스 SQL 쿼리에 직접 연결할 때 발생하는 보안 취약점을 이용한 공격 기법입니다. 공격자는 조작된 입력값을 통해 악의적인 SQL 코드를 삽입하여 데이터베이스 쿼리의 구조를 변경합니다. 이를 통해 인증 우회, 민감 정보 탈취, 데이터 변조 등 다양한 비인가 작업을 수행할 수 있습니다.

2. 주요 위험성

  • 데이터 유출: 사용자 계정, 비밀번호, 신용카드 정보 등 민감한 데이터가 외부로 노출될 수 있습니다.
  • 데이터 손상: 테이블이나 레코드가 임의로 수정, 삭제되어 시스템 무결성이 파괴됩니다.
  • 인증 우회: 로그인 절차 없이 관리자 권한을 획득하거나 다른 사용자로 위장할 수 있습니다.
  • 서버 장악: 데이터베이스를 발판 삼아 애플리케이션 서버 자체를 공격할 수 있습니다.
  • 서비스 거부(DoS): 과도한 쿼리 실행으로 데이터베이스 자원을 고갈시켜 정상 서비스를 방해합니다.

3. 공격 유형별 예시

3.1. 에러 기반 공격

쿼리 문법 오류를 유발하여 데이터베이스 에러 메시지로부터 정보를 얻습니다.

SELECT * FROM users WHERE username = 'admin' OR '1'='1' --' AND password = 'xyz'

3.2. 부울 기반 공격

참/거짓 결과를 반환하는 조건문을 삽입하여 데이터를 추측합니다.

SELECT * FROM products WHERE name LIKE '%iPhone%' AND (1=1 OR (SELECT COUNT(*) FROM users) > 0)

3.3. 시간 기반 공격

데이터베이스 응답 지연(예: WAITFOR DELAY)을 이용해 참/거짓을 판별합니다.

SELECT * FROM products WHERE id = 1; WAITFOR DELAY '00:00:05'

3.4. 블라인드 SQL 인젝션

화면에 직접적인 결과가 표시되지 않을 때, 반복적인 질의로 한 글자씩 데이터를 알아냅니다.

SELECT * FROM users WHERE id = 1 AND (SELECT SUBSTRING(password,1,1) FROM users WHERE id=1) = 'a'

3.5. 스택 쿼리(Stacked Queries) 공격

세미콜론(;)으로 여러 쿼리를 연결하여 삭제나 수정 등 추가 작업을 실행합니다.

SELECT * FROM products WHERE id = 1; DROP TABLE users; SELECT * FROM products WHERE id = 2

4. 방어 기법

4.1. 파라미터화된 쿼리 (Prepared Statements)

사용자 입력을 SQL 코드가 아닌 데이터 값으로 처리합니다. 가장 효과적인 1차 방어선입니다.

// 예시 (Java JDBC)
String sql = "SELECT * FROM users WHERE username = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, userInput);
ResultSet rs = pstmt.executeQuery();

4.2. 입력값 검증 및 필터링

허용된 문자(예: 숫자만, 이메일 형식)만 통과시키고 나머지는 차단합니다.

// 예시 (PHP)
if (!ctype_digit($id)) {
    die("잘못된 입력입니다.");
}

4.3. 최소 권한 원칙

애플리케이션에서 사용하는 데이터베이스 계정에 SELECT 등 꼭 필요한 권한만 부여하고 DROP, DELETE 등 위험한 작업은 제한합니다.

4.4. ORM(Object-Relational Mapping) 사용

MyBatis, Hibernate, Entity Framework 등 ORM 프레임워크는 대부분 자체적으로 파라미터 바인딩을 지원하여 SQL 인젝션 위험을 크게 줄여줍니다.

4.5. 이스케이프 처리

파라미터화된 쿼리를 사용할 수 없는 레거시 환경에서는 특수 문자를 안전하게 이스케이프합니다. 단, 이것만으로는 완벽하지 않으므로 다른 기법과 병행해야 합니다.

5. 종합 권장 사항

SQL 인젝션을 완벽히 차단하려면 단일 방어책에 의존하지 말고 파라미터화된 쿼리, 입력 검증, 최소 권한, 정기적인 보안 업데이트를 다중 계층으로 적용해야 합니다. 또한 정기적인 취약점 스캔과 코드 리뷰를 통해 숨겨진 취약점을 조기에 발견하고 패치하는 것이 중요합니다.

태그: SQL Injection Prepared Statement OWASP Database Security Web Vulnerability

7월 3일 19:47에 게시됨