16. 독립 보안 라벨 검증
기준선 평가: 2026-07-14 · 재검증: 2026-07-15 · 도구:
jam v0.40.0· Metrics Spec:v14.0.0· 지표 세트:jam-lite --only SEC
이 문서는 프로젝트 점수 회귀 코퍼스와 분리된 첫 외적 타당화 기준선이다. 기존 16개 E2E 저장소는 JAM 개발 과정에서 반복 관찰한 regression 표본이므로 “취약점을 맞혔는가”의 정답지가 아니다. 여기서는 JAM 결과를 보기 전에 지원 범위를 선언하고, 독립적으로 제공된 테스트별 라벨과 비교한다.
1. 데이터셋과 고정 계약
OWASP Benchmark는 정적·동적 보안 도구의 정확도를 비교하기 위한 실행 가능한 테스트 모음이며, 각 테스트의 실제 취약 여부와 CWE를 expectedresults로 제공한다. OWASP가 정의한 기본 결과 단위와 산식은 TP, FN, TN, FP, TPR(TP/(TP+FN)) 및 FPR(FP/(FP+TN))이다. 원본은 OWASP BenchmarkJava 저장소에 있다.
| 항목 | 고정값 |
|---|---|
| Dataset | OWASP Benchmark for Java 1.2 |
| Repository commit | 79b9bd6177e07991a9c11dc19e457c840e229931 |
| Label file | expectedresults-1.2.csv |
| Label SHA-256 | 1809f6a690c6cf7dd6685df6ebe2eef8fe3ca93d19a7ca0ce45987ca4f5d78e1 |
| 전체 라벨/소스 | 2,740 / 2,740 |
| JAM 지원 범위 | 1,001 cases |
| Partition | validation |
testdata/labeled-benchmarks.yaml이 commit, label digest, 라벨/소스 수, CWE 매핑과 관측 baseline을 한곳에 고정한다. tools/labeled-benchmark는 clone origin, detached commit, clean Git tree, 라벨 digest, 라벨-소스 1:1 대응, JAM run manifest v2의 complete integrity와 Java/SEC coverage, CSV 26열 계약을 검사한다.
2차 교차 검증 후보는 NIST SARD의 Juliet Java 1.3이다. NIST는 이 버전을 112개 CWE, 28,881개 테스트로 제공한다. 이번 baseline에는 섞지 않았으며 별도 adapter와 holdout 규칙이 생긴 뒤 추가한다.
2. 사전 선언한 평가 범위
결과를 본 뒤 유리한 항목만 고르는 것을 막기 위해 다음 매핑을 첫 실행 전에 고정했다.
| OWASP CWE | Category | JAM metric | Cases | 포함 이유 |
|---|---|---|---|---|
| 78 | cmdi | SEC-02 | 251 | Java 명령 실행 패턴을 명시적으로 지원 |
| 89 | sqli | SEC-02 | 504 | Java 동적 SQL 결합을 명시적으로 지원 |
| 327 | crypto | SEC-03 | 246 | Java 약한 암호 사용을 명시적으로 지원 |
지원하지 않는 CWE를 음성 사례로 세어 precision을 부풀리지 않는다. CWE별로 지정된 metric이 해당 BenchmarkTestNNNNN.java에 하나 이상 있으면 predicted positive다. 같은 테스트에 finding이 여러 개여도 한 번만 센다. 이 방식은 OWASP의 테스트 케이스 단위 판정과 맞으며 line-level finding 수를 분류 정확도로 오인하지 않는다.
추가로 precision은 TP/(TP+FP), recall은 OWASP TPR과 같은 TP/(TP+FN), F1은 precision과 recall의 조화 평균으로 계산한다. Aggregate는 세 CWE의 confusion count를 먼저 합친 micro average다.
3. Metrics v13 기준선과 Metrics v14 재검증
Metrics v14는 jam-full companion 계약만 바꾸고 JAM Lite SEC analyzer·비용·상한·집계는 바꾸지 않았다. 현재 도구 identity(v0.40.0 / metrics v14.0.0)로 같은 고정 commit을 재실행해 아래 confusion matrix가 v13 기준선과 동일함을 확인했다.
| Scope | TP | FN | TN | FP | Precision | Recall/TPR | FPR | F1 |
|---|---|---|---|---|---|---|---|---|
| Micro aggregate | 354 | 174 | 157 | 316 | 52.84% | 67.05% | 66.81% | 59.10% |
| CWE-78 / cmdi / SEC-02 | 113 | 13 | 15 | 110 | 50.67% | 89.68% | 88.00% | 64.76% |
| CWE-89 / sqli / SEC-02 | 241 | 31 | 26 | 206 | 53.91% | 88.60% | 88.79% | 67.04% |
| CWE-327 / crypto / SEC-03 | 0 | 130 | 116 | 0 | 0.00% | 0.00% | 0.00% | 0.00% |
이 결과는 현재 Java SEC 구현이 “precision 우선” 목표를 달성했다고 뒷받침하지 않는다.
- SEC-02는 높은 recall과 함께 안전 사례도 거의 같은 비율로 보고한다. 현재 Java 규칙은 동적 SQL 구성 또는 명령 호출의 비리터럴 인자를 탐지하지만, OWASP의 안전/취약 분기를 가르는 source-to-sink 흐름과 sanitizer 의미를 충분히 추적하지 않는다.
- SEC-03의 Java 범위가 OWASP CWE-327 사례와 맞지 않는다. 현재 구현은 주로
MessageDigest.getInstance("MD5"|"SHA-1")를 보지만 Benchmark의 crypto 분류는 다른 약한 cipher 사용도 포함하므로 이 범위에서 recall이 0이다. - Aggregate recall 67.05%만 보면 SEC-02의 넓은 탐지가 SEC-03 공백을 가린다. 따라서 aggregate 하나가 아니라 CWE별 confusion matrix를 항상 함께 보존한다.
이 baseline은 JAM 전체 보안 성능, 다른 언어, 실제 애플리케이션의 FP/KLOC를 대표하지 않는다. OWASP Benchmark는 의도적으로 단순화된 Java servlet 테스트이며, 이번 평가는 사전 선언한 세 CWE에만 해당한다. 프로젝트의 25/F 같은 JAM 점수도 분류 정확도와 다른 측정값이므로 이 문서의 판단 근거로 사용하지 않는다.
4. 재현과 CI
go build -o /tmp/jam-validation ./cmd/jam
go run ./tools/labeled-benchmark --validate-only
go run ./tools/labeled-benchmark \
--jam /tmp/jam-validation \
--cache-dir .cache/jam-validation/repos \
--out-dir reports/labeled-benchmark
산출물은 원본 JAM 5종과 summary.json, summary.md다. summary.json은 jam/labeled-benchmark-summary@1이며 docs/schemas/jam-labeled-benchmark-summary.schema.json으로 검증할 수 있다. .github/workflows/labeled-benchmark.yml은 관련 SEC/측정 계약 변경이 있는 PR과 main push, 주간 schedule에서 baseline confusion matrix를 재검증하고 증적을 artifact로 남긴다.
5. 이 결과로 내리는 결정
- 점수 공식을 바꾸지 않는다. 단일 Java benchmark 결과만으로 category weight, grade cut, cap, remediation cost를 조정하면 외적 타당화가 아니라 benchmark 맞춤 튜닝이 된다.
- Java SEC-02의 source-to-sink 구분을 우선 개선한다. command/SQL 생성 자체가 아니라 request 유래 값이 실제 sink에 도달하는지, parameterization 또는 sanitizer가 흐름을 끊는지를 구분해야 한다.
- Java SEC-03 지원 선언과 구현을 맞춘다. CWE-327에서 어떤 cipher/API를 지원할지 표준 근거와 음성 fixture를 먼저 명시한 후 analyzer를 확장한다.
- 모든 개선은 동일 holdout에서 TP 증가와 FP 비증가를 함께 확인한다. baseline 갱신은 코드·Metrics Spec·근거 문서 변경과 같은 review에서만 허용한다.
- 다음 외적 타당화는 두 축으로 분리한다. NIST Juliet adapter로 보안 CWE를 교차 검증하고, 별도의 실제 app/library/CLI 표본에서는 finding review 기반 precision·FP/KLOC·순위 안정성을 측정한다.