보안

SQL Injection(SQLi)

zinoing

1. SQL Injection이란 무엇인가

 SQL Injection은 사용자 입력이 검증 없이 SQL 쿼리에 직접 결합되어, 공격자가 악의적인 SQL을 삽입·실행할 수 있게 되는 취약점이다. 결과는 인증 우회, 데이터 유출·변조, 심지어 DB 서버 권한 획득까지 이어질 수 있다.


2. 왜 위험한가?

  • 데이터베이스는 애플리케이션의 핵심 데이터(계정, 결제정보, 개인정보)를 보관한다.
  • 공격자는 SQL을 조작해 민감한 데이터를 조회하거나 삭제·변경할 수 있다.
  • 자동화 도구(sqlmap 등)를 이용하면 단시간에 치명적인 피해를 일으킬 수 있다.

3. 주요 공격 유형

  • Error-based SQLi: 에러 메시지를 통해 DB 구조나 컬럼 정보를 알아냄.
  • Union-based SQLi: UNION으로 임의의 쿼리 결과를 합쳐 민감 데이터 획득.
  • Blind SQLi
    • Boolean-based: 참/거짓 응답(페이지 내용 변화)으로 데이터 추출.
    • Time-based: 조건에 따라 DB 지연을 발생시켜 정보를 추론.
  • Stored (Persistent) SQLi: 악성 페이로드가 DB에 저장되어 여러 사용자에게 영향.

4. 단순한 예시(취약 코드 → 공격 결과)

취약한 코드 (의사 코드)

# Python sqlite 예시 (취약) 
username = request.args.get('u') 
query = "SELECT * FROM users WHERE username = '" + username + "';" 
cursor.execute(query)

만약 username에 alice' OR '1'='1 를 넣으면 쿼리는:

SELECT * FROM users WHERE username = 'alice' OR '1'='1';
 

→ 조건이 항상 참이 되어 인증 우회나 데이터 유출이 발생할 수 있습니다.


5. 실전 방어 원칙 (우선순위별)

  1. Parameterized Queries / Prepared Statements 사용
    • 쿼리와 데이터(파라미터)를 분리하여 실행. 모든 DB 드라이버가 지원.
    • Parameterized Query는 “코드는 코드, 데이터는 데이터”를 강제로 분리.
  2. ORM/쿼리 빌더 활용
    • ORM의 쿼리 빌더를 쓰면 문자열 결합 실수를 줄일 수 있으나, raw SQL 사용 시 주의 필요.
  3. 입력 검증 — 화이트리스트 원칙
    • 허용 가능한 값(숫자만, 이메일 패턴 등)만 통과. 길이 제한과 타입 검사 병행.
  4. 최소 권한 원칙(Least Privilege)
    • 애플리케이션 DB 계정에 불필요한 DDL/관리 권한 금지. 읽기 전용 계정 분리 등.
  5. 에러 메시지 및 디버그 정보 숨기기
    • DB 에러를 그대로 사용자에게 보여주지 않기. (정보 노출 위험)
  6. WAF/IDS는 보조 수단
    • 알려진 패턴 차단에 유용하지만 근본 해결책은 아님.
  7. 정기적 코드리뷰·펜테스트·CI 통합 스캐닝
    • sqlmap, Burp 등으로 승인된 환경에서 점검. SAST/DAST 도구를 CI에 포함.

'보안' 카테고리의 다른 글

XSS(Cross-Site Scripting)  (0) 2025.10.28
JWT(Json Web Token)  (0) 2025.10.28
HTTPS와 SSL인증서의 역할  (0) 2025.10.28
CSRF(Cross-Site Request Forgery)  (0) 2025.10.28
쿠키와 세션  (0) 2025.10.28