SQL 인젝션은 사용자 입력값에 악의적인 SQL 구문을 끼워 넣어, 개발자가 의도하지 않은 데이터베이스 조회·수정·삭제를 실행시키는 공격이다.
웹 취약점 중 가장 오래됐지만 여전히 가장 치명적이며, OWASP Top 10에서 20년 넘게 상위권을 지키고 있다. 로그인 우회부터 회원 DB 전체 유출까지 한 줄의 입력으로 벌어진다.
SQL 인젝션은 어떻게 뚫리나
로그인 쿼리를 SELECT * FROM users WHERE id = '입력값'처럼 문자열을 이어 붙여 만들면, 공격자가 아이디 칸에 ' OR '1'='1을 넣는 순간 조건이 항상 참이 되어 인증이 통째로 뚫린다. 더 나아가 UNION SELECT로 다른 테이블을 조회하면 회원 정보·결제 내역까지 그대로 빠져나간다. 핵심 원인은 "데이터"로 받아야 할 입력을 "코드"로 실행해버리는 데 있다.
왜 AI가 짜준 코드에서 특히 자주 나올까?
AI 코딩 도구는 "동작하는" 쿼리를 빠르게 만들어주지만, 보안 맥락 없이 요청하면 입력값을 문자열로 이어 붙이는 방식을 그대로 내놓는 경우가 많다. 기능은 완성되고 화면도 잘 뜨기 때문에 취약점이 숨은 채 배포된다. 환경변수 노출과 함께 AI 코딩 서비스에서 반복적으로 발견되는 대표 패턴이다.
파라미터 바인딩만 하면 정말 막히나요?
그렇다. 근본 해법은 입력값을 쿼리 문자열에 붙이지 않고 파라미터 바인딩(prepared statement)으로 분리하는 것이다. WHERE id = ? 형태로 자리표시자를 두고 값을 따로 전달하면, DB가 그 값을 절대 코드로 해석하지 않아 인젝션이 원천 차단된다. ORM(예: Django ORM, SQLAlchemy)을 정석대로 쓰면 대부분 자동으로 바인딩되지만, raw()나 문자열 포매팅으로 직접 쿼리를 조립하는 순간 다시 위험해진다.
내 사이트는 안전한지 자가 점검 3가지
- 문자열로 쿼리를 조립하는 곳이 있나 — 코드에서
+나 f-string, 템플릿 리터럴로 SQL을 만드는 부분을 전부 파라미터 바인딩으로 바꾼다. - 입력 검증과 최소 권한 — 예상 형식(숫자·길이)을 서버에서 검증하고, DB 계정 권한을 필요 최소로 제한해 사고 시 피해 범위를 줄인다.
- 에러 메시지에 DB 정보가 새지 않나 — SQL 오류를 그대로 화면에 노출하면 공격자에게 힌트를 준다. 디버그 에러 페이지 노출도 함께 점검한다.
쿼리 조립부터 열어보세요
SQL 인젝션은 코드에서 쿼리를 어떻게 만드는지만 봐도 위험 여부가 꽤 드러납니다. 문자열을 이어 붙이는 쿼리가 남아 있다면 그것부터 파라미터 바인딩으로 바꾸세요. 밖으로 노출된 입력 지점이나 에러로 새는 DB 정보는 CodeScan 무료 진단에서 URL 하나로 확인할 수 있고, 실제로 데이터가 빠져나가는지까지 봐야 한다면 SENTRIX 모의해킹으로 넘기면 됩니다.