Skip to content

Security audit: LOW robustness fixes — skip, fallback, policy, redaction, containment, parse - #699

Open
gnodet wants to merge 9 commits into
security/audit-medium-fixesfrom
security/audit-low-robustness
Open

Security audit: LOW robustness fixes — skip, fallback, policy, redaction, containment, parse#699
gnodet wants to merge 9 commits into
security/audit-medium-fixesfrom
security/audit-low-robustness

Conversation

@gnodet

@gnodet gnodet commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Applies 6 LOW-severity robustness findings from the Glasswing static security audit (scan-maven-deploy-plugin-20260811). All confirmed TP with 5/5 adversarial-panel unanimity. Stacks on #698 (MEDIUM fixes).

Findings addressed

Finding Severity Title Patch
f007 LOW skip is a fail-open tri-state — unrecognized values silently publish bug_07
f008 LOW Snapshot deploy silently falls back to the release repository bug_08
f009 LOW No client-side release/snapshot policy guard; alt route gets API-default policies bug_09
f010 LOW Repository strings logged verbatim — URL-embedded userinfo leaks to CI logs bug_10
f011 LOW No containment on deploy-file file/files/sources/javadoc paths — composable exfil primitive bug_11
f012 LOW Alt-repo parse quirks: legacy pattern first, empty id accepted bug_12

Changes

  • f007: Shared parseSkipMode in both mojos — true/false/releases/snapshots matched case-insensitively; unrecognized values (typos like ture) now fail the build instead of silently deploying. Deploy-file releases/snapshots classification reordered after coordinate resolution
  • f008: WARN with fallback id+URL when a declared-but-unusable snapshotRepository routes a snapshot to the release repository
  • f009: warnIfPolicyMismatch WARNs pre-upload when the selected repository's explicit releases/snapshots policy rejects the artifact kind; enforcement stays server-side
  • f010: redactUrlUserInfo masks scheme://userinfo@ as scheme://***@ at all log sites; deploy lines log id (redacted-url)
  • f011: New opt-in maven.deploy.file.containedIn parameter: restricts all deploy-file path inputs to a containment directory (off by default)
  • f012: Fail-closed alt-repo parse: empty-trimmed id/url refused; ambiguous legacy id::layout::url whose URL part contains :: refused

Breaking changes

  • skip vocabulary is now fail-closed: unrecognized values fail the build
  • Ambiguous legacy id::layout::url alt-repo values now refused (was silently misdeploying)

Test plan

  • All 45 tests pass (36 existing + 9 new)
  • Build verified locally with Maven 4 rc-5

Audit source: scan-maven-deploy-plugin-20260811.zip

🤖 Generated with Claude Code

gnodet and others added 6 commits August 31, 2026 15:44
…kipMode(value, parame

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sitory declared' (doc

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ic limit the audit re

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…heme://userinfo@ as s

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ion (pipeline variabl

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… swap: reordering the

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet
gnodet force-pushed the security/audit-low-robustness branch from 01b6a86 to b8e8bcb Compare August 31, 2026 13:45
gnodet and others added 2 commits September 1, 2026 13:01
The f007 patch intentionally moved the releases/snapshots skip check
after version resolution so that a version supplied via the jar's
embedded POM is classified correctly. This means the jar IS inspected
before the skip decision, which is expected. Update the IT to assert
what matters (the deployment was skipped) instead of an implementation
detail (whether the jar was opened).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Same fix as deployfile-release-skip: the jar is inspected to resolve
the version before the snapshots skip check, which is the intended
behavior of the version-aware skip reordering (f007).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On macOS, /var is a symlink to /private/var.  When a non-existent
path (e.g. an artifact that hasn't been created yet) is checked against
an existing containment root, toRealPath() fails for the child but
succeeds for the root — giving /var/... vs /private/var/..., which
breaks the startsWith check.

Fix realOrNormalized() to walk up to the closest existing ancestor,
resolve its real path, then re-append the non-existent suffix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet
gnodet marked this pull request as ready for review September 1, 2026 21:16
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