LLM 리뷰어가 보안 게이트가 될 수 없는 이유
요약
최첨단 LLM 모델은 코드를 생성하는 과정(Generation Mode)에서 능동적인 보안 경고를 발행하지 못하며, 이는 AI 리뷰어가 개발 프로세스의 '보안 게이트' 역할을 할 수 없다는 핵심 논거입니다. 진정한 게이트는 모든 커밋에 자동으로 실행되며 동일한 입력에 대해 일관된 결과를 반환하는 반복 가능성(repeatability)을 가져야 합니다.
핵심 포인트
- LLM 리뷰어는 호출될 때만 작동하므로, 자동화된 보안 검사 역할을 할 수 없습니다.
- 진정한 '게이트'는 모든 커밋에서 자동으로 실행되며 동일한 입력에 대해 일관된 결과를 반환해야 합니다 (반복 가능성).
- AI 모델은 코드를 생성하는 것과 명시적으로 요청받아 검토하는 것은 별개의 작업입니다.
- 보안 취약점 판결이 스캔마다 달라지면, 개발팀은 그 신뢰성을 잃고 조치를 미루게 됩니다.
BrassCoders의 벤치마크에 따르면, 최첨단 모델(frontier model)은 여섯 가지 코드 생성 모드 작업에서 능동적인 보안 경고를 전혀 발행하지 않았습니다. 하지만 이 모델은 명시적으로 검토를 요청했을 때는 나중에 12개 중 12개의 버그를 잡아냈습니다. 바로 이 격차가 AI 리뷰어를 보안 게이트로 취급하는 것에 반대하는 핵심 논거입니다.
게이트는 누군가 요청하지 않아도 모든 커밋마다 자동으로 실행되어야 합니다. LLM 리뷰어는 호출될 때만 실행됩니다.
게이트의 실제 의미
BrassCoders는 동일한 코드에 대해 동일한 스캐너를 실행하고, 매번 동일한 결과를 도출합니다. 바로 이 반복 가능성(repeatability)이 그것을 단순한 도구(tool)가 아닌 게이트로 만듭니다. CI 체크는 일관되게 통과하거나 실패하며, 팀은 이에 따라 행동하는 법을 배웁니다.
게이트가 가진 정의적인 속성은 하나 있습니다: 자동으로 실행되며 동일한 입력에 대해 동일한 판결을 반환한다는 것입니다. 녹색 커밋(green commit)에서는 통과하고 실패하는 커밋(failing one)에서는 실패하는 테스트 스위트가 게이트입니다. 매번 같은 스타일 위반 사항에 대해 경고를 발생시키는 린터(linter)도 게이트입니다. 코드 리뷰 시점에 요청하여 사용하는 AI 리뷰어는 호출할 때 실행되며, 해당 실행에서 잡아낼 수 있는 것들을 포착하고 다음 번 동일한 코드를 실행했을 때는 다른 출력을 생성합니다. 이것은 유용한 도구이지, 게이트가 아닙니다.
개발자가 기억해서만 호출하는 보안 검사는 아무도 기억하지 못한 커밋을 놓칩니다. SQL 인젝션(SQL injection) 취약점은 세 명의 리뷰어가 있었지만 아무도 AI 리뷰어를 호출하지 않은 화요일 오후 PR에 실릴 수 있습니다. BrassCoders는 CI 단계가 실행되는 모든 커밋에서 작동합니다.
생성 모드 프로브(The Generation-Mode Probe)
BrassCoders는 공개된 벤치마크와 함께 생성 모드 프로브를 실행했습니다. 이는 보안에 대한 언급이 없는 여섯 가지 중립적인 코딩 작업으로, 모델에게 각각의 코드를 처음부터 작성하도록 요청한 것입니다. 모델은 대부분의 작업에서 깨끗한 코드(clean code)를 작성했지만, 여섯 가지 모든 작업에서 능동적인 보안 경고는 전혀 발행하지 않았습니다.
게시된 벤치마크 게시물(published benchmark post)은 다음과 같은 결과를 설명합니다: “모델이 코드를 작성하는 동안 능동적인 경고를 전혀 발행하지 않았습니다. 코드를 작성하고 넘어갔을 뿐입니다. 검토하라는 요청을 받았을 때만 문제를 지적했습니다.”
명시적인 검토에서 심어진 12개의 버그를 모두 잡아낸 것과 동일한 모델이 생성 과정 중에 취약점을 도입했고 아무 말도 하지 않았습니다. 이것은 모델에 대한 비판이 아닙니다. 코드를 생성하는 것과 코드를 검토하는 것은 다른 작업입니다. 모델은 프롬프트를 완료합니다. 보안 검토는 별도로, 명시적으로 호출되는 작업입니다.
보안을 위한 결정론 문제 (The Determinism Problem for Security)
BrassCoders는 user_lookup.py에 대해 모든 스캔에서 동일한 B608 결과를 반환하는 반면, LLM 리뷰어는 모델이 해당 실행을 샘플링하는 방식에 따라 다양한 결과를 반환합니다.
이는 특히 보안 측면에서 중요합니다. 같은 커밋에 대해 다른 판결을 내리는 CI 게이트는 개발자들에게 그 결과를 무시하도록 가르칩니다. 만약 SQL 인젝션 취약점이 화요일 스캔에서는 나타나고 수요일 스캔에서는 동일한 코드임에도 사라진다면, 팀은 즉시 조치하기보다 두 번째 의견을 기다리게 됩니다. 신뢰를 위해 두 번째 의견이 필요한 보안 취약점은 이미 게이트로서의 가치를 잃었습니다.
2025년 벤치마크(Gnieciak and Szandala, arXiv 2508.04448)에 따르면 LLM은 정적 분석기보다 높은 재현율(recall)을 보였지만, 라인-컬럼 수준에서 취약점을 잘못 위치시켰고 더 많은 오탐지(false positives)를 생성했습니다. 결정론 트레이드오프는 실제 문제입니다: BrassCoders는 정확한 라인을 고정하지만, 모델의 커버리지는 다양합니다.
데이터 처리 문제 (The Data-Handling Problem)
BrassCoders의 오픈 소스 코어는 외부 네트워크 호출을 전혀 하지 않고 0바이트를 기기 외부로 전송하며 brasscoders --offline scan으로 실행되는 반면, LLM 리뷰어는 모든 검토마다 사용자의 소스를 외부 API로 전송합니다.
데이터 처리 제약 조건이 있는 모든 코드베이스 — 내부 도구, 금융 기록, 의료 데이터, 개인 식별 정보(PII)를 처리하는 코드 —의 경우, 오프라인 경로가 모든 커밋에서 실행되어야 합니다. LLM 리뷰 경로는 실행할 때마다 정책 예외 처리가 필요하거나 자체 호스팅 모델이 필요합니다. 이 둘 중 어느 것도 게이트로서 확장성이 없습니다.
BrassCoders가 생성하는 결과 파일에는 스캐너 출력만 포함됩니다: 심각도, 파일 경로, 줄 번호, 수정 참고 사항. AI 어시스턴트가 .brass 파일에서 발견된 문제점을 분류할 때, 소스를 읽는 것이 아니라 발견된 요약 정보를 읽습니다. 따라서 분류 단계에서는 사용자의 소스가 로컬에 유지됩니다.
LLM이 여전히 우위를 점하는 부분
해당 모델은 BrassCoders의 벤치마크에서 어떤 정적 분석기(static analyzer)도 포착하지 못한 한 가지 문제점을 발견했습니다: 빈 리스트에 대한 방어 장치가 없는 sum(readings) / len(readings) — 아무 규칙도 일치시킬 수 있는 구조적 패턴을 남기지 않는 ZeroDivisionError입니다.
엣지 케이스에 대한 추론이 필요한 논리 버그는 모델의 영역입니다. 게이트는 구조적 패턴을 포착하고; 모델은 의도 실패(intent failures)를 포착합니다. ZeroFalse 논문과 Gnieciak and Szandala 벤치마크가 권장하는 올바른 패턴은 결정론적 게이트를 먼저 실행하고 그 위에 모델 검토를 계층화합니다. BrassCoders는 게이트를 실행하고; 사용자의 AI 에디터가 분류 작업을 처리합니다.
pip install brasscoders
brasscoders --offline scan /path/to/your/project
게이트가 실행됩니다. 모델이 분류합니다. 사용자가 둘 다 통과한 문제점들을 수정합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기