
Zero-dependency, offline CLI scanner that finds fastjson inside JARs and Spring Boot fat-JARs, flags CVE-2026-16723 exposure, and detects shaded dependencies for CI gating.
단 하나의 명령으로, 당신의 Java 애플리케이션에 fastjson이 있는지, 어디에 숨어 있는지, CVE-2026-16723의 영향을 받는지 확인하세요.
의존성 제로 · 완전 오프라인 · 단 23KB의 jar · Java 8+ 지원
2026년 7월 21일, fastjson 공식 측이 CVE-2026-16723(CVSS 9.0, 원격 코드 실행)을 공개했습니다:
수많은 보안 공지(다수의 영문 보안 매체 포함)가 여전히 "1.x는 EOL이며, 패치는 영원히 나오지 않을 것이고, fastjson2로 마이그레이션하는 수밖에 없다"고 말하고 있습니다. 이 주장은 2026-07-29부터 더 이상 성립하지 않습니다. 직접 확인해 보세요:
| 증거 | 링크 |
|---|---|
Maven 중앙 저장소에 com.alibaba:fastjson:1.2.84가 있으며, jar는 2026-07-29에 업로드됨 | repo1 |
GitHub release 1.2.84, 2026-07-29T08:24:51Z에 게시됨 | release |
핵심 커밋 fix: strengthen autoType type name validation and whitelist verification | 2026-07-29T07:02:55Z |
1.2.83은 2022년 5월에 배포되었고, 그 후 1.x 브랜치는 4년간 커밋이 없었습니다 —— 1.2.84는 이번 취약점을 위해 특별히 예외적으로 배포된 것입니다.
그 release 제목에는 보안 수정이 표시되어 있지 않습니다: 1.2.83의 제목에는 "(보안 수정)"이 적혀 있었지만, 1.2.84에는
"1.2.84版本发布"만 적혀 있습니다. 하지만 본문에는 적혀 있습니다 —— 완전한 Security Fixes 섹션이 있어 네 가지 AutoType
강화 항목을 하나하나 나열하고 있으며, 배포 당일(2026-07-29)부터 그랬습니다(Wayback 아카이브 20260729094935에서 확인 가능).
패치 배포 후에도 보안 공지와 스캐너 대부분이 왜 여전히 따라가지 않는지는 제가 확인하지 못했으며, 여기서 추측하지 않겠습니다.
📌 2026-08-14 정정: 여기에는 원래 "전문에 보안 언급이 없어서 후속 조치가 이루어지지 않았다"고 적혀 있었습니다. 앞 문장은 release 본문과 Wayback 당일 아카이브 실측 결과 틀린 것(제목만 표시되지 않았을 뿐)으로 밝혀졌고, 뒷 문장도 따라서 근거를 잃었으므로 함께 삭제했습니다.
👉 1.x 사용자에 대한 실질적 영향: 1.2.84로 업그레이드하는 것이 가장 저렴한 대응입니다(같은 브랜치의 마이너 버전이라 보통 코드 수정이 필요 없음). fastjson2로의 대규모 버전 마이그레이션을 즉시 강행할 필요는 없습니다. 본 도구는 이에 따라 권장 사항을 제시합니다.
⚠️ 전제 조건은 JDK 8 이상입니다(2026-10-14 실측): 1.2.84의 274개 class는 모두 Java 8 바이트코드(major 52)이고, 1.2.83은 Java 5(major 49)입니다. JDK 7(Zulu 7u352)에서는
javac가 경고만 내고 종료 코드 0을 반환하지만, 런타임에는 곧바로UnsupportedClassVersionError: com/alibaba/fastjson/JSON : Unsupported major.minor version 52.0을 던집니다. 또한 1.2.84의JSON.VERSION상수는 여전히"1.2.83"이므로, 이것으로 버전을 판단하면 잘못 볼 수 있습니다. 본 도구는pom.properties를 읽으므로 영향을 받지 않습니다.
그리고 가장 골치 아픈 점은:
fastjson은 보통 전이 의존성입니다 —— 아무도 직접 설치하지 않으며, 다른 라이브러리에 딸려 들어옵니다. 많은 팀이 자신이 그것을 사용하고 있다는 사실조차 모릅니다.
mvn dependency:tree는 의존성을 나열할 수 있지만, 두 가지 상황에서는 무력합니다:
본 도구는 바로 이 두 가지 상황을 위해 만들어졌습니다.
Releases에서 fastjson-check.jar를 다운로드한 후:
# 扫一个 jar(Spring Boot fat-JAR 会自动逐层展开)
java -jar fastjson-check.jar ./myapp.jar
# 扫一整个目录(递归查找所有 jar/war)
java -jar fastjson-check.jar /opt/apps
# 输出 JSON,接入流水线
java -jar fastjson-check.jar /opt/apps --json
설치가 필요 없고, 계정도 필요 없으며, 네트워크에 연결하지 않고, 어떤 데이터도 업로드하지 않습니다.
동일한 아티팩트가 CLI이자 Maven 플러그인입니다. 이 방식은 jar를 먼저 다운로드할 필요가 없습니다:
# 在你的项目目录下直接跑,扫的是 Maven 解析后的依赖
mvn io.github.xiaoqimikko:fastjson-check:0.3.1:check
또는 빌드 라이프사이클(verify 단계)에 바인딩합니다:
<plugin>
<groupId>io.github.xiaoqimikko</groupId>
<artifactId>fastjson-check</artifactId>
<version>0.3.1</version>
<executions>
<execution>
<goals><goal>check</goal></goals>
</execution>
</executions>
</plugin>
pom.xml을 스캔하는 것보다 더 정확한 이유CLI로 pom.xml을 스캔할 때 읽는 것은 텍스트인데, 실제 프로젝트에서 fastjson의 버전은 종종 그 텍스트 안에 없습니다:
<version>${fastjson.version}</version><parent>에서 상속된 경우, 당신의 pom에는 이 줄이 없습니다플러그인이 얻는 것은 Maven이 해석을 완료한 이후의 의존성 집합이며, 각 의존성은 로컬 저장소에 있는 실제 jar 경로를 가지고 있습니다.
따라서 이 도구가 가장 잘하는 경로를 그대로 따릅니다: 실제 jar 안의 com/alibaba/fastjson(2)/JSON.class를 스캔하는 것이지,
pom에 무엇이 적혀 있는지를 믿는 것이 아닙니다.
⚠️ 하지만 인식 경계는 이로 인해 바뀌지 않습니다: 판정 키는 여전히 그 class 경로이므로 relocate / 패키지명 변경 후 재패키징된 의존성은 여전히 인식할 수 없습니다 (아래 「이것이 아닌 것」 참조). 플러그인이 해결하는 것은 「버전이 어디에 적혀 있는가」이지, 「패키지명이 바뀌었는가」가 아닙니다.
| 매개변수 | 기본값 | 설명 |
|---|---|---|
-Dfastjson-check.failOnFound | false | CRITICAL / HIGH 발견 시 빌드 실패 처리 |
-Dfastjson-check.path | 설정 안 함 | 의존성 트리를 스캔하지 않고 이 경로(디렉터리 / jar / war / fat-jar)를 스캔 |
-Dfastjson-check.skip | false | 실행 건너뛰기 |
🔴 기본적으로 빌드를 실패시키지 않으며, 이는 의도된 것입니다, CLI의 종료 코드 의미와 다릅니다:
명령줄은 당신이 직접 입력하는 것이므로 종료 코드 1이 바로 당신이 원하는 것이지만, 플러그인은 파이프라인에 걸려 있으므로
자체 점검 도구가 당신이 전혀 준비하지 않은 상황에서 빌드를 빨갛게 만들어서는 안 됩니다. CI 게이트로 사용하려면 명시적으로
-Dfastjson-check.failOnFound=true를 추가하세요.
💡 Windows에서 보고서가 깨져 나오면 콘솔을 GBK로 되돌리세요(
chcp 936)—— 플러그인 모드의 출력 인코딩은 Maven이 결정하며, CLI의--utf8/--gbk스위치는 여기서는 닿지 않습니다.
fastjson-check 0.1.0 —— fastjson 应急排查(离线,不外传任何数据)
扫描目标:myapp.jar
已展开归档:3 个
发现 2 处 fastjson:
[CRITICAL] fastjson 1.2.83
位置 :myapp.jar!/BOOT-INF/lib/fastjson-1.2.83.jar
版本来源:pom.properties
场景 :Spring Boot fat-JAR ← CVE-2026-16723 的主要在野利用场景
结论 :命中 CVE-2026-16723(CVSS 9.0 远程代码执行),默认配置即可利用
处置 :1.x 已停止维护,不会有修复版本。应急处置二选一:①(推荐)迁移至
fastjson2 2.0.63 或更高版本;② 无法立即迁移时,先启用 SafeMode
彻底关闭 AutoType 以缓解,但这不是长期方案。
[UNKNOWN] fastjson 版本未知
位置 :myapp.jar!/BOOT-INF/lib/some-sdk-3.1.0.jar
版本来源:未知
场景 :Spring Boot fat-JAR ← CVE-2026-16723 的主要在野利用场景
注意 :疑似被 shade 进宿主 jar(有 class 但无 Maven 元数据),mvn dependency:tree 查不到它
结论 :无法确定 fastjson 版本
汇总:CRITICAL 1 UNKNOWN 1
두 번째 항목에 주목하세요 — 그 some-sdk-3.1.0.jar는 fastjson을 자신의 내부에 패키징했으며, 의존성 트리에서는 전혀 보이지 않습니다.
| 버전 | 판정 | 설명 |
|---|---|---|
| fastjson 1.2.68 ~ 1.2.83 | 🔴 CRITICAL | CVE-2026-16723에 해당, 1.2.84로 업그레이드하면 수정됨 |
| fastjson ≥ 1.2.84 | 🟢 OK | 공식 수정 포함(2026-07-29 릴리스) |
| fastjson < 1.2.68 | 🟠 HIGH | 이번 CVE에는 해당하지 않지만, 과거 AutoType RCE 계열 취약점이 있음 |
| fastjson2 ≤ 2.0.62 | 🔴 CRITICAL | 다형성 역직렬화 RCE(seeAlso 경로), 기본 설정만으로도 트리거 가능 |
| fastjson2 ≥ 2.0.63 | 🟢 OK | 현재 권장 버전 |
⚠️ 특별 주의: 공식적으로 권장되는 마이그레이션 대상인 fastjson2 자체도 ≤2.0.62 버전에서는 RCE가 존재합니다. 「이미 fastjson2로 마이그레이션했다」는 것이 안전을 의미하지 않으며, 반드시 버전 번호도 함께 확인해야 합니다.
--json 输出 JSON,便于接入流水线(恒为 UTF-8)
--utf8 强制以 UTF-8 输出(控制台中文乱码时用)
--gbk 强制以 GBK 输出(控制台中文乱码时用)
--no-color 关闭彩色输出
-h, --help 显示帮助
-v, --version 显示版本
종료 코드: 0 = 처리할 항목이 발견되지 않음(그리고 모든 파일이 실제로 읽혔음); 1 = CRITICAL/HIGH 발견; 2 = 사용법 오류; 4 = 읽을 수 없는 파일이 있음(문서 끝의 "종료 코드" 섹션 참조).
CI 게이트에 바로 사용 가능:
java -jar fastjson-check.jar ./build/libs --json || echo "发现高危依赖,阻断发布"
경계를 솔직하게 설명하여 안전하다고 오해하지 않도록 합니다:
com/alibaba/fastjson(2)/JSON.class 경로로 식별합니다. 어떤 라이브러리가 shade 시 패키지명을 com.foo.shaded.fastjson으로 변경했다면 찾아낼 수 없습니다mvn clean package
# 产物:target/fastjson-check.jar
컴파일 타깃은 Java 8이므로, 빌드된 jar를 아직 JRE 8을 실행 중인 구형 머신에 그대로 넣어 실행할 수 있습니다. 런타임 의존성 제로 —— 진단 도구가 대상 환경에 무언가를 더 넣어서는 안 됩니다(특히 JSON 라이브러리를 넣어서는 안 되는데, 우리가 점검하는 것이 바로 그것이기 때문입니다).
오탐 또는 미탐을 발견하셨다면 Issue를 열어 주세요. 보안 도구에서 가장 두려운 것은 사람들이 안전하다고 착각하게 만드는 것이며, 어떤 오판 하나라도 제기할 가치가 있습니다.
issue를 올릴 때 다음 정보를 첨부해 주시면 원인 파악이 훨씬 빨라집니다: