💡 핵심 인사이트 DB 방화벽(Database Firewall)은 **"데이터베이스에 접근하는 SQL 트래픽을가로채어, 사전에 정의된 보안 정책 위반 여부를リアルタイム檢查하고 공격을 차단하는 미들웨어"**입니다. SQL 인젝션(SQL Injection)은 이 DB 방화벽이防止하는 대표적인 공격 유형으로, **"사용자 입력을 SQL 查询에そのまま 삽입하여 数据库를Manipulate하는 해킹 기법"**입니다. OWASP Top 10에서 매년 반복되는常習犯であり、入力 검증不足から生みます。


Ⅰ. SQL 인젝션의 원리: 입력이 명령이 되는 순간

[SQL 인젝션 원리]

  정상な入力:
  사용자: "김철수" 검색
  SQL: SELECT * FROM users WHERE name = '김철수'
  결과: 김철수인 사용자 정보 반환

  SQL 인젝션 공격:
  공격자: "' OR '1'='1" 입력  ← 쿼리 문법 변화!
  SQL: SELECT * FROM users WHERE name = '' OR '1'='1'
  의미: '1'='1'은 항상 TRUE
  결과: users 테이블 전체 데이터 반환 (認証 bypass!)

SQL 인젝션의 4가지 유형

[SQL 인젝션 유형]

  1. In-Band SQLi (일반적)
     - 공격자가 같은 채널로 데이터 추출
     - 에러 메시지를利用한 In-Band
     - Union 쿼리를利用한 In-Band

  2. Blind SQLi (블라인드)
     - 에러 메시지 없음
     - "TRUE면 페이지 정상, FALSE면 다르게 표시" 利用
     - 시간 기반 (SLEEP() 利用) 블라인드

  3. Out-of-Band SQLi
     - 정상 채널 대신 우회 채널 (DNS, HTTP 요청)
     - 블라인드 환경에서 우회 채널로 데이터 탈취

  4. Second-Order SQLi
     - 악성 입력 저장 → لاحق에 다른 요청에서 실행
     - 즉각 실행이 아닌 "지연된 인젝션"

실제 공격 코드 예시:

# 취약한 코드 (Python + SQLite)
user_input = request.form['username']
query = f"SELECT * FROM users WHERE username = '{user_input}'"
# 공격자가 username에 "admin' --" 입력 시
# query = "SELECT * FROM users WHERE username = 'admin' --'"
# -- 이후는 주석처리 → 비밀번호 검증 우회!

# UNION 인젝션 (데이터 탈취)
# "' UNION SELECT credit_card FROM payments --"
# → 기존 쿼리 결과 + 카드번호 테이블 합산

Ⅱ. DB 방화벽의 작동 원리

[DB 방화벽 아키텍처]

  Application                    DBMS
     │                           │
     │ SELECT * FROM users...    │
     │ ───────────────────────► │  (클라이언트 → DB 직접 아닌)
     │                           │
     │      ┌────────────────────┤
     │      │                    │
     │      ▼                    │
     │ ┌─────────────┐            │
     │ │ DB Firewall │            │
     │ │             │            │
     │ │ 1. SQL 파싱 │            │
     │ │ 2. 정책 체크 │            │
     │ │ 3. 공격 탐지 │            │
     │ │ 4. 로깅/경고 │            │
     │ │ 5. 차단/허용 │            │
     │ └─────────────┘            │
     │      │                    │
     │      ▼                    │
     │ SELECT * FROM users...    │
     │ ───────────────────────► │
     │                           │
     │ ◄─────────────────────── │
     │ [정상 결과 또는 차단 알림]  │
     └───────────────────────────┘

  * Inline 모드: 방화벽이 실제 트래픽을 전달하면서検査
  * Mirror 모드: TAP/SPAN으로 트래픽 복사해서検査 (대량 트래픽)

방화벽이 탐지하는 패턴

# DB 방화벽 탐지 규칙 예시
rules:
  # 1. SQL 문법 이상 탐지
  - name: "unterminated_string"
    pattern: "SELECT.*FROM.*WHERE.*'$"
    severity: HIGH

  # 2. 주석亂用 탐지 (-- 주석으로 필터 우회)
  - name: "comment_injection"
    pattern: ".*--.*"
    severity: MEDIUM

  # 3. 시스템 테이블 접근 탐지
  - name: "system_table_access"
    pattern: ".*(mysql\.|pg_|sys\.|information_schema).*"
    severity: HIGH

  # 4. 비정상적으로 긴 SQL 탐지
  - name: " oversized_query"
    max_length: 10000
    severity: MEDIUM

  # 5. 다중 SQL 문 (세미콜론으로 분리)
  - name: "multiple_statements"
    pattern: ".*;.*(DROP|DELETE|INSERT|UPDATE).*"
    severity: CRITICAL

  # 6. 시간 지연 기반 블라인드 SQLi 탐지 (SLEEP/BENCHMARK)
  - name: "time_based_blind_injection"
    pattern: ".*(SLEEP\(|BENCHMARK\().*"
    severity: HIGH

III. SQL 인젝션 방어 전략: Defense in Depth

[SQL 인젝션 방어 5단계]

  Layer 1: 입력 검증 (Input Validation) ★가장 중요
  ┌──────────────────────────────────────────────┐
  │ - 화이트리스트 방식: 허용된 문자만 입력 가능    │
  │ - 사용자名的: "'", ";", "--", "/*" 等 차단   │
  │ - 타입 검증: username은 alphanumeric만 허용   │
  └──────────────────────────────────────────────┘
                    │
  Layer 2: Prepared Statement (파라미터화 쿼리)
  ┌──────────────────────────────────────────────┐
  │ # 취약한 코드                                  │
  │ query = f"SELECT * FROM users WHERE id={id}" │
  │                                              │
  │ # 안전한 코드 (Prepared Statement)             │
  │ cursor.execute("SELECT * FROM users WHERE id=?", (id,)) │
  │ # 파라미터가 문자열로 escaping되어 삽입       │
  └──────────────────────────────────────────────┘
                    │
  Layer 3: Stored Procedure (파라미터 자동 이스케이프)
  ┌──────────────────────────────────────────────┐
  │ - 애플리케이션에서 직접 SQL 미작성              │
  │ - DB에 사전 정의된 프로시저만 호출               │
  │ - 단, 프로시저 내부 문자열 동적 생성 시 주의     │
  └──────────────────────────────────────────────┘
                    │
  Layer 4: ORM (Object-Relational Mapping)
  ┌──────────────────────────────────────────────┐
  │ - SQL을 개발자가 직접 작성하지 않음             │
  │ - Django ORM, Hibernate 등이 파라미터 처리     │
  │ - But: 복잡한 쿼리에서는 Native SQL 불가피     │
  └──────────────────────────────────────────────┘
                    │
  Layer 5: DB 방화벽 +最小 권한 원칙
  ┌──────────────────────────────────────────────┐
  │ - DB 방화벽으로 알려진 공격 패턴 실시간 차단     │
  │ - 애플리케이션 계정은 DDL 권한 없음            │
  │ - 읽기 전용 계정과 쓰기 계정 분리               │
  └──────────────────────────────────────────────┘

Ⅳ. Prepared Statement의重要性

# 취약한 코드 vs 안전한 코드 비교

# ❌ 취약한 코드 (Python)
def get_user(username):
    query = f"SELECT * FROM users WHERE username = '{username}'"
    # username에 "admin' --" 입력 시 → 전체 사용자 노출

# ✅ 안전한 코드 (Prepared Statement)
def get_user(username):
    query = "SELECT * FROM users WHERE username = ?"
    cursor.execute(query, (username,))
    # 파라미터가 자동으로 이스케이프 처리됨

# ❌ 취약한 코드 (PHP)
$query = "SELECT * FROM users WHERE id = " . $_GET['id'];
// http://site.com/?id=1 OR 1=1 → 전체 데이터 노출

# ✅ 안전한 코드 (PHP PDO)
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $_GET['id']]);

Ⅴ. 실제 공격 시나리오と 📢 비유

실제 SQL 인젝션으로 인한 피해 사례:

[대규모 데이터 유출 사례]

  2017년 Equifax 데이터 유출:
  - Apache Struts 취약점 (SQL 인젝션과 유사한Injection 계열)
  - 1억 4,700만 명 정보 유출

  2022년 Log4j (Log4Shell):
  - 로그 메시지 내Injection → 시스템 명령 실행
  - SQL 인젝션과 같은 "입력값이 실행 코드로 변하는" 원리

 SQL 인젝션 피해:
  1. 데이터 베이스 전체 데이터 유출
  2. 관리자 계정 탈취 (認証 bypass)
  3. 테이블 삭제/변조 (DROP, UPDATE)
  4. 백도어 설치 ( INTO OUTFILE)
  5. 대상 서버 제어권 취득 ( xp_cmdshell)

📢 섹션 요약 비유: SQL 인젝션은 **"은행 창구의 작은 틈새"**와 같습니다. 은행원이 "이름을 말해주세요"라고 하면 정직한 사람은 "김철수"라고 답합니다. 그런데 악의적인 사람이 "김철수라고 말하고, 그리고 오늘 편한 금액으로 다 찾아가겠습니다"라고 이어서 말하면, 은행원이 "네?" 하고全部 그대로 처리해버리는 것이죠. DB 방화벽은 이 **"창구 직원이 받는 모든 말에서 부적절한 지시를 솎아내는 교육과 자동 시스템"**이고, Prepared Statement는 **"은행원이 고객의 말과 지시를 분리해서 받아들이는 창구 규칙"**입니다. "사용자 입력을 절대로 SQL 명령어와混淆하지 않는" 것이 핵심입니다.