Skip to content

chore: harden embedded-POM trust boundary in install:install-file - #446

Open
gnodet wants to merge 2 commits into
masterfrom
quick-fix/harden-embedded-pom-trust
Open

chore: harden embedded-POM trust boundary in install:install-file#446
gnodet wants to merge 2 commits into
masterfrom
quick-fix/harden-embedded-pom-trust

Conversation

@gnodet

@gnodet gnodet commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Hardens the embedded-POM trust boundary in install:install-file, addressing four findings from a static security audit of the Maven 4 line (commit 0bfcb64).

Findings addressed

ID Severity Title
f001 MEDIUM Embedded JAR POM silently chooses install coordinates, poisoning shared local repo
f002 MEDIUM Foreign embedded POM installed verbatim even with explicit CLI coordinates
f003 LOW Defense-in-depth DOCTYPE rejection for attacker-authored embedded POM
f004 LOW Coordinate validators accept dot-only and empty segments, escaping coordinate directory

Changes

  • Coordinate adoption visibility (f001): Fail when multiple META-INF/maven/*/pom.xml entries match; validate entry-path <g>/<a> against the embedded POM's effective GAV; log adopted coordinates at INFO (was DEBUG); WARN before overwriting an existing local-repo artifact with different content; validate packaging with the same rules as other coordinates.
  • CLI-coordinate priority (f002): When the operator supplies complete g/a/v/packaging, skip readingPomFromJarFile() entirely and generate a minimal POM. When partial coordinates are supplied, cross-check each against the embedded POM and fail on mismatch.
  • DOCTYPE screening (f003): Pre-scan embedded POM bytes for <!DOCTYPE before handing them to ModelXmlFactory.read(). Encoding-aware: BOM/first-bytes/XML-declaration sniffer covering UTF-8/16/32 and EBCDIC, with fail-closed handling for unsupported encodings and unterminated declarations.
  • Coordinate validation (f004): isValidId() rejects empty and dot-only values; new isValidGroupId() rejects leading/trailing/consecutive dots; isValidVersion() rejects empty and dot-only values. Defense in depth: composed layout path must reside under the local repository root.

Category

Security hardening — no live exploit demonstrated; static-analysis findings from a 5-lane audit with blind triage panel.

Test plan

  • All new unit tests pass (coordinate adoption, entry-path mismatch, multiple POM entries, invalid packaging, DOCTYPE rejection in UTF-8/UTF-16LE/UTF-16BE/EBCDIC/padded-declaration, leading-dot groupId, consecutive-dot groupId, dot-dot artifactId, dot-dot version, full-coordinates hostile POM ignored, partial-coordinates mismatch rejected, partial-coordinates match accepted)
  • Existing tests pass unchanged
  • mvn clean install -B succeeds

🤖 Generated with Claude Code

gnodet and others added 2 commits August 31, 2026 13:47
Security audit findings (static analysis, no live exploit demonstrated):

- f001 (MEDIUM): Make coordinate adoption from embedded POM visible and
  cross-checked — fail on multiple POM entries, validate entry-path vs
  model GAV, log at INFO, warn before overwriting, validate packaging
- f002 (MEDIUM): Skip embedded POM when full CLI coordinates supplied;
  cross-check operator-supplied coordinates against embedded POM
- f003 (LOW): Defense-in-depth DOCTYPE rejection for embedded POM XML
  with encoding-aware screening (UTF-8/16/32, EBCDIC)
- f004 (LOW): Reject empty/dot-only coordinates and leading-dot groupIds;
  containment-check install path against local repository root

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The embedded-POM trust hardening changed log.debug() to log.info()
for provenance visibility. Update the integration test assertions
to match the new log level and message format.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet
gnodet marked this pull request as ready for review September 1, 2026 10:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant