본 블로그는 학습용입니다. 명시적 동의 없는 시스템 접근·정보수집은 불법이며 형사·민사 책임이 따릅니다.
실습은 격리된 테스트 환경에서만 허용됩니다. (형법·정보통신망법·정보통신기반보호법 등)
1. 주제
주제: SQL 인젝션(SQL Injection) 취약점 분석
핵심 요약: SQL 인젝션은 공격자가 웹 애플리케이션의 취약점을 이용해 데이터베이스에 악의적인 SQL 코드를 주입, 실행하여 정보를 탈취하거나 시스템을 조작하는 가장 치명적인 공격 기법 중 하나입니다.
가장 빈번하게 언급되고, 또 가장 파괴적인 공격 중 하나가 바로 SQL 인젝션이며 해커가 웹사이트의 데이터베이스에 저장된 정보를 무단으로 열람, 수정, 삭제할 수 있게 만드는 강력한 해킹 기법입니다.
2. 정의 및 핵심 원리
2.1. 상세 정의
SQL 인젝션(SQLi)은 애플리케이션의 보안 취약점을 이용해 공격자가 데이터베이스에 임의의 SQL 구문을 주입하고 실행되게 하는 공격입니다. 일반적으로 웹 애플리케이션은 아이디나 비밀번호 같이 사용자가 입력한 값을 기반으로 SQL 쿼리를 동적으로 생성하여 데이터베이스와 통신합니다. 이때 개발자가 사용자의 입력 값을 제대로 검증하거나 처리하지 않으면, 공격자는 입력 값에 악의적인 SQL 코드를 포함시켜 개발자가 의도하지 않은 쿼리를 실행시킬 수 있습니다.
2.2. 핵심 원리

SQL 인젝션의 가장 근본적인 원인은 사용자로부터 입력받은 순수한 데이터가 서버에서 처리되지 않고 데이터베이스에서 실행 가능한 코드로 해석되는 것에 있습니다.
예를 들어, 로그인 폼을 생각해 봅시다
사용자가 아이디와 비밀번호를 입력하면, 서버는 다음과 같은 SQL 쿼리를 생성할 것입니다.
SELECT * FROM users WHERE userID = '입력_아이디' AND userPassword = '입력_비밀번호';
여기서 '입력_아이디'와 '입력_비밀번호'는 순수한 데이터로 취급되어야 합니다. 하지만 공격자는 이 데이터 입력 필드에 SQL 구문의 일부를 교묘하게 삽입하여 쿼리의 구조 자체를 바꿔버립니다.
3. 주요 공격 원리
정상적인 상황

- 사용자가 아이디로 myuser, 비밀번호로 mypass123을 입력합니다.
- 서버는 아래와 같은 정상적인 쿼리를 생성하여 실행합니다.
- SELECT * FROM users WHERE userID = 'myuser' AND userPassword = 'mypass123';
- 데이터베이스는 해당 아이디와 비밀번호가 일치하는 사용자를 찾아 결과를 반환합니다. (로그인 성공 또는 실패)
공격 상황

- 공격자가 아이디 입력창에 ' OR '1'='1 을, 비밀번호 입력창에는 아무 값이나 입력합니다.
- 서버는 이 입력 값을 그대로 받아 아래와 같이 비정상적인 쿼리를 생성합니다.
- SELECT * FROM users WHERE userID = '' OR '1'='1' AND userPassword = '아무값';
이 쿼리를 데이터베이스가 해석하는 방식을 봅시다
WHERE userID = '' : 이 부분은 거짓(false)이 될 수 있습니다.
OR '1'='1' : 하지만 OR 연산자 뒤에 '1'='1' 이라는 항상 참인 조건이 붙었습니다.
전체 WHERE 절이 참이 되어 users 테이블의 모든 데이터가 조회됩니다. 보통 이런 경우 첫 번째 사용자의 정보로 로그인이 성공하게 되며, 이를 통해 인증을 우회할 수 있습니다.
4. 유형 및 비교
4.1. 주요 유형
In-band SQLi (에러 / UNION 기반)
가장 일반적인 유형으로, 공격과 결과 확인이 동일한 채널(HTTP 응답)을 통해 이루어집니다.
- 에러 기반
고의로 잘못된 SQL 구문을 주입하여 데이터베이스가 반환하는 오류 메시지를 통해 데이터베이스의 구조를 파악하는 기법입니다. - UNION 기반
UNION SQL 연산자를 사용하여 원래의 쿼리 결과에 공격자가 원하는 쿼리 결과를 덧붙여 한 번에 탈취하는 기법입니다
Inferential SQLi
데이터베이스의 직접적인 응답 없이, 참/거짓 형태의 응답 차이를 통해 정보를 조금씩 유추해내는 Blind 공격입니다.
- Boolean 기반
SQL 쿼리 주입 결과 페이지의 응답이 '참'일 때와 '거짓'일 때 다른 점을 이용하여 한 글자씩 데이터를 추측합니다 - 시간 기반
SLEEP() 같은 지연 함수를 포함시켜, 조건이 참일 때 서버 응답이 지연되는 현상을 통해 정보를 파악하는 기법입니다
4.2. 유형별 비교
| 구분 | In-band SQLi | Inferential SQLi (Blind) |
| 결과 확인 | 직접적인 HTTP 응답 (에러 메시지, 데이터) | 간접적인 응답 변화 (페이지 내용, 응답 시간) |
| 공격 속도 | 빠름 | 매우 느림 |
| 공격 난이도 | 상대적으로 낮음 | 높음 (자동화 도구 주로 사용) |
| 주요 목적 | 데이터베이스 구조 파악, 대량 데이터 탈취 | 제한된 환경에서의 데이터 유추 및 탈취 |
5. 파급 효과 및 방어 전략
5.1. 주요 파급 효과
SQL 인젝션 공격이 성공하면 심각한 피해가 발생할 수 있습니다.
- 데이터 유출: 개인정보, 금융정보, 기업 비밀 등 민감한 데이터를 탈취합니다.
- 데이터 변조/삭제: 데이터베이스의 내용을 무단으로 수정하거나 삭제하여 서비스 장애를 유발합니다.
- 인증 우회: 관리자 계정을 탈취하여 시스템 전체를 장악합니다.
- 서버 장악: 데이터베이스의 특정 기능을 통해 서버의 파일을 읽거나 악성코드를 실행시켜 시스템 전체의 제어권을 탈취할 수도 있습니다.
5.2. 핵심 방어 전략
다행히도 SQL 인젝션은 올바른 개발 관행을 통해 충분히 막을 수 있습니다.
- Prepared Statements 사용: 사용자의 입력 값이 SQL 쿼리에 직접 합쳐지지 않고, 분리된 파라미터로 전달되게 하는 가장 효과적인 방법입니다. 데이터베이스는 쿼리의 '틀'을 먼저 컴파일하고 입력 값은 '데이터'로만 취급하여, 악의적인 코드가 실행되는 것을 원천적으로 차단합니다.
- 입력 값 검증: 허용할 값의 유형, 길이, 형식만 허용하는 화이트리스트(Whitelist) 방식을 적용하여 비정상적인 입력 값을 차단합니다.
- 최소 권한의 원칙: 웹 애플리케이션이 데이터베이스에 연결할 때 사용하는 계정의 권한을 SELECT 등 꼭 필요한 권한으로만 최소화합니다.
취약한 코드: query = "SELECT * FROM users WHERE userID = '" + user_input_id + "'"
안전한 코드: query = "SELECT * FROM users WHERE userID = %s"; cursor.execute(query, (user_input_id,))
6. 결론
SQL 인젝션은 조금만 주의를 기울이지 않으면 쉽게 발생할 수 있는 치명적인 취약점입니다. 개발 초기 단계부터 Prepared Statements 사용을 습관화하고, 모든 사용자 입력을 철저히 검증하는 시큐어코딩 문화를 정착시키는 것이 중요합니다. 작은 실수가 큰 데이터 유출 사고로 이어질 수 있다는 사실을 항상 기억해야 합니다.
참고 자료
'해킹&보안 > 웹' 카테고리의 다른 글
| [Writeup] 요청 조작을 통한 OTP 인증 우회 (0) | 2025.09.18 |
|---|---|
| Stored XSS란? (0) | 2025.08.27 |
| [Writeup] Local Authority (1) | 2025.04.29 |
| [Writeup] WebDecode (1) | 2025.04.29 |
| [Writeup] 웹 쿠키 조작을 활용한 플래그 추출 (0) | 2025.04.29 |