본문으로 건너뛰기
중급22

SQL Injection 직접 확인하기: 신호를 읽고 심각도를 판단하는 법

레슨 5에서 배운 인젝션 개념을 실제로 손으로 시도해본다. 대표적인 테스트 입력값과 에러 메시지에서 취약점 신호를 읽는 법, 그리고 발견했을 때 어떻게 리포트할지 익힌다.

  • #SQLInjection
  • #보안테스트
  • #취약점리포트

개념

시작하기 전에 — 반드시 허가된 환경에서만

이 레슨에서 다루는 입력값은 반드시 자신이 소유했거나 명시적으로 테스트 허가를 받은 환경(로컬 개발 환경, 사내 테스트 서버 등)에서만 시도해야 한다. 허가 없이 다른 사람의 서비스에 시도하는 것은 실습이 아니라 불법적인 공격 행위다. 모듈 7(레슨 3)에서 배운 환경 격리 원칙이 이 레슨에서는 안전장치이자 법적 경계선이기도 하다.

레슨 5의 개념을 손으로 확인하기

레슨 5에서 인젝션이 "사용자 입력이 명령어의 일부로 실행되는 취약점"이라고 배웠다. 이 레슨은 그걸 실제로 어떻게 확인하는지 다룬다.

검색창이 내부적으로 이런 SQL을 만든다고 가정하면:
SELECT * FROM products WHERE name = '[사용자 입력]'
 
정상 입력 "노트북"을 넣으면:
SELECT * FROM products WHERE name = '노트북'  → 정상 동작
 
공격 입력 "' OR '1'='1"을 넣으면:
SELECT * FROM products WHERE name = '' OR '1'='1'  → 조건이 항상
참이 되어, 검색어와 무관하게 전체 상품이 노출될 수 있다

대표적인 테스트 입력값

QA가 취약점 여부를 1차로 확인할 때 흔히 써보는 입력들이다.

입력값무엇을 확인하려는가
' OR '1'='1조건을 항상 참으로 만들어 인증·필터를 우회시킬 수 있는가
' (작은따옴표 하나만)입력을 제대로 이스케이프하지 않아 에러가 나는가
'; DROP TABLE users; --여러 명령어를 이어 붙여 실행시킬 수 있는가(운영 환경에서는 절대 실행하지 말 것 — 데이터가 정말 삭제된다)
' UNION SELECT username, password FROM users --다른 테이블의 데이터를 결과에 끼워 넣을 수 있는가

에러 메시지가 주는 신호

작은따옴표 하나만 넣었는데 아래와 같은 반응이 나온다면, 그 자체가 위험 신호다.

안전한 반응: "검색 결과가 없습니다" (입력이 안전하게 처리됨)
 
위험한 반응: "SQL syntax error near ''' at line 1" 같은
            데이터베이스 에러 메시지가 그대로 화면에 노출됨

레슨 5에서 배운 "보안 설정 오류"(에러 메시지에 시스템 정보 노출)와 "인젝션"이 여기서 함께 나타나는 경우가 많다 — 에러 메시지 자체가 "이 입력이 SQL 구문으로 해석되고 있다"는 증거이기 때문이다. 이걸 에러 기반 탐지라고 부른다. 화면에 에러가 안 보여도 응답 시간이 비정상적으로 길어지는 경우(예: ' OR SLEEP(5)=' 같은 입력)도 있는데, 이건 화면에 아무 힌트도 안 주면서 취약점을 감춘 경우라 더 찾기 어렵다 — 이런 고급 탐지 기법은 전문 보안 도구(레슨 6의 DAST)의 영역이다.

발견했다면 — 왜 이건 항상 심각도가 높은가

모듈 6(레슨 1)에서 배운 심각도 판단 기준을 떠올려보자. SQL Injection이 확인되면 거의 항상 **최고 심각도(Critical/Blocker)**로 분류된다 — 왜냐하면 이 결함 하나로 전체 데이터베이스의 정보가 유출되거나 삭제될 수 있어, 파급 범위가 "이 화면 하나"가 아니라 "서비스 전체"이기 때문이다. 모듈 6(레슨 2)에서 배운 좋은 결함 리포트 원칙이 여기서 특히 중요하다 — 재현 절차를 정확히 남기되, 실제 파괴적인 명령(DROP TABLE 등)은 절대 실행하지 않고 "이런 게 될 것으로 보인다"는 수준까지만 확인하고 멈춰야 한다.

실무에서 왜 필요한가

전담 보안팀이 없는 조직에서, 기능 테스트를 하던 QA가 우연히 입력창에 특수문자를 넣었다가 이상한 에러를 발견하는 경우가 실제로 드물지 않다. 이때 "어, 이상하네" 하고 넘기지 않고 이 레슨에서 배운 신호(SQL 에러 메시지, 비정상적인 결과)를 알아보는 QA는, 전문 보안 감사 전에 심각한 취약점을 먼저 잡아낼 수 있다. 다만 이 레슨의 목적은 QA를 침투 테스터로 만드는 것이 아니라, "이건 정상이 아니다"를 알아채고 적절한 사람에게 안전하게 에스컬레이션하는 것이다.

실습 과제

과제 1 — 입력값과 목적 짝짓기 (10분)

이 레슨에서 다룬 4가지 테스트 입력값을 각각 "무엇을 확인하려는 것인지" 자신의 말로 다시 설명해본다.

과제 2 — 발견 시나리오 리포트 작성하기 (15분)

"회원 검색창에 작은따옴표 하나만 입력했더니 SQL syntax error near ''' 라는 에러 메시지가 화면에 그대로 노출됐다"는 발견을, 모듈 6(레슨 2)에서 배운 형식(재현 절차·실제 결과·기대 결과·심각도)으로 리포트를 작성한다. 왜 이 심각도를 선택했는지도 한 문장으로 근거를 남긴다.

해설 보기

핵심은 심각도를 Critical로 판단한 근거를 구체적으로 쓰는 것이다. "보안 취약점이라 위험하다"처럼 뭉뚱그리지 말고, "이 결함이 확인되면 공격자가 UNION SELECT 등으로 다른 사용자의 개인정보나 인증 정보에 접근할 수 있어, 단일 화면의 문제가 아니라 전체 데이터베이스 노출로 이어질 수 있다"처럼 왜 파급 범위가 넓은지를 리포트에 남겨야 개발팀과 관리자가 우선순위를 즉시 이해할 수 있다.

자가 체크리스트

  • 이 레슨의 실습은 허가된 환경에서만 시도해야 한다는 것을 이해하고 그 이유를 설명할 수 있다
  • 대표적인 SQL Injection 테스트 입력값 4가지와 각각의 목적을 설명할 수 있다
  • 에러 메시지가 왜 취약점의 신호가 되는지 설명할 수 있다
  • SQL Injection이 왜 거의 항상 최고 심각도로 분류되는지 설명할 수 있다
  • 발견한 취약점을 파괴적인 명령 없이 안전하게 확인하고 리포트하는 절차를 설명할 수 있다

흔한 실수

  • 허가받지 않은 환경(실제 운영 서비스 등)에서 시도한다. 이는 실습이 아니라 불법 행위이며, 심각한 법적 책임으로 이어질 수 있다.
  • 취약점을 확인한다며 실제로 DROP TABLE 같은 파괴적인 명령을 실행한다. 취약점 존재는 훨씬 안전한 방법(작은따옴표 하나, 에러 메시지 관찰)으로도 충분히 확인할 수 있다.
  • 에러 메시지가 안 보인다고 안전하다고 단정한다. 화면에 신호가 없는 블라인드 SQL Injection도 존재한다 — 확신이 안 서면 전문 보안 도구나 담당자에게 넘기는 것이 맞다.
  • 발견한 취약점의 심각도를 낮게 잡는다. 파급 범위(전체 데이터베이스)를 고려하지 않고 "그냥 에러 메시지 하나"로 과소평가하면 안 된다.

참고 자료