Skip to content

UID2-7505: Detect unencrypted JSON request bodies in v2 envelope parsing#2660

Open
swibi-ttd wants to merge 7 commits into
mainfrom
swi-UID2-7505-detect-unencrypted-json
Open

UID2-7505: Detect unencrypted JSON request bodies in v2 envelope parsing#2660
swibi-ttd wants to merge 7 commits into
mainfrom
swi-UID2-7505-detect-unencrypted-json

Conversation

@swibi-ttd

@swibi-ttd swibi-ttd commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Improves the v2 envelope parse error messages. A common integration mistake — sending base64-encoded plain JSON (e.g. via curl) instead of an encrypted request envelope — currently returns the opaque Invalid body: Version mismatch., which gives no hint that the payload must be encrypted.

Changes

  1. Detect unencrypted JSON bodies. When envelope parsing fails and the body parses as JSON (an encrypted envelope never does), return a specific error: "Invalid body: The request body is unencrypted JSON. It must be an encrypted request envelope. See <docs> for encryption and decryption code examples." Runs only on the error path.
  2. Rename the Version mismatch error, which reads as an operator/API version problem: "Invalid body: Invalid request envelope format version: received X, must be 1." (VERSION constant → ENVELOPE_FORMAT_VERSION.)
  3. Append a link-only docs pointer to the other envelope parse errors (not valid base64 / too short / wrong key): "See <docs> for details on the request envelope format." Unlike a cause-asserting hint, this cannot mislead the wrong-secret or proxy-corruption cases.
  4. Fix error precedence in the octet-stream → base64 fallback. When both interpretations of an octet-stream body fail, the binary error was always returned — hiding the base64 path's more accurate diagnosis whenever the body was actually base64 text. A binary envelope can never be valid base64 (its first byte is the 0x01 envelope version byte, not a base64 character), so if the fallback got past base64 decoding, the body was base64 text and the fallback's error is returned instead.

Docs links are scope-aware (unifiedid.com / euid.eu); IdentityScope is plumbed from V2PayloadHandler. All existing leading phrases are preserved, and nothing in uid2-operator, uid2-e2e, uid2-validator, or the client SDKs matches the old Version mismatch string.

Testing

New tests for base64-encoded, raw, and short unencrypted JSON bodies, genuine version mismatch, the EUID docs link, and both directions of the octet-stream fallback precedence. mvn clean test: 757 tests, 0 failures.

Jira

UID2-7505

🤖 Generated with Claude Code

swibi-ttd and others added 7 commits July 23, 2026 13:07
When a v2 request body fails envelope parsing and the (decoded) bytes parse
as JSON, return a specific error explaining the body must be an encrypted
request envelope, with a link to the encryption/decryption docs (unifiedid.com
or euid.eu depending on identity scope). An encrypted envelope never parses
as JSON, so the check only fires for genuinely unencrypted payloads, and the
existing error messages remain byte-identical for all other causes
(corrupted envelope, proxy-transformed body, wrong client secret).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…stant

'Version mismatch' reads as an operator/API version problem. Rename the
constant to ENVELOPE_FORMAT_VERSION and report the error using the docs'
own term ('version of the envelope format'), including the received byte:
'Invalid body: Invalid request envelope format version: received X, must be 1.'

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A neutral pointer to the envelope-format docs, appended after each error's
cause statement; the leading phrase of every message is preserved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
When both the binary and base64 interpretations of an octet-stream body fail,
the binary error was always returned - hiding the base64 path's more accurate
diagnosis (e.g. unencrypted JSON) whenever the body was actually base64 text.
A binary envelope can never be valid base64 (its first byte is the 0x01
envelope version byte, not a base64 character), so if the fallback got past
base64 decoding, the body was base64 text and the fallback's error applies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@swibi-ttd
swibi-ttd force-pushed the swi-UID2-7505-detect-unencrypted-json branch from 0e75e91 to 94170b3 Compare July 23, 2026 03:07
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