Skip to content

Harden token/error handling, enforce HTTPS-or-loopback, and pin supply-chain versions - #2

Merged
lbb00 merged 1 commit into
mainfrom
security/token-and-redirect-hardening
Aug 1, 2026
Merged

lbb00 merged 1 commit into
mainfrom
security/token-and-redirect-hardening

Conversation

@lbb00

@lbb00 lbb00 commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Second round of codex-audited security fixes on top of the redirect/token-validation work from #1 (merged): Java token/header validation tightened to a printable-ASCII whitelist with a QdmpTransport-level enforcement to close a direct-construction bypass; expiresAt is now validated as non-negative and not-already-expired on every auth exchange path (cached and one-shot) in Go/Java, with refreshToken/openId non-empty checks across all three languages; Java's code2Session/refreshToken now return hand-written Code2SessionResult/RefreshTokenResult instead of generated DTOs whose auto-generated toString() leaked tokens; all three SDKs require HTTPS by default using a real IP-literal loopback check (the previous string-prefix check was bypassable via a hostname like "127.attacker.com"); server-controlled message/code/requestId fields are sanitized before reaching any error string, and response bodies are capped at 10MB; accidental debug-logging of tokens is now blocked across fmt/GoStringer/slog (Go), util.inspect (Node), and toString (Java); a Node ordering bug that could leave a failed TokenStore write locally cached as if persisted is fixed; and supply-chain inputs are pinned/verified (openapi-generator-cli jar SHA-256, Go's oapi-codegen pinned to v2.8.0, Gradle wrapper checksum, staticcheck version).

Test plan

  • Node: 91/91 tests, typecheck, lint clean
  • Java: full suite + checkstyle/spotless clean
  • Go: 81/81 tests (-race), gofmt/vet clean

…y-chain versions across Node/Java/Go SDKs

Second round of codex-audited security fixes on top of the redirect/token-validation work already in this PR:

- Tighten Java token/header validation to a printable-ASCII whitelist and enforce it inside QdmpTransport too, closing a direct-construction bypass of QdmpContext
- Reject non-numeric, negative, and already-expired expiresAt values on all three auth exchange paths (cached app token and one-shot code2Session/refreshToken) in Go/Java, and validate refreshToken/openId are non-empty across all three languages
- Replace Java's code2Session/refreshToken generated-DTO return types (which leaked tokens via auto-generated toString()) with hand-written Code2SessionResult/RefreshTokenResult, matching Go's existing types
- Require HTTPS by default in all three SDKs, using a real IP-literal loopback check (the previous string-prefix check could be bypassed by a hostname like "127.attacker.com")
- Sanitize server-controlled message/code/requestId fields (control-character stripping + length caps) before they reach any error string, and cap response body reads at 10MB
- Prevent accidental debug-logging of tokens: Go's Code2SessionResult/RefreshTokenResult now implement fmt.Stringer/GoStringer/slog.LogValuer, Node's results carry a redacted util.inspect renderer, Java's toString() also escapes control characters in openId
- Fix a Node ordering bug where a failed TokenStore write could still leave a token locally cached as if persisted
- Pin/verify supply-chain inputs: SHA-256-verify the downloaded openapi-generator-cli jar, pin Go's oapi-codegen to v2.8.0 via `go run`, add Gradle wrapper's distributionSha256Sum, pin staticcheck's version

## Test plan
- Node: 91/91 tests, typecheck, lint clean
- Java: full suite + checkstyle/spotless clean
- Go: 81/81 tests (-race), gofmt/vet clean
@lbb00
lbb00 merged commit abcd201 into main Aug 1, 2026
4 checks passed
@lbb00
lbb00 deleted the security/token-and-redirect-hardening branch August 1, 2026 11:29
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