Skip to content

Commit c38eb33

Browse files
authored
Revise non-normative notes section (#345)
* First draft of overhaul * Grammar * Improve look of compiled spec * Rework text around preflight * Fix capitalisation of WHATWG * Add spellings
1 parent 36c4444 commit c38eb33

File tree

2 files changed

+74
-33
lines changed

2 files changed

+74
-33
lines changed

cspell.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ words:
1212
- parallelization
1313
- structs
1414
- subselection
15+
- mitigations
1516
# Software
1617
- ical
1718
- WebDAV
1819
- Protobuf
20+
- WHATWG
21+
- OWASP
1922
# Deliberate typos
2023
- qeury
2124
- __typena

spec/GraphQLOverHTTP.md

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ accepting both media types, the client SHOULD indicate it prefers
276276
For HTTP GET requests, the _GraphQL-over-HTTP request_ parameters MUST be
277277
provided in the query component of the request URL, encoded in the
278278
`application/x-www-form-urlencoded` format as specified by the
279-
[WhatWG URLSearchParams class](https://url.spec.whatwg.org/#interface-urlsearchparams).
279+
[WHATWG URLSearchParams class](https://url.spec.whatwg.org/#interface-urlsearchparams).
280280

281281
The {query} parameter MUST be the string representation of the source text of
282282
the document as specified in
@@ -291,7 +291,7 @@ The {operationName} parameter, if supplied and not the empty string, represents
291291
the name of the operation to be executed within the {query} as a string.
292292

293293
Note: In the final URL all of these parameters will appear in the query
294-
component of the request URL as URL-encoded values due to the WhatWG
294+
component of the request URL as URL-encoded values due to the WHATWG
295295
URLSearchParams encoding specified above.
296296

297297
Setting the value of the {operationName} parameter to the empty string is
@@ -757,41 +757,79 @@ etc.
757757

758758
# Non-normative notes
759759

760+
This section of the specification is non-normative, even where the words and
761+
phrases specified in RFC2119 are used.
762+
760763
## Security
761764

762-
In this specification, GET requests are not supported for mutations due to
763-
security concerns. GET requests expose variables to logging mechanisms and
764-
intermediaries due to the URL encoding of parameters, which can lead to
765-
sensitive data being inadvertently logged. Furthermore, GET requests are
766-
considered "simple requests" under CORS (Cross-Origin Resource Sharing), meaning
767-
they bypass preflight checks that add a layer of security.
768-
769-
On the other hand, using `application/json` for request bodies mandates a CORS
770-
preflight request, adding a security layer by ensuring the client has explicit
771-
permission from the server before sending the actual request. This is
772-
particularly important in mitigating cross-site request forgery (CSRF) attacks.
773-
774-
It's important to note that "simple requests" like those using
775-
`application/x-www-form-urlencoded` or `multipart/form-data` do not have the
776-
same CORS behavior, and thus do not undergo the same preflight checks.
777-
Implementers should be aware of the security implications of using these types
778-
of requests. While they can be secured with the right headers enforced by the
779-
server, it is crucial to understand and properly account for the security risks
780-
involved.
781-
782-
To mitigate these risks, it is recommended that servers require a custom header
783-
to ensure requests are not "simple." For instance, a `GraphQL-Require-Preflight`
784-
header can be used to indicate that a preflight check has occurred, providing an
785-
additional layer of security.
765+
This specification focuses solely on the intersection of GraphQL and HTTP.
766+
General concerns of either technology, including security concerns, are out of
767+
scope, except where their interaction introduces additional considerations.
768+
769+
### HTTP
770+
771+
Implementers are expected to have a solid understanding of the security
772+
implications of exposing a service over HTTP, and are responsible for
773+
implementing relevant mitigations and solutions. This specification will not
774+
repeat standard HTTP best practices such as not using `GET` for requests with
775+
side effects, safe logging of requests without revealing sensitive information,
776+
ensuring all connections are encrypted via HTTPS, placing limits on the length
777+
of incoming data, implementing rate limits, authorization and authentication
778+
security, request tracing, intrusion detection, and so on.
779+
780+
### GraphQL
781+
782+
Implementers are further expected to have a solid understanding of the security
783+
implications of running a GraphQL service and are responsible for implementing
784+
relevant mitigations and solutions there. For example, they may: limit the size
785+
and token count of GraphQL documents; ensure document validity; limit the number
786+
of errors a response may return; limit information revealed via errors; enforce
787+
validation and execution timeouts and pagination limits; implement query depth
788+
and complexity limits; implement authentication and authorization; apply rate
789+
limits to critical logic; and so on.
790+
791+
### Exercise caution
792+
793+
Where this specification leaves flexibility for the implementer, the implementer
794+
should be very cautious when exercising this freedom. Implementers must make
795+
themselves aware of and account for the security implications of their choices;
796+
while many alternative choices can be secured, securing them is outside of the
797+
scope of this specification.
798+
799+
For example, this specification allows alternative media types to be used to
800+
encode the request body; however, media types such as `multipart/form-data` or
801+
`application/x-www-form-urlencoded` may result in the request being treated by a
802+
browser as a "simple request", which does not require a "preflight", thereby
803+
opening the server up to Cross-Site Request Forgery (CSRF/XSRF) attacks. The
804+
recommended `application/json` media type requires a "preflight" check when
805+
issued cross-domain. See
806+
[CORS protocol](https://fetch.spec.whatwg.org/#http-cors-protocol) in the WHATWG
807+
Fetch spec for more details on this.
808+
809+
Note: One approach used by the community to mitigate CSRF risks is to ensure a
810+
request is not "simple" by requiring a custom header—such as
811+
`GraphQL-Require-Preflight`—is included. The presence of a custom header forces
812+
browsers to enact a "preflight" check, thereby adding an additional layer of
813+
security. (This is not a standard header, and many alternative headers could
814+
serve the same purpose. This is presented merely as an example of a pattern seen
815+
in the community.)
816+
817+
Further extending this example, using `multipart/form-data` may allow large
818+
values to be referenced multiple times in a GraphQL operation, potentially
819+
causing the GraphQL service to process a much larger GraphQL request than the
820+
HTTP request size would suggest.
821+
822+
### Other resources
786823

787824
For more detailed security considerations, please refer to
788825
[RFC 7231](https://tools.ietf.org/html/rfc7231),
789-
[RFC 6454](https://tools.ietf.org/html/rfc6454), and other relevant RFCs.
826+
[RFC 6454](https://tools.ietf.org/html/rfc6454), other relevant RFCs, and other
827+
resources such as [OWASP](https://owasp.org).
790828

791-
## Request format compatibility
829+
## Future compatibility
792830

793-
Supporting formats not described by this specification, such as XML or Protobuf,
794-
may have potential conflicts with future versions of this specification as
795-
ongoing development aims to standardize and ensure the security and
796-
interoperability of GraphQL over HTTP. For this reason, it is recommended to
797-
adhere to the officially recognized formats outlined here.
831+
Supporting formats not described by this specification may have potential
832+
conflicts with future versions of this specification as ongoing development aims
833+
to standardize and ensure the security and interoperability of GraphQL over HTTP
834+
whilst accounting for its growing feature set. For this reason, it is
835+
recommended to adhere to the officially recognized formats outlined here.

0 commit comments

Comments
 (0)