Repository navigation
Releases: KimJeju/cpguard
Release list
v0.2.0 — accuracy overhaul + MCP server
Two big axes since v0.1.4 (70 commits).
Accuracy — measured on labelled ground truth, 8 languages
Every gain came from a defect the numbers exposed, not test-fitting. Score = recall − false-positive rate (the official OWASP metric; random = 0.000).
| before | now | |
|---|---|---|
| Java | 0.80 | 0.83 |
| Go | 0.15 | 0.66 |
| C++ | 0.10 | 0.80 |
| C | 0.19 | 0.52 |
Behind it: derived-value guards, receiver accumulation, closures/channels, ternary constant-set, and a measured storage-source policy. Honest caveats (especially why C/C++ precision reaches 100% on small corpora) are in bench/README.md.
MCP server — an AI agent can dynamically validate the findings
pip install "cpguard[mcp]". An agent (Claude Code, Cursor) drives CPGuard over MCP: scan, pull the source→sink evidence, explain a rule, and prove a finding at runtime. CPGuard knows the sink, so it emits a probe + an oracle (what to observe that proves the sink fired); the agent fires it with its own tools, and CPGuard judges CONFIRMED / LIKELY / NOT_REPRODUCED / FALSE_POSITIVE.
Oracle-match, not IAST — no instrumentation, so it reports "the predicted signal appeared", not "I observed the real execution path". The core opens no socket. 9 tools; design and boundaries in docs/mcp-server-design.md.
Windows installer attached below. From source: pip install . (add [mcp] for the MCP server).
CPGuard v0.1.4
CPGuard 0.1.4
이번 버전은 리눅스 환경에서 실제로 CPGuard를 돌려보면서 발견한 문제들을 먼저 정리했습니다.
겉으로는 스캔이나 출력이 정상적으로 끝난 것처럼 보이지만 실제 결과를 열어보면 문제가 있는 경우가 꽤 있었습니다. 이번에는 이런 문제들을 중심으로 안정성을 보완했고, 탐지 이후 판정을 얼마나 빠르게 처리할 수 있는지, 그리고 그 결과가 화면과 산출물에 어떻게 이어지는지까지 진단 워크플로를 크게 손봤습니다.
🔧 실제 환경에서 발견한 문제 수정
스캔 제외 경로
tmp, build 같은 이름의 디렉터리가 프로젝트 상위 경로에 포함되어 있으면 해당 이름 때문에 프로젝트 전체가 제외되는 문제가 있었습니다.
특히 리눅스에서 /tmp 아래에 프로젝트 압축을 풀어 테스트할 때 쉽게 발생할 수 있는 문제였습니다.
이제 제외 디렉터리는 전체 절대경로가 아니라 스캔 루트 기준 상대경로로 판단합니다.
한글 PDF 깨짐
한글 폰트가 없는 서버에서 PDF를 생성하면 파일은 정상적으로 열리지만 본문이 전부 ■로 표시되는 문제가 있었습니다.
나눔고딕(OFL-1.1)을 패키지에 포함했고, 시스템에 사용 가능한 한글 폰트가 있으면 해당 폰트를 우선 사용합니다.
사용 가능한 폰트를 하나도 찾지 못한 경우에는 깨진 PDF를 생성하지 않고 오류로 중단하도록 변경했습니다.
SARIF 줄 번호
.env, id_rsa처럼 정확한 줄 번호를 알 수 없는 탐지에서 SARIF의 startLine이 0으로 출력되는 문제가 있었습니다.
SARIF의 줄 번호는 1부터 시작하기 때문에 GitHub Code Scanning에서 결과 전체가 거부될 수 있습니다.
이제 줄 번호가 0 이하로 계산되는 경우 최소 1로 보정합니다.
의존성 ZIP 때문에 프로젝트가 배치로 오판정되는 문제
기존에는 압축 내부에 .zip 파일이 하나라도 있으면 여러 프로젝트를 묶은 배치로 판단했습니다.
이 때문에 Yarn PnP 프로젝트의 .yarn/cache/*.zip 같은 의존성 파일까지 프로젝트로 인식하면서, 약 5GB 규모의 프로젝트 하나가 1,762건의 스캔으로 쪼개지는 문제가 발생했습니다.
이제는 ZIP이 아닌 파일이 함께 존재하는 경우 단일 프로젝트로 판단하도록 기준을 변경했습니다.
진단 대상 때문에 도구가 영향을 받는 경로 수정
진단 대상 자체가 CPGuard의 동작을 방해할 수 있는 몇 가지 경로도 함께 수정했습니다.
-
압축 해제 시 아카이브가 신고한 크기를 그대로 믿고 무제한 스트리밍하던 문제
- 실제로 기록한 바이트 기준으로 상한을 적용합니다.
-
마스킹 규칙이 자신의 매치만 가리던 문제
- 주민등록번호와 사설 IP처럼 서로 다른 규칙의 결과가 같은 줄에 있을 때 다른 규칙의 원문이 그대로 노출되지 않도록 수정했습니다.
-
파일 경로와 소스 코드가 이스케이프 없이 Excel 셀에 들어가던 문제
- Excel 수식 인젝션이 발생하지 않도록 처리했습니다.
🔍 분석 정확도 개선
안전하게 검증된 분기는 탐지에서 제외
다음과 같이 값을 변경하지 않고 안전성을 검증하는 코드가 기존에는 오탐의 원인이 되는 경우가 있었습니다.
if (is_numeric($x)) {
query($x);
}이제 조건문에서 실제로 검증된 경로를 분석에 반영합니다.
즉, is_numeric($x)처럼 안전성을 확인한 값은 참 분기에서 탐지 대상에서 제외하고, 반대로 !is_numeric($x)처럼 검증에 실패한 위험 경로는 그대로 탐지합니다.
프레임워크 진입점 인식
Spring 컨트롤러의 파라미터는 프레임워크가 값을 주입하기 때문에 코드 내부에서 직접 호출되는 지점이 없습니다.
기존에는 호출자를 찾지 못해 컨트롤러 파라미터 자체가 진입점으로 인식되지 않는 문제가 있었습니다.
이번 버전부터 다음과 같은 프레임워크 입력 지점을 진입점으로 인식합니다.
- Spring:
@RequestParam,@PathVariable,@RequestBody등 9종 - ASP.NET Core:
[FromQuery],[FromBody]등 5종 - Java / Kotlin / C# 지원
어노테이션이 없는 일반 파라미터는 기존과 동일하게 처리합니다.
🧭 진단 워크플로 개선
이번 버전에서는 탐지 이후의 판정 과정을 크게 개선했습니다.
판정 결과를 화면에 즉시 반영
판정은 단순히 상태만 변경하는 것이 아니라 화면의 숫자에도 바로 반영됩니다.
조치완료 또는 오탐으로 판정하면 새로고침하지 않아도:
- 조치 대상 건수
- 등급별 건수
가 즉시 줄어듭니다.
반면 탐지 총계는 그대로 유지합니다.
탐지 총계는 이번 스캔에서 실제로 발견한 사실이고, 판정에 따라 줄어드는 것은 현재 남아 있는 작업량이기 때문입니다.
재진단 시 판정 승계
같은 이슈를 매번 처음부터 다시 판정할 필요가 없도록 했습니다.
다음 정보를 기준으로 이슈의 지문을 만들고, 재진단 결과가 이전 지문과 동일하면 직전 스캔의 판정과 의견을 자동으로 가져옵니다.
- 규칙
- 파일
- 공백을 정규화한 Sink 코드
승계된 판정 건수도 화면에서 확인할 수 있습니다.
일괄 판정
필터로 결과를 좁힌 뒤 해당 결과 전체를 한 번에 판정할 수 있도록 했습니다.
반복적으로 같은 상태를 지정해야 하는 작업을 줄였습니다.
흐름 내용 필터
데이터 흐름을 따라가면서 호출 또는 변수를 기준으로 결과를 필터링할 수 있습니다.
- 전체 / Source / Sink
- 포함 / 미포함
- 정규식
을 지원합니다.
그 밖의 진단 관리 기능
이번 버전에서 다음 기능도 추가했습니다.
- 판정 이력
- 저장하고 다음
- 유사 이슈 그룹
- 진단 중단
- 다건 삭제
- 진행 중인 진단으로 돌아가기
📄 산출물 개선
보고서 양식 관리
보고서에서 사용할 항목을 직접 관리할 수 있도록 했습니다.
- 절 포함 / 제외
- 표지 제목
- 머리말
- 로고
각 설정을 이름을 붙여 저장하고, 보고서 내보내기 시 원하는 양식을 선택할 수 있습니다.
합본 보고서에도 동일하게 적용됩니다.
제외 설정과 부록
프로젝트별로 다음 정보를 저장합니다.
- 제외 경로
- 제외 규칙
- 제외 사유
그리고 실제 진단에 사용된 설정을 보고서에도 포함합니다.
보고서의 부록 B·C에서 확인할 수 있습니다.
분석 대상 현황
분석 대상에 대한 현황도 보고서에 추가했습니다.
- 언어별 파일 수
- 라인 수
- 탐지 건수
- 탐지 밀도
흐름 불확실성 표시
분석 대상에 실제 코드가 없는 함수를 거치는 데이터 흐름은 별도로 표시합니다.
분석 결과만 보고 흐름이 완전히 확인된 것으로 오해하지 않도록 하기 위한 표시입니다.
📋 점검 기준 정비
모바일 앱 보안약점 점검기준
국가법령정보센터의 [별표 3] 원문과 대조해 26개 항목으로 정비했습니다.
기존에 빠져 있던 다음 항목도 추가했습니다.
- 오버플로우(정수형, 메모리 버퍼)
- 소스코드 난독화 미적용
설계단계 보안설계 기준
구현단계 49개와 짝을 이루는 설계단계 보안설계 기준 20개 를 추가했습니다.
설계서를 확인해야 하는 항목이라 정적 분석으로는 판단할 수 없기 때문에 모두 「진단 대상 아님」으로 표시합니다.
확인할 수 없는 항목을 임의로 「양호」로 처리하지 않습니다.
구현단계 기준
구현단계 49개는 별표 원문과 항목 및 분류가 일치하는지 다시 확인했고, 표기만 일부 정정했습니다.
🧪 테스트
실제 환경에서의 안정성을 확인하기 위해 테스트 범위도 확대했습니다.
-
Ubuntu Runner 기반 CI 추가
-
OWASP Benchmark v1.2
- N = 1,572
- F1 = 0.689
- Score = 0.392
-
전체 테스트 298개
📦 배포
Windows 환경에서는 Python을 별도로 설치하지 않아도 바로 실행할 수 있도록 설치 파일을 제공합니다.
CPGuard-Setup-0.1.4.exe
이번 0.1.4는 단순히 탐지 규칙을 추가한 버전이라기보다, 실제 Linux 환경에서 발견된 문제를 해결하고 진단 → 판정 → 재진단 → 보고서까지 전체 흐름을 다듬은 버전입니다.
CPGuard v0.1.3
✅ Assessment standards / 점검 기준
Pick the reference the findings are judged by, before the scan starts — several at once:
진단 시작 전에 판정 기준을 고릅니다. 복수 선택이 가능합니다.
- 행정안전부 소프트웨어 개발보안 가이드 — MOIS secure coding weaknesses (7 categories)
- 전자금융감독규정 웹 취약점 — the web checklist Korean finance assessments apply in parallel
- OWASP Top 10 (2021) · CWE
The mapping key is CWE, so the scan runs once and the standards only shape the report — switching or adding a reference never means rescanning. Filter the review screen by check item, group the issue list by it, and tick which standards each export carries.
A check item with no rule behind it is never reported as "pass." Items outside static analysis — directory indexing, admin page exposure, CSRF — are marked 진단 대상 아님 / Not assessed, so the deliverable never claims a check that did not happen.
규칙이 없는 항목은 양호로 찍지 않고 '진단 대상 아님'으로 표기합니다.
📄 Consolidated assessment report / 합본 진단 결과 보고서
Tick the projects on the Reports screen and get one submission-ready document covering all of them, in Word (.docx) and PDF. The Word file is the editable master, so the analyst can drop it into the client's template and ship it.
리포트 화면에서 프로젝트를 체크하면 전체를 한 문서로 묶습니다. Word 본이 편집 원본입니다.
1. 취약점 진단 개요 진단 목적·근거 고시 / 수행 일정 / 점검 도구 / 점검 수행 인원
2. 진단 항목 기준별 유형·설명·항목 수
3. 진단 결과 3.1 최초 진단 결과 (프로젝트별 파일 수·빌드 라인·위험도별 검출)
3.2 진단 결과 점검 (오탐/제외 사유와 진단원 의견)
3.3 최종 점검 결과 + 3.3.x 프로젝트별 상세
4. 유형별 조치 권고 5. 종합 의견
The review verdicts become the report. Marking a finding as a false positive or excluding it on the review screen — with the note explaining why — is what turns a raw scanner dump into a deliverable. Section 3.2 is built from exactly those verdicts, and the initial/final totals differ accordingly.
Every deliverable is now black text on light grey — assessment reports travel as black-and-white printouts and get pasted into the client's own template, so nothing is distinguished by colour alone.
🎯 Engine accuracy / 엔진 정밀도
Measured against OWASP Benchmark v1.2 (Java, N = 1,572) over the six data-flow categories:
| Recall | Precision | F1 | FP rate | Score | |
|---|---|---|---|---|---|
| before | 19.7% | 88.2% | 0.323 | 6.1% | 0.137 |
| v0.1.3 | 65.1% | 73.2% | 0.689 | 25.9% | 0.392 |
Every point came from a defect the numbers exposed — not from tuning to the test cases:
- Taint died inside
tryblocks — the block was folded into an opaque node, losing statement order. Java puts almost everything intry, so tracking effectively stopped there. for (T v : coll)— the loop variable never inherited the collection's taint, so user input arriving through a collection vanished.new FileInputStream(path)— constructors were not matched as sinks.- No path sensitivity — 46% of the benchmark's safe cases kill the vulnerable branch with a condition that is constant at compile time. Added constant propagation.
- Container mutation (
list.add,sb.append,map.put) did not propagate; maps are now tracked per literal key somap.put("a", tainted)does not taintmap.get("b"). java.xssrule was missing entirely (455 cases, 0 detected).
📦 Installer / 설치본
The previous installer silently shipped without 7 of the 11 languages. The packaging spec had a hand-written grammar list that was never updated Java, Kotlin, Go, Ruby, C/C++, Swift and C# worked in development and quietly did nothing once installed. The list is now derived from the loader source and pinned by a test.
This build was verified by launching the packaged executable and scanning a 12-language project through it all 12 detected.
🔧 Also in this release
- Apache-2.0 licence there was no licence file at all, which legally meant nobody could use it.
- macOS / Linux the Korean PDF font path was hard-coded to
C:/Windows/Fonts. Now discovered per platform, withCPGUARD_PDF_FONTto override. The engine, web UI and every report format are pure Python; only the installer and the native window are Windows-specific. - Long paths files past
MAX_PATHwere silently skipped and the integrity report still said "fully analysed". Fixed at the walk root. - Download filenames ong project names produced broken headers; names are now bounded by bytes and sent per RFC 5987.
- English deliverables and UI no longer leak Korean (verified by scanning the rendered output for Hangul).
- 253 tests passing.
Install: download CPGuard-Setup-0.1.3.exe below and run it. Per-user install, no admin rights; the WebView2 runtime is bundled and installed if missing.
CPGuard v0.1.2
A big usability release: interactive project dashboards, a much better audit workbench, in-app guides, and large-project robustness. Verified end-to-end on a real 26k-file / 2.3GB project.
프로젝트 대시보드·감사 작업대·인앱 가이드·대형 프로젝트 대응을 크게 개선한 릴리스. 실제 26k 파일 / 2.3GB 프로젝트로 검증했습니다.
✨ New / 추가
- Interactive project home / 프로젝트 홈 강화 — 위험도 도넛·상위 규칙/CWE 막대·필터·페이지네이션 취약점 탐색기(5만건+ 대응).
- Audit notes / 감사자 의견 — 이슈별 판단 근거 메모 저장(평문, HTML 렌더 안 함).
- In-app guides / 인앱 가이드 — 사용 가이드 + 프로바이더별 API 키 발급 팝업(Claude / Gemini / ChatGPT).
- Real progress bar / 진행 바 — 단계별 % + 무한 애니메이션으로 멈춘 듯 보이던 문제 해소.
🐞 Fixes / 수정
- 대형 스캔 원본 보관 — 큰 프로젝트에서도 코드 + Source→Sink 흐름 표시(이전엔 '원본 없음').
- 막대 그래프 채움 — 대시보드·탐색기 막대가 값대로 렌더됨(inline-span width 버그).
- Windows 긴 경로 해제 — 깊게 중첩된 대형 프로젝트 해제 크래시(MAX_PATH) 해결.
- LLM 신원 연동 Claude 키 —
anthropic-workspace-id전송 + 설정 칸·안내. - 텍스트 오버플로·레이아웃·네이티브 다운로드(캐시/PDF 뵰어) 수정.
Large projects / 대형 프로젝트
업로드 상한 상향(20만 파일 / 8GB, env 조정), 진단 시작 로딩 오버레이, 멀티프로세스 파싱. 26,049 파일 → 4,857건 약 5분.
Install / 설치
Windows 오프라인 설치본: CPGuard-Setup-0.1.2.exe (Python·관리자 권한 불필요).
GitHub Action
- uses: KimJeju/cpguard@v0.1.2
with: { path: '.', fail-on: 'high' }
- if: always()
uses: github/codeql-action/upload-sarif@v3
with: { sarif_file: '${{ steps.<id>.outputs.sarif }}' }Full changelog: v0.1.1...v0.1.2
CPGuard v0.1.1
Adds an app icon and fixes two native-desktop (WebView2) download bugs found in field testing.
하루 테스트에서 발견된 네이티브(WebView2) 다운로드 버그 2건 수정 및 앱 아이콘 추가.
✨ New / 추가
- App icon — shield (security) +
CPG+ taint-flow motif (source→sink). Applied to the exe, installer, window, and web favicon.
앱 아이콘 — 방패(보안) +CPG+ taint 흐름(source→sink). exe·설치본·창·웹 favicon 전부 적용.
🐞 Fixes / 수정
- Wrong project's export downloaded. SQLite reuses deleted
pks and WebView2 cached the export GET, so a reused id could serve a previous project's file. Download views are nowno-store.
잘못된 프로젝트 산출물이 다운로드되던 문제. SQLite pk 재사용 + WebView2 캐시 조합 → 다운로드 뷰에 캐시 금지. - PDF report hijacked the native window. WebView2's built-in PDF viewer took over the whole window. Download links now carry
downloadso they save instead of rendering inline.
PDF 리포트가 네이티브 창을 뷰어로 탈취하던 문제. 다운로드 링크에download속성 → 인라인 렌더 대신 저장.
Install / 설치
Windows 오프라인 설치본: CPGuard-Setup-0.1.1.exe (Python·관리자 권한 불필요).
Usage as a GitHub Action / 액션 사용
- uses: KimJeju/cpguard@v0.1.1
with: { path: '.', fail-on: 'high' }
- if: always()
uses: github/codeql-action/upload-sarif@v3
with: { sarif_file: '${{ steps.<id>.outputs.sarif }}' }CPGuard v0.1.0
CPG-based taint-analysis SAST that runs in GitHub Actions and uploads SARIF to GitHub Code Scanning.
GitHub Actions에서 실행되어 SARIF를 GitHub Code Scanning에 올리는 CPG 기반 taint 분석 SAST입니다.
Usage / 사용법
permissions:
contents: read
security-events: write
jobs:
sast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- id: cpguard
uses: KimJeju/cpguard@v0.1.0
with:
path: '.'
fail-on: 'high' # fail the build on high+ findings (none = report only) / high 이상 탐지 시 빌드 실패
- if: always()
uses: github/codeql-action/upload-sarif@v3
with: { sarif_file: '${{ steps.cpguard.outputs.sarif }}' }Features / 기능
- Languages / 언어: JavaScript · TypeScript · PHP · Python
- Interprocedural taint with function summaries + all-language pattern axis (secrets, PII, config hygiene) / 함수 요약 기반 프로시저간 taint + 전 언어 패턴 축
- SARIF 2.1.0 output → inline alerts on PRs via Code Scanning / PR 인라인 표시
- Severity gate / 등급 게이트:
--fail-on {critical|high|medium|low|info|none} - LLM triage (optional) / LLM 트리아지(선택): Claude · Gemini · GPT to cut false positives / 오탐 감소
Inputs / 입력
| Input | Default | Description |
|---|---|---|
path |
. |
Path to scan / 스캔 경로 |
sarif |
cpguard.sarif |
SARIF output file / SARIF 출력 파일 |
fail-on |
none |
Fail at this severity or above / 이 등급 이상이면 실패 |
args |
— | Extra cpguard scan args, e.g. --jobs 4 / 추가 인자 |