730. SQL 인젝션 (Injection) - Error, Blind, UNION 연산 유출 기법

핵심 인사이트: "로그인 아이디에 '홍길동'을 치세요"라고 했더니, 해커가 아이디 창에 홍길동' OR '1'='1 이라는 이상한 외계어(프로그래밍 코드)를 쳤다. 그러자 은행 데이터베이스(DB)가 이 텍스트를 평범한 글씨가 아니라 '나한테 내리는 명령 코드'로 착각하고 뇌정지를 일으켜, 전체 고객의 비밀번호와 계좌 잔액을 몽땅 화면에 토해내 버렸다. 이것이 20년 넘게 전 세계 웹 해킹 1위를 차지하고 있는 불멸의 악마, SQL 인젝션이다.

Ⅰ. SQL 인젝션 (Injection)의 개념과 발생 원인

  • 개념: 해커가 웹사이트의 검색창, 로그인 창, 주소창 등에 악의적인 **데이터베이스 쿼리문(SQL)**을 몰래 삽입(Injection)하여, 백엔드 서버의 데이터베이스(DB)를 속이고 권한을 탈취하거나 기밀 데이터를 빼내는 공격입니다.
  • 원인: 개발자가 짠 서버 코드가, 사용자가 친 글자를 무비판적으로 믿고 그대로 DB에 찔러 넣기(조립하기) 때문에 발생합니다.

Ⅱ. 해커의 마법: 만능 마스터키 (OR '1'='1)

  • 정상적인 서버 로그인 로직: SELECT * FROM members WHERE ID = '사용자입력' AND PW = '사용자입력'
  • 해커는 아이디 칸에 admin' -- (뒤를 주석 처리), 비밀번호 칸에 아무거나 적습니다.
  • 조작된 로직: SELECT * FROM members WHERE ID = 'admin' -- AND PW = '아무거나'
  • 뒤쪽 패스워드 묻는 코드가 --(주석 기호) 때문에 삭제(투명화)되어버리고, DB는 무조건 "오 관리자(admin) 맞네!" 하고 서버 문을 활짝 열어버리는 마법이 일어납니다.

Ⅲ. SQL 인젝션의 3대 공격 기법 (어떻게 털어먹는가?) 🌟

1. Error-based (에러 기반) 인젝션 - "오류 메시지에서 답 훔치기"

  • 방식: 해커가 고의로 문법이 틀린 말도 안 되는 쿼리문(작은따옴표 ' 등)을 입력창에 던집니다.
  • 결과: 서버가 바보같이 친절하게 Error: MySQL syntax error near... 테이블 이름은 user_info입니다 같은 에러 메시지를 화면에 그대로 뱉어줍니다. 해커는 이 에러 힌트를 줍고 주워 DB의 테이블 이름과 비밀번호를 퍼즐 맞추듯 캐냅니다.

2. UNION-based (유니온 기반) 인젝션 - "정상 결과에 쓰레기 섞기"

  • 방식: 두 개의 SQL 검색 결과를 위아래로 딱 이어 붙여서 보여주는 UNION 연산자를 악용합니다.
  • 결과: 해커가 게시판 검색창에 자유게시판' UNION SELECT 아이디, 비밀번호 FROM 회원DB -- 라고 던집니다. 서버는 순진하게 위에 자유게시판 글을 띄워주고, 그 밑에다가 해커가 요구한 전체 회원의 아이디와 비밀번호 목록을 합쳐서 한 화면에 다 뿌려줍니다. 가장 파괴적이고 데이터 탈취에 직빵인 공격입니다.

3. Blind (블라인드) 인젝션 - "장님 스무고개" 🌟

보안이 좀 잘 된 서버는 Error 메시지도 안 보여주고 UNION 결과도 막아버립니다. (화면에 아무 변화가 없습니다.)

  • Boolean-based (참/거짓) 스무고개: 해커가 and (select 비밀번호첫글자 from admin) = 'A'를 쳐봅니다. 화면이 정상으로 뜨면 "아 첫 글자가 A구나!", 화면이 안 뜨면 "A가 아니네, 그럼 B를 넣어볼까?" 하고 미친 듯이 수만 번 질문을 던져 장님 코끼리 만지듯 비밀번호를 한 글자씩 빼냅니다.
  • Time-based (시간 지연) 스무고개: 참/거짓으로 화면 변화조차 없을 때 씁니다. 해커가 and IF(비밀번호 첫 글자='A', SLEEP(5), 0)이라고 던집니다. 만약 웹사이트가 5초 동안 멈췄다가(지연) 뜨면? "아, 첫 글자가 A가 맞아서 컴퓨터가 5초 잤구나!"라고 서버의 응답 속도를 스톱워치로 재서 비밀번호를 알아내는 징글징글하고 악랄한 끝판왕 스무고개 기법입니다.

Ⅳ. 방어 대책 (Prepared Statement)

  • 근본 해결책: 개발자가 쿼리문을 짤 때 입력값을 절대 그냥 합치지 말고, **Prepared Statement(미리 준비된 구문, 바인딩)**라는 안전망을 써야 합니다.
  • 이렇게 하면 해커가 OR '1'='1 이라는 해킹 코드를 쳐도, 서버는 이를 "실행할 코드"로 보지 않고 **"오, 이 사람의 로그인 아이디가 OR '1'='1 이구나. 참 특이한 이름이네. 가입된 적 없으니 꺼져!"**라며 단순한 글자(String) 덩어리로 취급해버려 해킹이 100% 무력화됩니다. (추가로 방화벽 단에서 앞선 696번 WAF 장비를 써서 차단합니다.)

📢 섹션 요약 비유: SQL 인젝션은 우편번호 적는 칸에 '명령어'를 적어 우체국을 조종하는 짓입니다. 소포 봉투 수신인 칸에 '홍길동'이라고 쓰지 않고, "이 소포는 버리고 우체국 금고 비밀번호를 나한테 보내라"라고 적어서 냅니다. 바보 같은 구형 자동분류기(DB)는 겉면의 글자를 '주소'로 착각하지 않고 '우체국장님의 긴급 명령'으로 오인하여, 소포 대신 은행 금고 비밀번호를 나에게 쏴주는 대참사입니다. 이를 막으려면 우체국 분류기(Prepared Statement)가 겉면에 적힌 어떤 무시무시한 말도 무조건 '주소지 글자'로만 취급하고 절대 '명령어'로 실행하지 못하게 기계를 뜯어고쳐야 합니다.