
GitHub의 `/security-review` 명령어를 사용해 본 후의 생각
요약
GitHub Copilot CLI의 실험적 기능인 `/security-review` 명령어의 보안 취약점 탐지 성능을 검증하기 위한 실험 보고서입니다. OWASP Juice Shop을 활용해 다양한 모델(Claude, GPT 시리즈)이 실제 보안 취약점을 얼마나 정확히 찾아내는지 테스트했습니다.
핵심 포인트
- Copilot CLI의 /security-review 기능은 코드 변경점의 취약점을 분석함
- OWASP Juice Shop을 활용해 14개의 보안 취약점을 대상으로 실험 설계
- 모델 성능(Haiku vs Opus 등)에 따른 보안 탐지 정확도 차이 분석
- 비대화형 실행을 위한 --no-ask-user 플래그의 중요성 확인
지난주 업무용 계정에 Copilot CLI를 설정하던 중, 실험적인 /security-review 명령어를 발견했습니다. 이에 대한 별도의 공지를 보지 못했기에, 어떻게 작동하는지 궁금하여 조금씩 살펴보았습니다.
이 명령어가 하는 일을 요약하자면 다음과 같습니다: 코딩 세션을 마치면, 명령어가 diff(차이점)를 읽고 발생 가능성이 높은 취약점 목록을 생성합니다. 이론적으로는 매우 유용합니다. 하지만 수동으로 살펴보면서 알 수 없었던 점은 기반이 되는 모델(model)이 얼마나 중요한가 하는 것이었습니다. Haiku 대신 Opus를 선택하는 것이 실제로 더 나은 보안 탐지 결과를 제공하는 것일까요, 아니면 단순히 더 화려한 래퍼(wrapper)를 위해 동일한 답변에 비용을 지불하는 것일까요?
그래서 이를 알아내기 위해 OWASP Juice Shop을 활용한 작은 테스트 환경(harness)을 구축했습니다. 이는 제 업무용 구독 서비스를 통해 진행한 소규모 실험이었습니다. 이 포스트는 그 실험의 결과물입니다.
설정 (The setup)
정답지(answer key)가 알려진 대상이 필요했고, Juice Shop은 제가 이전에 살펴본 적이 있는 앱입니다. 이는 알려진 문제 카탈로그가 포함된 데모용 취약 Node.js 앱입니다. 저는 원본 앱을 가져와 기존 취약점으로부터 10가지 변경 사항을 만들었습니다. 각 변경 사항은 단순히 카탈로그에 등록된 하나 이상의 취약점을 다시 도입하는 방식입니다. 10가지 변경 사항 전체에 걸쳐 총 14개의 취약점이 있었습니다:
- SQL injection (SQL 인젝션)
- Weak crypto (취약한 암호화)
- SSRF (서버 측 요청 위조)
- Path traversal (경로 탐색)
- XXE (XML 외부 엔티티)
- Insecure deserialization (안전하지 않은 역직렬화)
- Broken access control (취약한 접근 제어)
- Hardcoded credentials (하드코딩된 자격 증명)
- Missing rate limiting (속도 제한 누락)
- Open redirect (오픈 리다이렉트)
파일, CWE, 그리고 한 줄 설명이 포함된 정답(ground truth)은 catalogue.md에 저장되어 있습니다. AI 리뷰어는 /security-review 프로세스 동안 이 파일을 절대 보지 못합니다.
각 변경 사항에 대해, 저는 /security-review를 비대화형(non-interactively)으로 실행하고 출력을 캡처합니다.
--no-ask-user 플래그가 중요합니다. 이 플래그가 없으면 명령어가 초기 패스(pass) 이후 입력 대기를 위해 일시 중지되는 것처럼 보이며 스크립트 내에서 종료되지 않습니다. 이 플래그를 사용하면 깔끔한 JSON 스트림과 실행에 소비된 크레딧(credits)을 포함하는 최종 result 이벤트를 얻을 수 있습니다.
그 후, 별도의 고정된 LLM 채점기(grader)가 카탈로그(catalogue)와 리뷰어의 출력물을 가져와 각 변경 사항에 대해 세 가지 수치인 탐지됨(detected), 놓침(missed), **오탐(false positives)**을 생성합니다. 채점기는 카탈로그를 보지만, 리뷰어는 보지 못합니다. 채점 모델은 모든 실행 과정에서 일정하게 유지되므로, 채점기의 편향(bias)은 일정한 오프셋(offset)으로 작용합니다. 저는 이번 실험에서 규모를 크게 가져가기로 결정하고 Opus 4.6을 사용했습니다.
저는 이를 5개 모델 × 4회 독립 실행 × 10개 변경 사항 = 총 200회 리뷰에 걸쳐 실행했습니다. 작은 표본이긴 하지만, 요즘 토큰(tokens) 비용이 비싸고 저는 예산이 아닌 호기심으로 비용을 충당하고 있었기 때문입니다. 전반적인 형태를 파악하고 향후 작업을 계획하기에는 충분한 양이라고 생각합니다.
테스트된 모델: Claude Haiku 4.5, Sonnet 4.6, Opus 4.6, GPT-5.4, GPT-5.5. 이들은 모두 현재 Copilot CLI에서 선택 가능한 모델들입니다.
결과
4회 실행에 대한 평균 탐지율(mean detection rate)과 범위 및 표준 편차(standard deviation):

claude-opus-4.6 93% (93–93, σ 0.0) 2.5 FPs 30.0 credits/run
gpt-5.5 91% (86–93, σ 3.6) 0.8 FPs 75.0 credits/run
claude-sonnet-4.6 86% (79–93, σ 8.2) 0.8 FPs 10.0 credits/run
...
두 가지 사항이 눈에 띄어 글로 남길 가치가 있다고 느꼈습니다.
1. Haiku 4.5가 Sonnet 4.6과 동일한 평균 탐지율을 기록하면서 비용은 약 1/3 수준
두 모델 모두 평균 탐지율 86%를 기록했습니다. Haiku는 10개 변경 사항 스윕(sweep)당 3.3 크레딧이 소요되는 반면, Sonnet은 10 크레딧이 소요됩니다. 이 벤치마크에서 동일한 결과에 대해 3배의 비용 차이가 발생하는 것입니다.
만약 활발하게 운영되는 저장소(repo)의 모든 PR(Pull Request)에 대해 /security-review를 실행할 계획이라면, 이 부분이 가장 먼저 검토해야 할 항목처럼 느껴집니다. Sonnet이 평균적으로 오탐(false positives)이 약간 더 적지만(0.8 대 1.2), 그 차이가 매우 근소하여 이런 종류의 작업에는 Haiku를 사용하고, 중요하지 않은 결과는 더 큰 모델을 사용하여 수정하거나 버리는 방식을 고려하게 만들었습니다.
2. Opus는 실행 시 변동성이 없는 유일한 모델입니다
Opus는 매번 14개 중 13개를 맞혔습니다. 동일한 탐지율, 동일하게 놓친 취약점, 네 번의 실행 모두 결과가 같았습니다.
다른 모델들은 모두 변동이 있었습니다. Sonnet은 네 번의 실행 동안 79%에서 93% 사이의 범위를 보였습니다. Haiku도 마찬가지였습니다. 이는 "동일한 입력에 대한 동일한 모델"임에도 불구하고 **14%포인트의 변동(swing)**이 발생했음을 의미합니다.
만약 당신의 보안 게이트(security gate)가 단 한 번의 /security-review 실행이며, 그것이 중간 단계의 모델이라면, 당신은 부분적으로 노이즈를 보고 있는 것입니다. 이번 작업을 하기 전 제가 예상했던 것보다 재실행(re-running)이 더 중요하며, 따라서 저렴한 모델로 반복 실행하는 것이 프런티어 모델(frontier models) 중 하나만큼 성능이 좋으면서도 비용은 더 저렴할 가능성이 있습니다.
비용 문제

크레딧(Credits)은 모델별로 분류됩니다. 모든 Haiku 실행은 약 3.3의 비용이 들었고, 모든 Opus 실행은 30.0이 들었습니다. 따라서 이것은 일화적인 비용 데이터가 아니라, 테스트를 기반으로 한 가격표입니다:
| 모델 | 10개 변경 사항 스윕(sweep)당 크레딧 | Haiku 대비 |
|---|---|---|
| claude-haiku-4.5 | 3.3 | 1.0× |
| ... |
이 벤치마크가 저를 진정으로 불확실하게 만든 지점은 이것입니다: 이러한 종류의 분석이 프런티어 모델을 사용하며 소비하는 토큰(tokens)만큼의 가치가 있는가?
Haiku로 주당 100개의 PR을 처리하는 팀은 보안 검토에 주당 약 330 크레딧을 지출합니다. GPT-5.5에서 동일한 작업량을 수행하면 약 7,500 크레딧이 듭니다. 엔지니어링 예산에서 크레딧 비용을 지불한다면 이는 의미 있는 숫자이며, Haiku의 경우 비용 대비 편익(cost-benefit)이 명확할 정도로 비용이 작습니다. 반면 GPT-5.5의 경우, 탐지율이 단 1%포인트 낮음에도 불구하고 22배 더 많은 비용을 지불하게 되는데, 이는 정당화하기가 더 어렵습니다. 특히 많은 기업이 이미 어느 정도의 보안 도구(security tooling)를 구축해 놓았을 가능성을 고려하면 더욱 그렇습니다.
제 의견은 이렇습니다: 리스크가 큰 차이점(high-stakes diffs)에 대해서는 **아마도 그렇다(yes)**이지만, 나머지 대다수의 일반적인 경우(long tail)에는 아니다(no)입니다. 하지만 이 도구는 현재 당신이 그런 결정을 내리도록 도와주지는 않습니다. 그러므로 선택하는 모델에 유의하십시오.
면책 조항 (Disclaimer): 이것은 재미로 만든 사이드 프로젝트이며, 심도 있는 연구가 아닙니다
저는 불확실하고 거창한 주장보다는 작더라도 확실한 주장을 하는 편이 낫다고 생각하기에, 다음과 같은 점을 밝힙니다:
- n=4는 작은 표본입니다. "Haiku가 Sonnet과 대등하다"는 발견은 이 실행 결과들과 일치하지만, 통계적으로 확립된 것은 아닙니다. 실행 횟수를 늘리면 더 명확해질 수 있겠지만, 회사의 토큰을 여기에 전부 쏟아붓지는 않을 것입니다. AI가 제 업무를 대신 수행하도록 할 토큰도 남겨두어야 하니까요.
- Juice Shop는 매우 잘 알려져 있습니다. 다섯 가지 모델 모두의 학습 데이터 (training data)에 거의 확실히 포함되어 있을 것이며, 이는 점수를 대략적으로 균일하게 부풀릴 수 있습니다. 그렇기 때문에 여기서 흥미로운 비교 대상은 절대적인 탐지율 (detection rates)이 아니라 모델 간의 비교입니다. 더 나은 벤치마크 (benchmarks)가 있다는 것을 알고 있지만, 저는 그저 제가 아는 작은 것으로 장난을 치고 싶었을 뿐이며, 그래서 익숙한 것을 선택하기로 했습니다. 벤치마크를 구축하는 데 토큰을 조금 더 사용했습니다.
- 채점자 (grader)가 카탈로그를 보고 있습니다. 채점자는 "이 발견이 카탈로그에 등록된 취약점 (vuln)과 일치하는가"에 맞춰 조정되어 있는데, 이는 완벽한 1:1 매칭이 아니며 AI가 틀릴 수도 있습니다. 몇 가지 일치 사례를 무작위로 점검해 보았을 때 정확했으므로, 채점자가 특히 Opus 4.6 모델에 대해 괜찮은 성능을 보인다고 믿습니다.
- 단일 워크로드 (workload). 이것은 일반적인 OWASP 클래스의 버그가 포함된 Node.js 디프 (diffs)에 대한
/security-review테스트입니다. 다른 언어의 경우 결과가 다를지는 알 수 없습니다. 인기가 적은 언어들은 탐지율에서 더 큰 차이를 보일 수도 있다고 추측합니다. - 모델은 변합니다. 지금은 2026년 5월 말입니다. 만약 여러분이 나중에 이 글을 읽고 있다면, 모델의 가격 및 기능 변화로 인해 결론이 달라질 수 있습니다.
만약 이 프로젝트에 제대로 자금을 지원한다면 제가 다음에 할 일
- 모델당 n을 10 이상으로 늘려 Haiku 대 Sonnet 문제를 해결하겠습니다.
- 학습 데이터의 영향을 중립화하기 위해 Juice Shop과 병행하여 프라이빗 리포지토리 (private repo) 벤치마크를 추가하겠습니다.
- "합집합을 사용한 2× Haiku"와 "1× Opus"를 정면 대결(head-to-head)로 테스트하겠습니다. 이것이 이 데이터가 제기하는 가장 유용한 실무적 질문이며, 여전히 미해결 상태로 남아 있습니다.
- 평가자 간 신뢰도 (inter-rater calibration)를 위해 두 번째 독립적인 채점자를 추가하거나, 더 결정론적인 (deterministic) 방식을 도입하겠습니다.
만약 /security-review를 사용해 보면서 서로 다른 패턴을 발견했거나, 어떤 코드베이스가 더 나은 대상이 될지에 대한 아이디어가 있다면 진심으로 듣고 싶습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기