SQL Injection: 두 판 사이의 차이
기술노트
(CS 용어 정리 - SQL Injection 추가) |
(컴퓨터 과학 용어 정리 - SQL Injection 추가) |
||
1번째 줄: | 1번째 줄: | ||
= SQL Injection = | |||
== 개념 == | |||
SQL Injection은 웹 애플리케이션의 주요 보안 취약점으로, 공격자가 악의적인 SQL 코드를 삽입하여 데이터베이스를 비정상적으로 조작하는 공격 기법입니다. 이 공격은 애플리케이션이 사용자 입력을 적절히 검증하지 않고 SQL 쿼리에 직접 포함시킬 때 발생합니다. | |||
< | == 유형 == | ||
=== 기본적인 SQL Injection === | |||
* 사용자 입력이 SQL 쿼리의 구조를 변경하는 경우 | |||
* 예: <code>SELECT * FROM users WHERE username='admin' AND password='' OR '1'='1'</code> | |||
* <code>'1'='1'</code>은 항상 참이므로 인증 우회 가능 | |||
==== | === Blind SQL Injection === | ||
* 직접적인 결과를 볼 수 없지만 참/거짓 응답으로 정보를 유추 | |||
* 예: <code>SELECT * FROM users WHERE username='admin' AND (SELECT 1 FROM information_schema.tables WHERE table_name='users' LIMIT 1)=1</code> | |||
* 시스템 반응을 통해 특정 테이블 존재 여부 확인 | |||
=== Error-based SQL Injection === | |||
* 데이터베이스 오류 메시지를 통해 정보 획득 | |||
* 예: <code>SELECT * FROM users WHERE id=1 AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))</code> | |||
* 오류 메시지에 데이터베이스 버전 정보가 포함됨 | |||
=== Time-based SQL Injection === | |||
* 시간 지연을 통해 정보 유추 | |||
* 예: <code>SELECT * FROM users WHERE id=1 AND IF(1=1, SLEEP(5), 0)</code> | |||
* 조건이 참이면 5초간 지연됨 | |||
< | === Union-based SQL Injection === | ||
SELECT | * UNION 구문을 이용해 추가 쿼리 실행 | ||
</ | * 예: <code>SELECT name, email FROM users WHERE id=1 UNION SELECT username, password FROM admin</code> | ||
* 관리자 테이블의 정보 획득 가능 | |||
SQL | == 방어 방법 == | ||
=== 매개변수화된 쿼리(Prepared Statements) 사용 === | |||
<syntaxhighlight> | * SQL 쿼리와 데이터를 분리하여 처리 | ||
* 예: | |||
<syntaxhighlight lang="java"> | |||
String query = "SELECT * FROM users WHERE username = ? AND password = ?"; | |||
PreparedStatement stmt = connection.prepareStatement(query); | |||
stmt.setString(1, username); | |||
stmt.setString(2, password); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
=== 입력 값 검증 === | |||
* 사용자 입력에 SQL 명령어나 특수문자가 포함되었는지 확인 | |||
* 화이트리스트 방식으로 유효한 입력만 허용 | |||
=== ORM(Object-Relational Mapping) 사용 === | |||
* SQL 쿼리를 직접 작성하지 않고 객체 모델을 통해 데이터베이스에 접근 | |||
* 예: Hibernate, Entity Framework, Django ORM 등 | |||
=== 최소 권한 원칙 === | |||
* 데이터베이스 계정에 필요한 최소한의 권한만 부여 | |||
* 읽기 전용 작업에는 SELECT 권한만 부여된 계정 사용 | |||
=== 오류 메시지 숨기기 === | |||
* 상세한 데이터베이스 오류 메시지를 사용자에게 노출하지 않음 | |||
* 일반적인 오류 메시지로 대체 | |||
=== | === WAF(Web Application Firewall) 사용 === | ||
* 웹 애플리케이션 방화벽을 통해 SQL Injection 패턴 차단 | |||
== 실제 사례 == | |||
=== Sony Pictures (2011) === | |||
* LulzSec 해커 그룹이 SQL Injection 취약점을 이용해 100만 명 이상의 사용자 정보 유출 | |||
=== Yahoo (2012) === | |||
* 약 45만 명의 계정 정보가 SQL Injection을 통해 유출됨 | |||
=== LinkedIn (2012) === | |||
* 약 650만 명의 사용자 비밀번호 해시가 유출 | |||
=== TalkTalk (2015) === | |||
* 영국 통신회사 TalkTalk의 고객 정보 15만 건이 SQL Injection 공격으로 유출 | |||
== 보안 인식의 중요성 == | |||
* SQL Injection은 OWASP Top 10에서 지속적으로 상위권에 포함되는 심각한 보안 위협 | |||
* 개발자 교육과 코드 리뷰를 통해 SQL Injection 취약점 예방 가능 | |||
* 정기적인 보안 테스트와 코드 스캐닝으로 취약점 조기 발견 | |||
== 관련 주제 == | |||
* 웹 보안 | |||
* OWASP | |||
* 데이터베이스 보안 | |||
* 입력 검증 | |||
* 보안 코딩 가이드라인 |
2025년 4월 17일 (목) 15:33 기준 최신판
SQL Injection
개념
SQL Injection은 웹 애플리케이션의 주요 보안 취약점으로, 공격자가 악의적인 SQL 코드를 삽입하여 데이터베이스를 비정상적으로 조작하는 공격 기법입니다. 이 공격은 애플리케이션이 사용자 입력을 적절히 검증하지 않고 SQL 쿼리에 직접 포함시킬 때 발생합니다.
유형
기본적인 SQL Injection
- 사용자 입력이 SQL 쿼리의 구조를 변경하는 경우
- 예:
SELECT * FROM users WHERE username='admin' AND password= OR '1'='1'
'1'='1'
은 항상 참이므로 인증 우회 가능
Blind SQL Injection
- 직접적인 결과를 볼 수 없지만 참/거짓 응답으로 정보를 유추
- 예:
SELECT * FROM users WHERE username='admin' AND (SELECT 1 FROM information_schema.tables WHERE table_name='users' LIMIT 1)=1
- 시스템 반응을 통해 특정 테이블 존재 여부 확인
Error-based SQL Injection
- 데이터베이스 오류 메시지를 통해 정보 획득
- 예:
SELECT * FROM users WHERE id=1 AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))
- 오류 메시지에 데이터베이스 버전 정보가 포함됨
Time-based SQL Injection
- 시간 지연을 통해 정보 유추
- 예:
SELECT * FROM users WHERE id=1 AND IF(1=1, SLEEP(5), 0)
- 조건이 참이면 5초간 지연됨
Union-based SQL Injection
- UNION 구문을 이용해 추가 쿼리 실행
- 예:
SELECT name, email FROM users WHERE id=1 UNION SELECT username, password FROM admin
- 관리자 테이블의 정보 획득 가능
방어 방법
매개변수화된 쿼리(Prepared Statements) 사용
- SQL 쿼리와 데이터를 분리하여 처리
- 예:
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement stmt = connection.prepareStatement(query);
stmt.setString(1, username);
stmt.setString(2, password);
입력 값 검증
- 사용자 입력에 SQL 명령어나 특수문자가 포함되었는지 확인
- 화이트리스트 방식으로 유효한 입력만 허용
ORM(Object-Relational Mapping) 사용
- SQL 쿼리를 직접 작성하지 않고 객체 모델을 통해 데이터베이스에 접근
- 예: Hibernate, Entity Framework, Django ORM 등
최소 권한 원칙
- 데이터베이스 계정에 필요한 최소한의 권한만 부여
- 읽기 전용 작업에는 SELECT 권한만 부여된 계정 사용
오류 메시지 숨기기
- 상세한 데이터베이스 오류 메시지를 사용자에게 노출하지 않음
- 일반적인 오류 메시지로 대체
WAF(Web Application Firewall) 사용
- 웹 애플리케이션 방화벽을 통해 SQL Injection 패턴 차단
실제 사례
Sony Pictures (2011)
- LulzSec 해커 그룹이 SQL Injection 취약점을 이용해 100만 명 이상의 사용자 정보 유출
Yahoo (2012)
- 약 45만 명의 계정 정보가 SQL Injection을 통해 유출됨
LinkedIn (2012)
- 약 650만 명의 사용자 비밀번호 해시가 유출
TalkTalk (2015)
- 영국 통신회사 TalkTalk의 고객 정보 15만 건이 SQL Injection 공격으로 유출
보안 인식의 중요성
- SQL Injection은 OWASP Top 10에서 지속적으로 상위권에 포함되는 심각한 보안 위협
- 개발자 교육과 코드 리뷰를 통해 SQL Injection 취약점 예방 가능
- 정기적인 보안 테스트와 코드 스캐닝으로 취약점 조기 발견
관련 주제
- 웹 보안
- OWASP
- 데이터베이스 보안
- 입력 검증
- 보안 코딩 가이드라인