fix(elysia)!: withhold the raw upstream error message from the SSE error frame#476
Open
rejifald wants to merge 1 commit into
Open
fix(elysia)!: withhold the raw upstream error message from the SSE error frame#476rejifald wants to merge 1 commit into
rejifald wants to merge 1 commit into
Conversation
…ror frame `@stitchapi/elysia`'s `streamStitchSse` wrote the raw `event.message` (and a caught throw's message) straight into the terminal `event: error` SSE frame, disclosing it to the client. A transport failure leaks internal topology (`getaddrinfo ENOTFOUND payments.internal.corp`) and an upstream `401` leaks its status — the exact class the other five hosts (express / fastify / hono / nest / next) already guard against. elysia was the lone outlier. Bring elysia in line: the error frame now carries a generic `data: error` token by default; `onError` still receives the real failure server-side for logging, and a new `errorData` option opts in to shaping the client-facing payload (`errorData: (e) => e.message`) when the upstream messages are known safe. A caught throw is normalised to an error event so `errorData` sees a consistent shape. Flips the two SSE tests that asserted the leak, and adds internal-hostname regression + `errorData` opt-in coverage; documents the option in the README and integration page. BREAKING: the SSE `error` frame's `data` is now `error` by default instead of the raw message — opt back in with `errorData`. Pre-GA. Carved out of the #470 contract-freeze sweep so this security fix lands and is reviewed on its own (in #470 it is bundled with the `streamStitchSse` option-shape convergence). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Security: SSE error frame leaked the raw upstream message
@stitchapi/elysia'sstreamStitchSsewrote the rawevent.message(and a caught throw'smessage) straight into the terminal
event: errorSSE frame, disclosing it to theclient:
A transport failure leaks an internal hostname; an upstream
401leaks its status. This isthe exact disclosure class the other five hosts already guard against — on
main,express/fastify/hono/nest/nextall write a genericdata: errortoken bydefault (
DEFAULT_ERROR_DATA/SAFE_MESSAGE). elysia was the lone outlier still echoingthe raw message, and its tests even asserted the leak.
Fix
Bring elysia in line with its siblings:
data: errortoken by default.onErrorstill receives the real failure server-side, for logging.errorDataoption opts in to shaping the client-facing payload(
errorData: (e) => e.message) when upstream messages are known safe.errorDatasees a consistent shape.The SSE
errorframe'sdatais nowerrorby default instead of the raw message. Optback in with
errorData. Pre-GA, no deprecation.Tests
Flips the two SSE tests that asserted the leak, and adds an internal-hostname
regression +
errorDataopt-in coverage (error path and throw path). Verified the fourassertions fail on the pre-fix
srcand pass after. README + integration doc document theoption.
Context
Carved out of the #470 contract-freeze sweep so this security fix lands and is reviewed on
its own. In #470 it's bundled with the
streamStitchSseoption-shape convergence(
data(chunk, index),eventas a function, anidoption, theStitchEventSourcehoist)— all omitted here; this keeps elysia's existing signatures and changes only the error
disclosure.
Verification
pnpm --filter @stitchapi/elysia test(24 pass) +check:typesclean.🤖 Generated with Claude Code