모든 AI 코드 리뷰의 사각지대는 결국 동일한 하나로 귀결된다
요약
AI 코드 스캐너가 잡아낼 수 없는 코드 리뷰의 사각지대를 '의도 실패'와 '런타임 실패' 두 가지 범주로 정의합니다. 스캐너는 코드의 형태는 파악하지만 그 의미와 의도를 이해하지 못한다는 근본적인 한계를 설명합니다.
핵심 포인트
- 코드 스캐너는 코드의 구조(form)는 보지만 의미(meaning)는 보지 못함
- 의도 실패: 올바른 코드와 잘못된 코드가 구조적으로 동일하여 발생하는 버그
- 런타임 실패: 소스 코드가 아닌 실행 중인 시스템 환경에서 발생하는 위험
- 로직 버그, 권한 확인 오류, 백도어 등은 패턴 매칭으로 탐지 불가
AI가 생성한 코드에서 코드 스캐너(code scanner)가 잡아낼 수 없는 모든 것은 하나의 근본 원인으로 요약됩니다. 스캐너는 '구조(structure)'를 보며, 스캐너가 놓치는 모든 것은 그 구조를 볼 수 있는 구조가 결여되어 있기 때문입니다. 이러한 누락은 정확히 두 가지 범주로 나뉩니다. 즉, 올바른 코드와 잘못된 코드가 동일한 형태를 공유하는 의도(intent) 실패, 그리고 문제가 실행 중인 시스템에서만 존재하는 런타임(runtime) 실패입니다. BrassCoders는 7개의 포스트에 걸쳐 한 번에 하나의 실패 사례를 통해 그 경계를 그려왔으며, 이것은 그 전체 지도를 한 페이지에 담은 것입니다.
일단 이 규칙을 이해하고 나면, AI 코드 도구가 할 수 있는 것과 할 수 없는 것의 전체 영역이 흩어진 결함 목록이 아니라, 그 모든 것을 관통하는 하나의 선으로 보이기 시작할 것입니다.
단 하나의 규칙
BrassCoders는 결정론적 패턴 보고자(deterministic pattern reporter)입니다. 위험하다고 알려진 형태를 매칭하고, 매 실행마다 동일한 방식으로 보고합니다. 이 도구의 한계를 정의하는 규칙은 간단합니다. 스캐너는 코드의 '형태(form)'는 볼 수 있지만 그 '의미(meaning)'는 볼 수 없다는 것입니다. 따라서 위험성이 형태가 아닌 의미에 존재하는 모든 버그는 튜닝의 문제가 아니라 구조적으로 스캐너에게 보이지 않습니다.
이 단 하나의 규칙이 모든 사각지대를 두 가지 유형으로 분류합니다. 버그가 스캐너를 피할 수 있는 이유는 소스 코드상에서 올바른 버전과 잘못된 버전이 동일하게 보이기 때문이며, 이것이 '의도 실패'입니다. 또는 위험이 소스 코드에는 전혀 존재하지 않고 오직 실행 중인 시스템에만 존재하기 때문에 피할 수 있는데, 이것이 '런타임 실패'입니다. 스캐너가 놓치는 그 어떤 것도 이 두 가지 범주를 벗어나지 않습니다.
의도 실패 (The Intent Failures)
BrassCoders는 의도를 검증할 수 없습니다. 올바른 코드와 잘못된 코드가 구조적으로 동일하여 매칭할 '나쁜 형태'가 없기 때문입니다. 7개의 경계 중 3개가 바로 이러한 실패에 해당합니다. 로직 버그(logic bug)는 잘못된 것을 계산하는 잘 구성된 코드이며, 깨진 권한 확인(broken authorization check)은 잘못된 규칙을 강제하는 그럴듯한 확인 절차이고, 의도적인 백도어(backdoor)는 알려진 양호한 코드처럼 보이도록 설계된 코드입니다.
이 세 가지 모두 한 가지 이유로 인해 패턴 매칭 (pattern matching)을 무력화합니다. 즉, 위험 요소가 코드가 '해야만 했던' 동작에 관한 사실이며, 그 의도가 규칙이 읽을 수 있는 곳 어디에도 작성되어 있지 않기 때문입니다. sum(readings) / len(readings)가 안전한지 여부는 리스트가 비어 있을 수 있는지에 달려 있고, 올바른 권한 확인 (authorization check)은 소유권 모델 (ownership model)에 달려 있으며, 백도어 (backdoor)는 작성자의 의도에 달려 있습니다.
각 실패 사례는 별도의 포스트로 다룹니다 — 로직 버그 (logic bug), 깨진 권한 확인 (broken authorization check), 그리고 실제 xz-utils 침해 사고 (xz-utils compromise)를 반영하는 의도적인 백도어 (deliberate backdoor)입니다. OWASP는 깨진 접근 제어 (broken access control)를 웹 위험 요소 1위로 선정했는데, 이는 애플리케이션의 의도가 버그를 정의하는 영역에서 자동화된 탐지가 가장 어려움을 겪기 때문입니다.
런타임 실패 (The Runtime Failures)
BrassCoders는 런타임 실패 (runtime failure)를 잡아낼 수 없습니다. 왜냐하면 위험 요소가 커밋된 소스 코드에는 전혀 나타나지 않기 때문입니다. 위험은 시스템이 실행될 때만 존재하며, 일곱 가지 경계 중 네 가지가 이러한 형태를 띱니다. 프롬프트 인젝션 (Prompt injection)은 에이전트가 런타임에 읽는 신뢰할 수 없는 콘텐츠를 통해 전달됩니다; 데이터 유출 (data leakage)은 모델이 추론 (inference) 시점에 민감한 데이터를 출력할 때 발생합니다; 설정 오류 (misconfiguration)는 배포 (deploy)의 속성입니다; 그리고 진짜 병목 현상은 실행 중인 워크로드 (live workload)에 대해 측정된 사실입니다.
이 중 그 어느 것도 저장소 (repository)에 리터럴 (literal) 형태로 존재하지 않습니다. 주입된 명령은 런타임에 README 파일에 실려 들어오고; 유출된 기록은 소스 코드가 아닌 모델의 컨텍스트 (context)를 통해 흐르며; 디버그 플래그 (debug flag)는 배포 시 환경 변수 (environment variable)에 의해 전환되고; 핫스팟 (hotspot)은 부하 상황에서 프로파일러 (profiler)가 측정하는 바로 그 라인입니다.
각각은 고유한 문제점을 가지고 있습니다 — 프롬프트 인젝션 (prompt injection), 데이터 유출 (data leakage), 설정 오류 (misconfiguration), 그리고 성능 병목 현상 (performance bottleneck). OWASP는 LLM 애플리케이션을 위한 Top 10 (Top 10 for LLM Applications)에서 런타임 (runtime) AI 리스크를 추적합니다. 코드베이스 전체를 스캔해도 찾을 수 있는 것이 없을 것입니다. 왜냐하면 실패의 원인이 코드에 있지 않기 때문입니다.
이것이 2계층 모델 (Two-Layer Model)을 강제하는 이유
BrassCoders는 결정론적 요소와 추론 요소의 분리를 제품 선호도가 아닌 구조적 사실로 취급합니다. 즉, 형태 (shape)와 의미 (meaning) 사이의 경계는 하나의 도구가 다른 도구로 작업을 넘겨주어야 하는 지점입니다. 스캐너 (scanner)는 형태 계층을 완전히 점유하며 그 너머까지 도달할 수 없습니다. 의도 (intent)에는 추론기 (reasoner)가 필요하고, 런타임 (runtime)에는 모니터 (monitor)가 필요하며, 아무리 규칙을 많이 작성하더라도 패턴 매처 (pattern matcher)를 이 중 어느 하나로 바꿀 수는 없습니다.
이것이 제품 전체가 기반하고 있는 분업입니다. BrassCoders는 구조적 발견 사항을 결정론적이고 재현 가능하게 보고하며, 출력을 읽는 AI 어시스턴트 (AI assistant)는 의도에 대해 추론하고, 런타임 제어 (runtime controls)는 실행 중인 시스템을 관리합니다. 각 계층은 다른 계층이 구조적으로 할 수 없는 일을 수행합니다. 과도한 약속을 하는 모든 "AI 코드 리뷰" 도구의 실패 모드 (failure mode)는 하나의 계층이 세 가지 모두를 커버한다고 주장하는 것입니다.
각 측면에서 발생하는 것
BrassCoders는 형태 (shape)를 포착하고, 추론 계층 (reasoning layer)은 의도 (intent)를 포착하며, 런타임 계층 (runtime layer)은 동작 (behavior)을 포착합니다. 참조용으로 나열하면, 7개의 경계와 그 인계 (handoffs) 과정은 각각 하나의 열에 정렬됩니다.
| 계층 (Layer) | 포착하는 내용 (What it catches) | 포착하는 주체 (Who catches it) |
|---|---|---|
| Shape (정적 상태) | SQL 인젝션 (SQL injection), 취약한 암호화 (weak crypto), 비밀 정보 (secrets), 커맨드 인젝션 (command injection), 성능 안티 패턴 (perf anti-patterns) | BrassCoders (결정론적 스캔 (deterministic scan)) |
| ... |
이 지도가 곧 논거입니다. 특정 버그가 어느 열에 존재하는지 알려주는 도구는 이미 어떤 도구가 그것을 잡아낼 것인지도 알려준 셈이며, 세 개의 열 모두를 잡아낼 수 있다고 주장하는 스캐너는 구조적으로 제공할 수 없는 확신을 팔고 있는 것입니다.
pip install brasscoders
brasscoders --offline scan /path/to/your/project
Shape 계층에 대해 스캔을 실행하세요. 의도 (intent)는 추론기 (reasoner)로 보내고, 런타임 (runtime)은 모니터 (monitor)로 보내세요. 하나의 규칙이 각각이 무엇인지 알려줄 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기