Reject GET requests with a Content-Type other than application/json#8191
Reject GET requests with a Content-Type other than application/json#8191
Conversation
GET requests carry their GraphQL operation in query parameters, not a body, so there is no legitimate reason to send any Content-Type other than application/json (which Apollo Client Web sends by default). Reject any other value — including valid MIME types like text/plain and application/graphql, as well as malformed values — with HTTP 415. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
✅ Docs preview readyThe preview is ready to be viewed. View the preview File Changes 0 new, 3 changed, 0 removedBuild ID: fee45bd747a958a117a72c9e URL: https://www.apollographql.com/docs/deploy-preview/fee45bd747a958a117a72c9e
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughA security-hardening update in v5.5.0 enforces Content-Type validation: Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
.changeset/chatty-worlds-vanish.md (1)
12-12: Consider making this sentence evergreen.Line 12’s “as of March 2026” timestamp may become stale quickly in long-lived release notes.
📝 Suggested wording
- Apollo is aware of one browser which as of March 2026 has a bug which allows an attacker to circumvent Apollo Server's CSRF prevention feature to carry out read-only XS-Search-style CSRF attacks. + Apollo is aware of a browser bug that allows an attacker to circumvent Apollo Server's CSRF prevention feature to carry out read-only XS-Search-style CSRF attacks.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.changeset/chatty-worlds-vanish.md at line 12, The phrase "as of March 2026" makes the release note line time-sensitive; update the sentence in the .changeset entry that currently reads "as of March 2026" to an evergreen form (e.g., remove the date or replace with "recently" or "currently being patched by the vendor") so it does not become stale—edit the sentence mentioning the browser bug and Apollo Server v5.5.0 to omit the explicit timestamp while preserving the meaning about the vendor patch and mitigation.packages/integration-testsuite/src/httpServerTests.ts (1)
630-634: Rename this test for accuracy.Line 630 says “non-preflighted”, but the case uses
application/graphql, which is preflighted (as your own comment in Lines 631-633 notes).🧹 Suggested rename
-it('throws an error if GET request has a non-preflighted non-application/json content-type', async () => { +it('throws an error if GET request has a preflighted non-application/json content-type', async () => {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/integration-testsuite/src/httpServerTests.ts` around lines 630 - 634, The test description is inaccurate: update the it(...) string that currently reads "throws an error if GET request has a non-preflighted non-application/json content-type" to reflect that the case uses a preflighted MIME type (application/graphql). Locate the it(...) block (the test wrapping createApp()) and change the description to something like "throws an error if GET request has a preflighted non-application/json content-type" or more specific "throws an error if GET request has a preflighted application/graphql content-type".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/source/security/cors.mdx`:
- Line 203: Fix the grammar in the summary sentence that currently reads "the
incoming request include" by changing "include" to "includes"; locate the
sentence in the paragraph discussing Content-Type (the sentence starting "This
means that all `POST` requests...") and update it so it reads "the incoming
request includes a `Content-Type` header specifying `application/json`" to
correct subject-verb agreement.
---
Nitpick comments:
In @.changeset/chatty-worlds-vanish.md:
- Line 12: The phrase "as of March 2026" makes the release note line
time-sensitive; update the sentence in the .changeset entry that currently reads
"as of March 2026" to an evergreen form (e.g., remove the date or replace with
"recently" or "currently being patched by the vendor") so it does not become
stale—edit the sentence mentioning the browser bug and Apollo Server v5.5.0 to
omit the explicit timestamp while preserving the meaning about the vendor patch
and mitigation.
In `@packages/integration-testsuite/src/httpServerTests.ts`:
- Around line 630-634: The test description is inaccurate: update the it(...)
string that currently reads "throws an error if GET request has a
non-preflighted non-application/json content-type" to reflect that the case uses
a preflighted MIME type (application/graphql). Locate the it(...) block (the
test wrapping createApp()) and change the description to something like "throws
an error if GET request has a preflighted non-application/json content-type" or
more specific "throws an error if GET request has a preflighted
application/graphql content-type".
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e713a20b-f102-4044-b593-9c54b849cfbd
📒 Files selected for processing (7)
.changeset/chatty-worlds-vanish.mddocs/source/integrations/building-integrations.mddocs/source/security/cors.mdxdocs/source/workflow/requests.mdpackages/integration-testsuite/src/apolloServerTests.tspackages/integration-testsuite/src/httpServerTests.tspackages/server/src/runHttpQuery.ts
📜 Review details
🧰 Additional context used
🪛 GitHub Check: AI Style Review
docs/source/security/cors.mdx
[notice] 203-203: docs/source/security/cors.mdx#L203
Framing: Use the imperative 'ensure' to make the summary more direct and reader-centric.
Language: Corrected 'include' to 'includes' to ensure proper grammar.
Products and Features: Remove 'the' before 'Apollo Server' as it is not part of the proper product name.
Structural Elements: Keep list items short for scannability. Move the detailed explanation and parenthetical notes to the following paragraph.
Text Formatting: Use code font for the GET keyword and use plain text for version numbers (v5.5.0).
Verb Tense and Voice: Use present tense instead of future tense and active voice instead of passive voice where possible.
Voice: The original text is unopinionated and overly verbose. Prescribe the 'happy path' of using application/json and Apollo Client directly.
Word and Symbol Usage: Avoid using 'do' for emphasis in 'do include'; it's more direct to say 'include'.
- The incoming request includes a `Content-Type` header that specifies a type other than `text/plain`, `application/x-www-form-urlencoded`, or `multipart/form-data`. Notably, a `Content-Type` of `application/json` (including any suffix like `application/json; charset=utf-8`) is sufficient. This means that all `POST` requests (which must use `Content-Type: application/json`) will be executed. Additionally, all versions of [Apollo Client Web](/react/api/link/apollo-link-http) that support `GET` requests include `Content-Type: application/json` headers, so any request from Apollo Client Web (`POST` or `GET`) will be executed. (As of v5.5.0, Apollo Server rejects GET requests which contain a non-empty `Content-Type` other than `application/json`, so in practice this bullet point could be summarized as "ensure the incoming request includes a `Content-Type` header specifying `application/json`".)
🪛 markdownlint-cli2 (0.21.0)
docs/source/integrations/building-integrations.md
[warning] 124-124: Emphasis style
Expected: underscore; Actual: asterisk
(MD049, emphasis-style)
[warning] 124-124: Emphasis style
Expected: underscore; Actual: asterisk
(MD049, emphasis-style)
🔇 Additional comments (5)
packages/server/src/runHttpQuery.ts (2)
24-24: New MIME parsing import is appropriate.Line 24 cleanly introduces the parser dependency needed for stricter GET header validation.
199-211: GET content-type validation is correctly enforced early.The new guard in Lines 199-211 rejects invalid/malformed GET
content-typewith 415 before request construction, which matches the security objective.docs/source/workflow/requests.md (1)
85-87: Docs update is clear and aligned with runtime behavior.Lines 85-87 accurately describe allowed GET
content-typevalues and the 415 rejection path.docs/source/integrations/building-integrations.md (1)
123-124: Security guidance here is strong and actionable.Lines 123-124 clearly communicate the CSRF risk when integrations accept unsafe POST content-types.
packages/integration-testsuite/src/apolloServerTests.ts (1)
3180-3194: Test expectations now correctly match the new GET validation path.The updated assertions in Lines 3180-3194 validate both HTTP 415 and
invalidRequestWasReceivederror propagation.
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @apollo/server-integration-testsuite@5.5.0 ### Minor Changes - [#8191](#8191) [`ada1200`](ada1200) Thanks [@glasser](https://github.com/glasser)! -⚠️ SECURITY `@apollo/server/standalone`: Apollo Server now rejects GraphQL `GET` requests which contain a `Content-Type` header other than `application/json` (with optional parameters such as `; charset=utf-8`). Any other value is now rejected with a 415 status code. (GraphQL `GET` requests without a `Content-Type` header are still allowed, though they do still need to contain a non-empty `X-Apollo-Operation-Name` or `Apollo-Require-Preflight` header to be processed if the default CSRF prevention feature is enabled.) This improvement makes Apollo Server's CSRF more resistant to browsers which implement CORS in non-spec-compliant ways. Apollo is aware of one browser which as of March 2026 has a bug which allows an attacker to circumvent Apollo Server's CSRF prevention feature to carry out read-only XS-Search-style CSRF attacks. The browser vendor is in the process of patching this vulnerability; upgrading Apollo Server to v5.5.0 mitigates this vulnerability. **If your server uses cookies (or HTTP Basic Auth) for authentication, Apollo encourages you to upgrade to v5.5.0.** This is technically a backwards-incompatible change. Apollo is not aware of any GraphQL clients which provide non-empty `Content-Type` headers with `GET` requests with types other than `application/json`. If your use case requires such requests, please [file an issue](https://github.com/apollographql/apollo-server/issues) and we may add more configurability in a follow-up release. See [advisory GHSA-9q82-xgwf-vj6h](GHSA-9q82-xgwf-vj6h) for more details. ### Patch Changes - Updated dependencies \[[`ada1200`](ada1200)]: - @apollo/server@5.5.0 ## @apollo/server@5.5.0 ### Minor Changes - [#8191](#8191) [`ada1200`](ada1200) Thanks [@glasser](https://github.com/glasser)! -⚠️ SECURITY `@apollo/server/standalone`: Apollo Server now rejects GraphQL `GET` requests which contain a `Content-Type` header other than `application/json` (with optional parameters such as `; charset=utf-8`). Any other value is now rejected with a 415 status code. (GraphQL `GET` requests without a `Content-Type` header are still allowed, though they do still need to contain a non-empty `X-Apollo-Operation-Name` or `Apollo-Require-Preflight` header to be processed if the default CSRF prevention feature is enabled.) This improvement makes Apollo Server's CSRF more resistant to browsers which implement CORS in non-spec-compliant ways. Apollo is aware of one browser which as of March 2026 has a bug which allows an attacker to circumvent Apollo Server's CSRF prevention feature to carry out read-only XS-Search-style CSRF attacks. The browser vendor is in the process of patching this vulnerability; upgrading Apollo Server to v5.5.0 mitigates this vulnerability. **If your server uses cookies (or HTTP Basic Auth) for authentication, Apollo encourages you to upgrade to v5.5.0.** This is technically a backwards-incompatible change. Apollo is not aware of any GraphQL clients which provide non-empty `Content-Type` headers with `GET` requests with types other than `application/json`. If your use case requires such requests, please [file an issue](https://github.com/apollographql/apollo-server/issues) and we may add more configurability in a follow-up release. See [advisory GHSA-9q82-xgwf-vj6h](GHSA-9q82-xgwf-vj6h) for more details. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: David Glasser <glasser@apollographql.com>
GET requests carry their GraphQL operation in query parameters, not a body, so there is no legitimate reason to send any Content-Type other than application/json (which Apollo Client Web sends by default). Reject any other value — including valid MIME types like text/plain and application/graphql, as well as malformed values — with HTTP 415.
This also addresses GHSA-9q82-xgwf-vj6h
Summary by CodeRabbit
Security
Documentation