로그인 회원가입
SQL INJECTION 이란?
normaltic 짝사랑남 2025-11-17 17:01:39

SQL 인젝션(SQL Injection)의 구조와 왜 발생하는지 자세한 설명

SQL 인젝션은 웹 애플리케이션에서 사용자 입력이 SQL 쿼리의 일부로 해석되면서 공격자가 의도하지 않은 SQL 명령을 실행시키는 취약점입니다.

아래 내용을 단계별로 이해하시면 전체 구조가 명확하게 보입니다.


1️⃣ 웹 애플리케이션에서 SQL이 동작하는 기본 구조

일반적인 웹 서비스는 다음과 같은 흐름으로 작동합니다.

  1. 사용자가 로그인 ID, 검색어 등을 입력함

  2. 서버(PHP, Python, Node.js 등)가 입력값을 받아 SQL 쿼리를 생성함

  3. 생성된 SQL 문을 DB 서버(MySQL 등)에 전송

  4. DB 서버가 결과를 서버에게 되돌려줌

  5. 서버는 그 결과를 HTML로 만들어 사용자에게 보여줌

예를 들어 로그인을 한다면 서버는 대략 이런 쿼리를 만들게 됩니다.

SELECT * FROM users WHERE username = '입력 아이디' AND password = '입력 비밀번호';

여기까지는 정상적인 흐름입니다.


2️⃣ SQL 인젝션이 어디서 끼어드는가? (취약점의 구조)

문제는 서버가 SQL 쿼리를 만들 때 문자열을 이어 붙이는 방식을 사용하면 발생합니다.

예시(취약한 코드):

$query = "SELECT * FROM users WHERE username = '" . $id . "' AND password = '" . $pw . "'";

위처럼 문자열로 직접 이어 붙이면, 사용자의 입력이 “코드”처럼 동작할 수 있습니다.


✔ 예시 — 공격자가 입력한 값

  • username: admin

  • password: ' OR '1'='1

그러면 최종적으로 DB에 전달되는 SQL은 이렇게 됩니다:

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

여기서 '1'='1' 은 항상 참(True)이므로
비밀번호 검증이 완전히 무너져 버립니다.

즉,

사용자가 입력한 값이 SQL 문법으로 해석되면서 원래 의도를 벗어난 SQL이 실행됨

이 구조가 SQL 인젝션입니다.


3️⃣ 왜 이런 공격이 발생하는가? (근본 원인)

SQL 인젝션의 근본 원인은 다음과 같습니다.


✔ (1) 입력값과 SQL 코드가 구분되어 있지 않기 때문

서버가 입력값을 별도의 데이터로 처리하지 않고
그냥 쿼리 문자열에 직접 끼워 넣어버리기 때문입니다.

DB 입장에서는 이것이 데이터인지, 공격용 SQL인지 구분할 수 없습니다.


✔ (2) 입력값 검증 부족

  • 특수문자( ', " , -- , # 등 ) 필터링 실패

  • 타입 체크 부족

  • 잘못된 escape 처리

이러한 문제들이 쿼리를 무방비하게 만듭니다.


✔ (3) Prepared Statement(준비된 문) 사용 안 함

SQL 인젝션이 없는 안전한 방식은 바로 **Prepared Statement(프리페어드 스테이트먼트)**입니다.

예시:

$stmt = $db->prepare("SELECT * FROM users WHERE username = ? AND password = ?"); $stmt->bind_param("ss", $id, $pw);

이 방식은 DB가
“? 부분은 무조건 데이터로만 처리하고, 절대 SQL 코드로 해석하지 않는다”
고 약속하는 방식이기 때문에 SQL 인젝션이 원천적으로 차단됩니다.


4️⃣ SQL 인젝션으로 어떤 일이 벌어질 수 있는가?

SQL 인젝션은 웹 해킹에서 가장 위험한 취약점 중 하나이며, 다음과 같은 공격이 가능합니다.

✔ 로그인 우회

비밀번호 없이 admin으로 로그인

✔ DB 내용 탈취

회원 정보, 비밀번호 해시, 이메일 등 전체 조회 가능

✔ 테이블 삭제

DROP TABLE users;

✔ 시스템 명령 실행 (DB의 기능에 따라)

MySQL의 LOAD_FILE, INTO OUTFILE 등 악용 가능

✔ 서버 권한 상승 공격으로 이어질 수도 있음

즉, SQL 인젝션은 단순한 로그인 우회 공격을 넘어서
전체 시스템을 무너뜨릴 수 있는 취약점입니다.


5️⃣ SQL 인젝션을 방어하는 기본 원칙

방어는 크게 3가지입니다.


✔ (1) Prepared Statement 사용 (가장 중요)

? 또는 :value 같은 placeholder 사용
➡️ 입력값을 절대 SQL 코드로 해석하지 않음
➡️ 99% 해결됨


✔ (2) 입력값 validation + escaping

  • ', ", ;, --, # 등을 의미 없는 문자로 처리

  • 숫자는 숫자인지 체크

  • 길이 제한

  • 화이트리스트 방식 필터링


✔ (3) 최소 권한 원칙 적용

웹 서비스에서 사용하는 DB 계정은 권한을 최소한만 부여해야 합니다.

예:

  • DROP TABLE 금지

  • UPDATE 제한

  • 특정 테이블만 SELECT 가능하도록 제한


🔚 정리

SQL 인젝션은 다음과 같은 이유로 발생합니다:

사용자 입력을 SQL 쿼리에 직접 포함시키기 때문이며,
데이터와 코드가 구분되지 않아 입력값이 SQL 명령처럼 동작하기 때문이다.

그리고 제대로 된 방어는:

Prepared Statement 사용 + 입력값 검증 + 최소 권한 설정

이 세 가지로 요약됩니다.

리스트 글삭제 글수정

댓글 0
등록하기