9.1 KiB
9.1 KiB
title, source_type, status, related_branches, related_projects, tags, created, status_label, target_audience, inspiration_url, archive_url
| title | source_type | status | related_branches | related_projects | tags | created | status_label | target_audience | inspiration_url | archive_url | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| blog-topic / archunit-jackson-default-typing-cve-2019-14379-block-2026-05-29 | blog-topic | raw |
|
|
|
2026-05-29 | ready-for-canonical | backend-engineer |
blog-topic: archunit-jackson-default-typing-cve-2019-14379-block-2026-05-29
Layer:
raw/blog-topics/— 채용공고가 아닌 작업·학습·트러블슈팅에서 나온 블로그 글감 원석. canonical 정제 전 raw 후보이며,wiki/blog/직접 생성 근거가 아니다.
Parent / 부모
- raw/branch-notes/feature-boundary-validation-mapping-contract — B5 결정 + Claims to Verify 의 두 행
actually-implemented승급. 본 글감은 그 enforcement 패스의 보안 측면 단독 추출.
트리거 / Trigger
- 트리거 유형:
branch-work - 트리거 날짜: 2026-05-29
- 트리거 연결 노트: raw/branch-notes/feature-boundary-validation-mapping-contract — 1차 enforcement 패스에서
no_jackson_laissez_faire_subtype_validator+no_jackson_enable_default_typing_call두 ArchUnit 규칙 +DefaultTypingFixtureviolations-as-data 테스트로 CVE-2019-14379 의 코드 진입점을 정적으로 차단한 작업.
글감 / Topic seed
- 한 문장 요지: Jackson polymorphic deserialization 의 RCE 게이트 (
ObjectMapper.enableDefaultTyping()/activateDefaultTyping(LaissezFaireSubTypeValidator)) 는 런타임 dependency check 가 아니라 컴파일/테스트 단계의 fitness function 으로 막아야 안전하다 — 한번 머지된 뒤에는 production 트래픽으로 RCE 가 터지는 게 검출 시점이므로 너무 늦다. - 떠오른 계기: feature-boundary-validation-mapping-contract B5 결정의 enforcement 단계. CVE 자체의 발견 (2019) 과 Jackson 2.10 의
@Deprecated조치 (2019-09) 가 있었음에도, 우리 코드가 호출하지 않는다 는 사실은 매 PR 마다 사람이 보장해야 하는 규약이었다. 이걸 ArchUnit fitness function 으로 commit 으로 박은 사례. - 예상 제목 후보:
- CVE-2019-14379 의 호출 경로를 ArchUnit 으로 정적 봉쇄하기
- "Jackson 을 안전하게 쓴다" 를 컨벤션이 아닌 fitness function 으로 박는 방법
enableDefaultTyping()한 줄이 RCE 가 되는 이유와 정적 차단
핵심 주장 후보 / Claim candidates
- 사실 후보:
- CVE-2019-14379 의 RCE 경로는
ObjectMapper.enableDefaultTyping()활성화 +ehcache같은 gadget class 가 classpath 에 있는 조건 — 근거: NVD CVE-2019-14379 (CVSS 9.8), Jackson 보안 가이드enableDefaultTyping의@Deprecated since 2.10표기. - Jackson 2.10 의 공식 대체 API 는
activateDefaultTyping(PolymorphicTypeValidator)이며, allowlist 구현체BasicPolymorphicTypeValidator또는@JsonTypeInfo(use = NAME) + @JsonSubTypes명시가 정식 — 근거:raw/official-docs/schema-jackson-polymorphic-deserialization.md#JACK-POLY-C1..C5. LaissezFaireSubTypeValidator는 모든 subtype 허용 의 명시적 anti-allowlist — 클래스 이름 그 자체가 "보안 검증 없음" 의 표지 — 근거:JACK-POLY-C2.- ca-tmpl 의 적용:
src/app-bootstrap/src/test/java/dev/caskeleton/bootstrap/architecture/CleanArchitectureTest.java에 두 규칙 추가 —no_jackson_laissez_faire_subtype_validator(클래스 참조 차단),no_jackson_enable_default_typing_call(메서드 호출 차단). 위반 fixture 는violations/boundary/DefaultTypingFixture.java. - 규칙 두 개를 분리한 이유:
LaissezFaireSubTypeValidator없이enableDefaultTyping()만 호출해도 (ObjectMapper.DefaultTyping.NON_FINAL등 deprecated overload) 위험. 호출 차단과 import 차단이 독립적인 진입점 이므로 둘 다 닫아야 한다.
- CVE-2019-14379 의 RCE 경로는
- 경험 후보:
- ArchUnit DSL 의
callMethodWhere(target(name(...)))패턴은 호출자 의도와 무관하게 메서드 이름 으로 catch.enableDefaultTyping이라는 메서드 이름이 ObjectMapper 외부에 존재할 가능성이 거의 0 이므로 owner 필터를 생략해도 false positive 없음 — 단순 규칙이 충분. - violations-as-data fixture 는
DefaultTypingFixture.unsafe()한 메서드로 두 규칙을 동시에 catch (호출 + 참조). 한 fixture 가 서로 다른 규칙 두 개를 동시에 검증 하는 케이스 — 규칙별 1:1 fixture 가 아니어도 됨. app-bootstrap의 test classpath 에 Jackson 이 없어서 컴파일 실패 →testImplementation 'org.springframework.boot:spring-boot-starter-json'추가. fitness function 자체에 의존성을 끌어들이는 cost 가 있음을 의식해야 한다.
- ArchUnit DSL 의
- 의견 / 해석 후보:
- 라이브러리 버전 차단 (jackson-databind ≥ 2.10) 은 supply-chain branch 의 책임이지만, 코드 사용 차단 (deprecated API 호출 금지) 은 boundary contract 의 책임. 두 가지를 같은 PR 에서 묶으면 책임 경계가 흐려진다.
- "CVE 가 알려진 후에는 사람이 review 로 막으면 된다" 는 흔한 반론은 시간 경과에 따른 attention decay 를 무시한다. 5년 뒤 합류한 신입이 PR review 할 때
enableDefaultTyping이 안전한지 즉시 판단하기 어렵다 — fitness function 은 지식 보존 비용 의 외부화. - Jackson 2.15 의 sealed type 자동 인식 같은 조용한 행동 변화 가 들어와도, 본 규칙은 호출 자체를 차단하므로 회귀 없음 — Jackson 의 mitigation 진화를 기다리는 대신 진입점 자체를 봉쇄 하는 전략의 정당화.
Outline seed
- CVE-2019-14379 의 한 줄 —
enableDefaultTyping()+ ehcache gadget 으로 RCE (CVSS 9.8). - Jackson 의 공식 대응 — 2.10
@Deprecated+PolymorphicTypeValidator+BasicPolymorphicTypeValidatorallowlist. - 하지만 우리 코드가 호출하지 않는다 는 사실의 유지비용 — review fatigue, 시간 경과, 신입 합류.
- fitness function 으로의 외부화 — ArchUnit 규칙 두 개 (
callMethodWhere+dependOnClassesThat) 의 의도와 분리 이유. - violations-as-data 로 규칙이 실제로 catch 하는지 박기 —
DefaultTypingFixture한 메서드가 두 규칙을 동시에 검증. - fitness function 의 비용 —
spring-boot-starter-json을 test classpath 에 끌어들임. - 보안 책임의 경계 — 코드 사용 차단 (boundary contract) vs 버전 차단 (supply-chain) 의 분리.
- 정리 — CVE 차단은 지식 보존 비용 의 코드화. fitness function 이 review 의 검토 부담을 commit 으로 이전한다.
Canonical 전환 후보 / Canonical extraction candidates
wiki/projects/ca-tmpl/archunit-jackson-cve-block.md후보:- 실제 두 규칙 +
DefaultTypingFixture의 코드 발췌. testImplementation 'spring-boot-starter-json'추가의 비용.- violations-as-data 1 fixture × 2 negative test 패턴.
- 실제 두 규칙 +
wiki/concepts/fitness-function-for-known-cve.md후보:- "우리 코드가 호출하지 않는다" 를 review 로 유지하는 비용 분석.
- 코드 사용 차단 vs 버전 차단의 책임 경계.
- 라이브러리 mitigation 진화와 진입점 차단 전략의 trade-off.
- 필요한 추가 검증:
BasicPolymorphicTypeValidator사용을 권장 하는 메시지를 ArchUnit 위반 메시지에 포함할 가치가 있는지 — false-positive 시 개발자가 즉시 대안을 알 수 있게.- sealed
Command타입 도입 시 본 규칙이@JsonTypeInfo명시 패턴과 충돌하지 않는지 (충돌 없음 가설 — 검증은 future use case 에서).
Sources / 근거 후보
- raw/branch-notes/feature-boundary-validation-mapping-contract — B5 결정 + 1차 enforcement 패스 결과.
- raw/official-docs/schema-jackson-polymorphic-deserialization —
JACK-POLY-C1..C5(CVE, deprecated API, allowlist 표준). - raw/blog-topics/archunit-violations-as-data-pattern-2026-05-28 — violations-as-data 메타 패턴. 본 글감은 그 패턴의 보안 특화 사례.
- raw/branch-notes/feature-architecture-enforcement-rules — 같은 fitness-function 자체 검증 라인.
미해결 / Unknown
- 아직 확인해야 할 사실: violation message에
BasicPolymorphicTypeValidator대안을 포함할지 여부. - 과장하면 안 되는 부분: ArchUnit rule은 ca-tmpl 코드의 특정 호출/참조를 차단하는 것이며, Jackson RCE 일반 위험을 모두 제거한다고 쓰지 않는다.
Related / 관련
- 관련 branch: raw/branch-notes/feature-boundary-validation-mapping-contract
- 관련 raw topic: raw/blog-topics/archunit-violations-as-data-pattern-2026-05-28
Decision / 처리 결정
- 액션:
promote-to-canonical - 이유:
wiki/projects/ca-tmpl/boundary-validation-mapping.md에 Jackson default typing CVE static block 글감으로 반영했다. - 다음 단계: source canonical이
verified상태이므로 이후blogify대상으로 삼을 수 있다. 단 ArchUnit rule이 탐지 가능한 호출/참조 범위로 제한된다는 점을 유지한다.