gyumin.log

SQL 인젝션 공격 방식과 사례

지난번에 SQL 인젝션과 XSS를 비교하며 표적이 다르다는 것만 잡았다. 이번엔 SQL 인젝션 하나만 깊게 판다. 어떻게 공격하고, 실제로 어떻게 털렸는지.

정의

사용자 입력값이 검증 없이 데이터베이스 질의문(SQL)에 그대로 들어가, 공격자가 질의문의 구조 자체를 바꾸는 취약점이다.

왜 생기나

입력을 문자열로 이어붙여 SQL을 만들 때 생긴다.

"SELECT * FROM users WHERE id='" + 입력 + "'"

입력에 따옴표 하나만 들어와도 질의문이 깨진다. 개발자가 의도한 문장 구조를 사용자가 바꿀 수 있게 되는 것이다.

공격 방식 세 가지

유형페이로드 예노리는 것
로그인 우회' OR '1'='1' -- 조건을 항상 참으로 만들어 인증 통과
Union 기반 추출' UNION SELECT username, password FROM users -- 다른 테이블 데이터를 결과에 붙여 화면에 노출
블라인드' AND SLEEP(5) -- 응답 차이·응답 시간으로 한 글자씩 알아냄
  • 로그인 우회: 아이디 칸에 ' OR '1'='1' -- 를 넣으면 질의가 WHERE id='' OR '1'='1'이 되어 비밀번호 검증이 무력화된다.
  • Union 기반: 원래 결과에 다른 테이블 데이터를 이어 붙여 뽑아낸다.
  • 블라인드: 결과가 화면에 안 보일 때, 참/거짓에 따른 반응이나 지연 시간으로 데이터를 추론한다.

실제 사례

  • 소니 픽처스(2011): 공격 그룹이 SQL 인젝션 하나로 백만 개 이상의 계정 정보를 빼냈다. 비밀번호를 평문으로 저장한 게 겹쳐 피해가 커졌다.
  • 톡톡(TalkTalk, 영국 통신사, 2015): URL 파라미터의 SQL 인젝션으로 고객 개인정보가 대량 유출됐고 회사는 거액의 과징금을 맞았다.

두 사고의 공통점은 취약점 자체보다 함께 겹친 실수가 피해를 키웠다는 것이다. 인젝션으로 데이터를 뽑아도 비밀번호가 제대로 암호화돼 있었다면 2차 피해는 줄었다.

막는 법

입력을 질의 문자열에 이어붙이지 않고 매개변수 바인딩(프리페어드 스테이트먼트)으로 분리한다. 입력이 아무리 이상해도 “구조”가 아니라 “값”으로만 취급된다. 이게 1차 방어이자 사실상 유일한 근본 대책이다.