14강 / 20강

SQL 인젝션 — 검색창으로 DB를 통째로

따옴표 하나가 여는 문, 그리고 준비된 질의

SQL 인젝션 — 검색창으로 DB를 통째로
가장 오래됐지만 여전히 가장 많이 터지는 웹 취약점입니다.

13강의 원칙 — "입력을 문장으로 해석하지 마라" — 를 가장 유명하게 어긴 사례가 SQL 인젝션입니다. 검색창이나 로그인창에 넣은 값이 DB 질의(SQL)의 일부로 해석되면서, 공격자가 DB에게 직접 명령을 내리게 됩니다.

이번 강의는 실제로 우리 쇼핑몰 검색창을 뚫어 회원 정보를 빼내 본 뒤, 막습니다.

따옴표 하나로 문장을 깬다

검색창에 '(따옴표) 하나만 넣어 봅시다. 앱이 이걸 문장에 그대로 이어 붙이면 SQL 문법이 깨져 오류가 나요. 공격자에게 이 오류는 "여기 인젝션 된다"는 신호입니다.

SQL 인젝션 실습실 — 검색창에 공격 문자열을 넣어 보고 준비된 질의로 막는다
불러오는 중…

실습실에서 준비된 질의를 끈 상태로 아래 순서를 시도해 보세요.

  • ' — 문장이 깨져 오류 (탐색)
  • ' OR '1'='1 — 조건이 항상 참 → 전체 상품이 다 나옴
  • ' UNION SELECT email, password FROM users -- — 회원 표가 상품 자리에 나옴 😱

마지막 것이 실제 유출 사고의 모습입니다. 상품을 검색했는데 회원 이메일과 비밀번호 해시가 쏟아져 나오는 거죠.

공격 문자열이 만들어 내는 SQL 을 직접 봅니다.
Python 브라우저 안에서 실행 (계산용)
준비된 질의를 켰는지에 따라 결과가 갈립니다.
🥷 공격자 브라우저 안에서 실행 (계산용)

근본 해결 — 준비된 질의(placeholder)

필터링으로 위험한 글자를 막으려는 시도는 늘 뚫립니다(우회가 무한해요). 정답은 구조적으로 데이터와 명령을 분리하는 것 — 준비된 질의입니다.

위험 — 이어 붙이기
"...name = '" + 입력 + "'"
입력이 문장이 됨
안전 — placeholder
"...name = ?", (입력,)
입력은 값으로만 들어감

준비된 질의에서는 DB가 문장 구조를 먼저 정하고, 입력은 나중에 값 자리에만 채웁니다. 따옴표를 아무리 넣어도 '그런 이름의 상품 없음'이 될 뿐, 문장이 안 바뀌어요.

🤔 확인 문제
SQL 인젝션의 근본 해결책은?
🤔 확인 문제
웹 앱 DB 계정에서 DROP·GRANT 권한을 뺐습니다(9강). SQL 인젝션이 성공하면?