Skip to content

fix: bound response reads and sanitize remote-derived strings - #2081

Merged
cstamas merged 3 commits into
masterfrom
security/unbounded-reads-sanitization
Aug 31, 2026
Merged

fix: bound response reads and sanitize remote-derived strings#2081
cstamas merged 3 commits into
masterfrom
security/unbounded-reads-sanitization

Conversation

@gnodet

@gnodet gnodet commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes 4 findings from the maven-resolver security audit (scan-maven-resolver-20260811):

Finding Severity Description
f004 MEDIUM HTTP error-response bodies read unbounded into memory (decompression-amplified OOM)
f024 LOW Hostile remote checksum file causes unbounded allocation
f026 LOW Server Last-Modified future date permanently pins artifact against refresh
f028 LOW Remote-derived strings reach console logs without control-character sanitization

Root cause: Response bodies, checksum files, timestamps, and strings from the remote side are consumed with no size cap, no plausibility clamp, and no control-character sanitization.

Fix: Bound before allocating: cap error-body and checksum reads, clamp timestamps, sanitize control characters in log messages.

Test plan

  • Existing tests pass
  • Error body read capped at 64KB
  • Checksum file read capped
  • Last-Modified clamping tested
  • Control character sanitization tested

🤖 Generated with Claude Code

@gnodet
gnodet force-pushed the security/unbounded-reads-sanitization branch 2 times, most recently from f1f8c3a to 5b18ca0 Compare August 30, 2026 20:00
@gnodet
gnodet marked this pull request as ready for review August 31, 2026 05:20
@gnodet
gnodet requested a review from cstamas August 31, 2026 05:20
@gnodet gnodet added bug Something isn't working priority:major Major loss of function labels Aug 31, 2026
@gnodet gnodet added this to the 2.0.23 milestone Aug 31, 2026

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strong security-hardening PR that correctly addresses 4 audit findings (f004, f024, f026, f028) with good test coverage. One gap needs attention.

⚠️ UrlTransporter missing clampRemoteLastModified (f026 incomplete)

UrlTransporter.java line 253 applies raw remote lastModified via pathProcessor.setLastModified(task.getDataPath(), lastModified) without clamping. The Apache, JDK, and Jetty transports were all fixed in this PR to use HttpTransporterUtils.clampRemoteLastModified(), but the URL transport was missed.

The UrlTransporter module already imports HttpTransporterUtils (line 54), so the fix is a one-line change:

pathProcessor.setLastModified(task.getDataPath(), HttpTransporterUtils.clampRemoteLastModified(lastModified));

Since UrlTransporter handles HTTP connections (used as a bootstrapping fallback), a hostile server could serve a far-future Last-Modified header that permanently pins the artifact against refresh — the same f026 vulnerability fixed in the other transports.

@since tag corrections

  • LogSanitizer.java line 29: @since 2.0.22@since 2.0.23 (2.0.22 is already released)
  • HttpTransporterUtils.java line 345: clampRemoteLastModified — same @since correction

Positive observations

  • The bounded-read implementation in RFC9457Reporter.readBody() is well structured: 64KB cap is generous for legitimate payloads while preventing decompression-bomb OOM
  • The readFirstNonEmptyLine() correctly enforces the 8192-char bound on total data consumed, not just per-line
  • The LogSanitizer.sanitize() lazy-allocation pattern avoids overhead on the clean-string fast path
  • catch (RuntimeException ignore) in RFC9457Reporter is correct — the parse path involves Gson, URI.create(), getAsInt(), etc., which throw various RuntimeException subtypes on truncated/hostile input

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of gnodet

@cstamas

cstamas commented Aug 31, 2026

Copy link
Copy Markdown
Member

Right, URL transport was missed.

@gnodet

gnodet commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Fixed — UrlTransporter now applies HttpTransporterUtils.clampRemoteLastModified() to the Last-Modified value before calling setLastModified(), closing the f026 gap that @gnodet spotted. Also fixed @since 2.0.222.0.23 in LogSanitizer and HttpTransporterUtils.clampRemoteLastModified().

gnodet and others added 3 commits August 31, 2026 13:10
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address review feedback:
- UrlTransporter: apply clampRemoteLastModified() to prevent far-future
  Last-Modified from pinning artifacts against refresh (f026 gap)
- Fix @SInCE 2.0.22 → 2.0.23 in LogSanitizer and HttpTransporterUtils

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet
gnodet force-pushed the security/unbounded-reads-sanitization branch from 704fd87 to ffda463 Compare August 31, 2026 11:12
@cstamas
cstamas merged commit 7006fc3 into master Aug 31, 2026
24 checks passed
@cstamas
cstamas deleted the security/unbounded-reads-sanitization branch August 31, 2026 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working priority:major Major loss of function

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants