0 ratings0% found this document useful (0 votes) 72 views12 pagesGraph QL
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content,
claim it here.
Available Formats
Download as PDF or read online on Scribd
972522, 6:33 AM GrapnOL - OWASP Cheat Sheet Series
GraphQL Cheat Sheet
Introduction
GraphQL is an open source query language originally developed by Facebook that can be used to
build APIs as an altemative to REST and SOAP. Ithas gained popularity since its inceptionin 2012
because of the native flexibility it offers to those building and calling the APL There are GraphQL.
servers and clients implemented in various languages. Many companies use GraphQL including
Gitriub, Credit Karma, Intuit, and PayPal.
This Cheat Sheet provides quidance on the various areas that need to be considered when working
with Graphol:
‘Apply proper input validation checks on all incoming data.
‘* Expensive queries will lead to Denial of Service (DoS), so add checks to mit or prevent queries
‘that are too expensive.
+ Ensure that the API has proper access control checks.
«Disable insecure default configurations (eg. excessive errors, introspection, GraphiQL, etc.)
Common Attacks
Injection -this usually incdes but is not fited to:
# SQL and NoSAt injection
¢ OS Command injection
«SRF and CRLF injection/Request Smuggling
DoS (Denial of Service)
Abuse of broken authorization: ether improper or excessive access, including IDOR
Betching Attacks, a GraphQL-specific method of brute force attack.
+ Abuse of insecure default configurations
Best Practices and Recommendations
Intps:ifcheatshectseries.owasp.orgicheatsheets/GraphQL_Cheat_Sheet himl ane972522, 6:33 AM GrapnOL - OWASP Cheat Sheet Series
Input Validation
‘Adding strict input validation can help prevent against injection and DoS. The main design for
GraphQL is that the user supplies one or more identifiers and the backend has a number of data
fetchers making HTTP, DB, or cther calls using the given identifiers. This means that user input will
beincluded in HTTP requests, DB queries, or other requests/calls which provides opportunity for
injection that could lead to various injection attacks or DoS.
‘See the OWASP Cheat Sheets on Input Validation and general injection prevention for full details to
best perform input validation and prevent injection.
General Practices
Validate all incoming data to only allow valid values (ie. allow list).
+ Use specific GraphOL data types such as scalars or enums, Write custom GraphQL velidators
for more complex validations. Custom scalars may also come in handy.
Define schemas for mutations input,
List allowed characters - donit use a block list
+ The stricter the fist of allowed characters the better. Alot of times a good starting point is
only allowing alphanumeric, non-unicode characters because it will disallow many attacks.
To property handle unicode input, use a single internal character encoding
Gracefully reject invalid input, being careful nct to reveal excessive information about how the
‘AP\ and its validation works.
Injection Prevention
\When handling input meant to be passed to ancther interpreter (e.g. SQL/NoSQL/ORM, OS, LDAP,
XML):
‘+ Alwayschoose libraries/modules/packages offering safe APIs, such as parameterized
statements.
‘+ Ensure that you follow the documentation so you are property using the tool
+ Using ORMs and ODMs are a good option but they must be used properly to avoid flaws
suchas ORM injection,
+ If such tools are not available, always escape/encode input data according to best practices of
‘the target interpreter
+ Choose a welldocumented and actively maintained esceping/encoding library. Many
languages and frameworks have this functionality bun.
Intps:ifcheatshectseries.owasp.orgicheatsheets/GraphQL_Cheat_Sheet himl ane972522, 6:33 AM GrapnOL - OWASP Cheat Sheet Series
For mote information see the below pages:
‘© SQL Injection Prevention
‘* NoSQL Injection Prevention
‘¢ LDAP Injection Prevention
‘© 0S Command Injection Prevention
‘¢ XML Security and XXE Injection Prevention
Process Validation
When using user input, even if sanitized and/or validated, it should not be used for certain
Purposes that would give a user control over data flow. For example, do not make an
HTTP/resource request to a host that the user supplies (unless there is an absolute business
need).
DoS Prevention
DoS is an attack against the availability and stability of the API that can make it slow, unresponsive,
or completely unavailable. This CS details several methods to limit the possibility of a DoS attack
at the application level and other layers of the tech stack. There is also a CS dedicated to the topic
of Dos,
Here are recommendations specific to GraphQL to limit the potential for DoS:
«+ Add depth limiting to incoming queries,
+ Add amount
iting to incoming queries,
+ Add pagination to limt the amount of data that can be returned in a single response
‘+ Add reasonable timeouts at the application layer, infrastructure layer, or bath
+ Consider performing query cost analysis and enforcing a maximum allawed cost per query
‘+ Enforce rate limiting on incoming requests per IP or user (or both) to prevent basic DoS
attacks
+ Implement the batching and caching technique on the server-side (Facebook's Datal oader can
be used for this)
‘Query Limiting (Depth & Amount)
In GraphQL each query has adepth (eg. nested objects) and each object requested in a query can
have an amount specified (e.g. 99999999 of an object). By default these can both be unlimited
which mey leadto a DoS. You should set mits on depth and amount to prevent DoS but this
Intps:ifcheatshectseries.owasp.orgicheatsheets/GraphQL_Cheat_Sheet himl az972522, 6:33 AM GrapnOL - OWASP Cheat Sheet Series
usually requires a small custom implementation asit is nct natively supported by GraphQl. See
this and this page for more information about these attacks and how to add depth and amount
limiting. Adding pagination can also help performance.
‘APIs using graphqtjava can utilize the builtin MaxQueryDepthinstrumentation for depth limit
‘APIs using JavaScript can use graphql-deptivlimit to implement depth limiting and graphelinput-
number to implement amount limiting.
Here is an example of a GraphQL query with depth N:
query evil { # Depth: 8
album(id: 42) { # Depth: 1
songs { # Depth: 2
album { # Depth: 3
ce # Depth: ...
album {id: N} # Depth: N
+
}
}
+
Here is an example of a GraphQL query requesting 99999999 of an object:
query {
author (id: “abo") {
posts(First: 99999999) {
title
>
>
}
Timeouts
‘Adding timeouts can be a simple way to limit how many resources any single request can
consume, But timeouts are not always effective since they may not activate until a malicious query
has already consumed excessive resources. Timeout requirements will differ by API and data
fetching mechanism; there isn't one timeout value that will work across the board.
‘At the application level, timeouts can be added for queries and resolver functions. This option is
usually more effective since the query/resolution can be stopped once the timeout is reached.
GraphQL does not natively support query timeouts so custom code is required. See this blog post
formore about using timeouts with GraphQL or the two examples below.
JavaScript Timeout Example
Code snippet ffom this SO answ
Intps:ifcheatshectseries.owasp.orgicheatsheets/GraphQL_Cheat_Sheet himl ana972522, 6:33 AM GrapnOL - OWASP Cheat Sheet Series
request .incrementResolverCount = function () {
var runTime = Date.now() - startTine;
if (runtime > 18080) { // @ timeout of 10 seconds
if (request.logTimeouterror) {
Jogger(‘ERROR', “Request ${request.uuid} query execution tineout”);
}
request logTimeoutError = false;
throw ‘Query execution has timeout. Field resolution aborted’ ;
>
this. resolverCount++;
a
Java Timeout Example using Instrumentation
public class Timeoutinstrumentation extends SimpleInstrumentation {
override
public DataFetcher> instrunentDataFetcher (
DataFetcher dataFetcher, InstrumentationFieldFetchParaneters
parameters
4
return environment ~>
Observable. fronCallable(() -> dataFetcher .get(environment))
+subscribeOn(Schedulers .conputation())
stimeout(18, TimeUnit.SECONDS) // tineout of 18 seconds
-blockingFirst() ;
Infrastructure Timeout
‘Another option to adda timeout that is usually easier is adding a timeout on an HTTP server
(Apache/ttpd, nginx), reverse praxy, or ad balancer. However, infrastructure timeouts are cften
inaccurate and can be bypassed more easily than application-level ones.
Query Cost Analysis
Query cost analysis involves assigning costs to the resolution of fields or types in incoming queries
so that the server can reject queries that cast too much fo run or will consume toomeany
resources. This isnot easy to implement and may not always be necessary but it is the most
thorough approach to preventing DoS. See "Query Cost Analysis" in this blog post for more details
on implementing this controb
‘Apollo recommends:
Before you go ahead and spend a ton of time implementing query cost analysis be certain you
need it. Try to crash or slow dawn your staging API
a nasty query and see how far you get —
Intps:ifcheatshectseries.owasp.orgicheatsheets/GraphQL_Cheat_Sheet himl siz972522, 6:33 AM GrapnOL - OWASP Cheat Sheet Series
maybe your API doesrit have these kinds of nested relationships, or maybe it can handle
fetching thousands of records at a time perfectly fine and doesrtt need query cost analysis!
‘APIs using graphdt-java can utilize the builtin MaxQueryComplexityinstrumentationto toenforoe
max query complextty. APIs using JavaScript can utilize graphal-cost-analysis or graphqk
validation-complexity to enforce max query cost.
Rate Limiting
Enforcing rate limiting on a per IP or user (for anonymous and unauthorized access) basis can help
limit a single users ability to spam requests to the service and impact performance. Ideally this
can be done with a WAF, API gateway, or web server (Nginx, Apache/HTTPD) to reduce the effort of
adding rate imiting,
Oryou could get somewhat complex with throttiing and implementit in your code (non-trivial), See
“Throttling” here for more about GraphQL-specific rate limiting.
Server-side Batching and Caching
To increase efficiency of a GraphQL APL and reduce its resource consumption, the batching and
caching technique can be used to prevent making duplicate requests for pieces of data within a
small time frame. Facebook's Datal.oader tool is one wey to implement this,
‘System Resource Management
Nat properly limiting the amount of resources your API can use (e.g. CPU or memory), may
‘compromise your API responsiveness and availability, leaving it vunerable to DoS attacks. Some
limiting can be done at the operating system level,
OnLinux, a combination of Control Groups(cgroups), User Limits (ulimits), and Linux Containers
(XC) can be used,
However, containerization platforms tend to make this task much easier. See the resource limiting
section in the Docker Security Cheat Sheet for how to prevent DoS when using containers.
Access Control
Toensure that a GraphQL API has proper access control, do the following:
+ Always validate that the requester is authorized to view or mutate modify the data they are
requesting. This can be done with RBAC or ather access control mechanisms.
‘* Thiswill prevent IDOR issues, includingboth BOLA and BFLA.
Intps:ifcheatshectseries.owasp.orgicheatsheets/GraphQL_Cheat_Sheet himl ez972522, 6:33 AM GrapnOL - OWASP Cheat Sheet Series
‘+ Enforce authorization checks on bath edges and nodes (see example bug report where nodes
did not have authorization checks but edges did).
* Use Interfaces and Unions to create structured, hierarchical deta types which can be used to
retum mote oF fewer object properties, according to requester permissions.
‘+ Quety and Mutation Resolvers can be used to perform access control vaidation, possibly
using some RBAC middleware.
« Disable introspection queries system-wide in any production or publicly accessible
environments.
+ Disable GraphiQL and other similar schema exploration tools in production or publicly
accessible environments.
General Data Access
It's commonplace for GraphQL requests to include one or more direct IDs of objects in order to
fetch or modify them. For example, a request for a certain picture may include the ID that is,
actually the primary key in the database for that picture. As with any request, the server must verify
that the caller has access to the object they are requesting, But sometimes developers make the
mistake of assuming that possession of the object's ID means the caller should have access.
Failure to verify the requester’s access in this case is called Broken Object Level Authentication,
alsoknown as IDOR,
It's possible for a GraphQL API to support access to objects using their ID even if that is not
intended, Sometimes there are node or nodes or both fields in a query object, and these can be
Used to access objects directly ty 1D. You can check whether your schema has these fields by
running this on the commendtline (assuming that schena..json contains your GraphQL. schema):
cat schena.json | jq ".data._-schena.types|] | select(.name=-\"Query\") | .fields{]
| ,
variables: < variables for query @ >,
7
{
query: < query 1 >,
variables: < variables for query 1 >,
hb
{
query: < query n>
variables: < variables for query n >,
}
]
‘And heres an example query ofa single batched GraphdL call requesting muttple different
instances of the droid object:
query {
droid(id: *2000") {
>
second:droid(id: "2001") {
>
third:droid(ad: 2002") ¢
)
}
Inthis case it could be used to enumerate every possible droid object that is stored on the server
in very few network requests as opposed to a standard REST API where the requester would need
Intps:ifcheatshectseries.owasp.orgicheatsheets/GraphQL_Cheat_Sheet himl anz972522, 6:33 AM GrapnOL - OWASP Cheat Sheet Series
to submit a different network request for every different droid ID they want to request. This type
of attack can lead to the following issues:
‘+ Applicationevel DoS attacks - A high number of queries or object requests in a single network
call could cause a database to hang or exhaust other available resources (e.g. memory, CPU,
downstream services).
+ Enumeration of objects on the server, such as users, emails, and user IDs
+ Brute forcing passwords, 2 factor authentication codes (OTPs), session tokens, or other
sensitive values.
+ WAFs, RASPs, IDS/IPS, SIEMs, or other security tooling will ikely not detect these attacks since
they only appear to be one single request rather than an a massive amount of network traffic.
‘+ This attack will ikely bypass existing rate limits in tools like Nginx or other proxies/gateways
since they rely on looking at the raw number of requests,
Mitigating Batching Attacks
In order to mitigate this type of attack you should put limits on incoming requests at the code level
so that they can be applied per request. There are 3 main options:
+ Add object request rate limiting in code
+ Prevent batching for sensitive objects
‘+ Limit the number of queries that can run at one time
One option is to create a code-level rate limit on how many objects that callers can request. This
means the backend would track how many different object instances the caller has requested, so
that they will be blocked after requesting too many objects even if they batch the object requests in
a single network call. This replicates a network-level rate limit that a WAF or other tool would do.
‘Another option is to prevent batching for sensitive objects that you don't want to be brute forced,
such as usernames, emails, passwords, OTPs, session tokens, etc. This way an attacker is forced
to attack the API like a REST API and make a different network call per object instance. This is not
supported natively so it will require a custom solution. However once this control is put in place
other standard controls will function normally to help prevent any brute forcing
Limiting the number of operations that can be batched and run at once is another option to
mitigate GraphQL batching attacks leading to DoS. This is not a silver bullet though and should be
used in conjunction with other methods.
Secure Configurations
Intps:ifcheatshectseries.owasp.orgicheatsheets/GraphQL_Cheat_Sheet himl enn972522, 6:33 AM GrapnOL - OWASP Cheat Sheet Series
By default, most GraphQL implementations have some insecure default configurations which
should be changed
+ Dont retum excessive error messages (e.g. disable stack traces and debug mode)
‘+ Disable or restrict Introspection and GraphiQL based on your needs.
‘+ Suggestion of mis-typed fields if the introspection is disabled
Introspection + GraphiQh
GraphQL Often comes by default with introspection and/or GraphiQL enabled and not requiring
authentication. This allows the consumer of your API to learn everything about your API, schemas,
mutations, deprecated fields and sometimes unwanted "private fields’.
This might be an intended configuration if your API is designed to be consumed by external clients,
but can also be an issue if the API was designed to be used internally only. Although security by
obscurity is not recommended, it might be a good idea to consider removing the Introspection to
avoid any leak. if your API is publicly consumed, you might want to consider disabling it for not
authenticated or unauthorized users.
For internal API, the easiest approach Is to just disable Introspection system-wide. See this page or
consult your GraphQL implementations documentation to learn how to disable introspection
altogether. If your implementation does not natively support disabling introspection or if you would
like to allow some consumers/roles to have this access, you can build a filter in your service to only
allow approved consumers to access the introspection system.
Keep in mind that even if introspection is disabled, attackers can still guess fields by brute forcing
them. Furthermore, GraphQL has a builtin feature to return a hint when a field name that the
requester provides is similar (but incorrect) to an existing field (e.g. request has usr and the
response will ask Did you meen “user?” ). You should consider disabling this feature if you have
disabled the introspection, to decrease the exposure, but nct all implementations of GraphOL.
‘support doing so. Shapeshifter is one 100) that should be able to do this,
Disable introspection - Java
GraphQlschena schena = GraphalSchena.newSchema\ )
-query(SterWarsschene .queryType)
sfieldVisibility(
NotntrospectionGraphqiFieldVisibility..NO_INTROSPECTION.FIELD_VISIBILITY )
sbuild();
Disable Introspection & GraphiQL - JavaScript
Intps:ifcheatshectseries.owasp.orgicheatsheets/GraphQL_Cheat_Sheet himl sone972522, 6:33 AM GrapnOL - OWASP Cheat Sheet Series
‘app.use('/graphql', graphqlHTTP({
schema: MySessionAwareGraphQLSchena,
+ validetionRules: [NoTntrospection]
grephigl: process. env.NODE_ENV
y)
development",
Dont Retum Excessive Errors
GraphQl APIsin production shaukirtt retum stack traces or be in debug mode. Doing this is
implementation specific, Butusing mddleware is one popular way to have better control over
errors the server retums. To disable excessive errors with Apollo Server either pass debug: false
to the Apollo Server constructor or setthe Node EN environment variable to ‘production or ‘test.
However, if you would like to log the stack trace intemally without retuming itto the user see here
for how to mask and log errors so they are available to the developers but nat callers of the API.
Other Resources
Tools
‘* InQL Scanner Security scanner for GraphQL. Particularly useful for generating queties and
mutations autometically from given schema and them feeding them to scanner.
‘* GraphiQl -Schema/object exploration
¢ GraphQL Voyager - Schema/object exploration
GraphQL Security Best Practices + Documentation
‘© GraphQL security best practices
* Protecting GraphQl. APIs from security threats -blog post
‘« https://nordicapis.com/security-points-to-consider-beforeimplementing-graphql/
«Limiting resource usage to prevent DoS (timeouts, throttling, complexity management, depth
limiting, etc.)
# GraphQl Security Perspectives
+ A developer's security perspective of GraphQh
More on GraphQL Attacks
‘* Some common GraphQL attacks + attacker mindset
Bypassing permissions by smuggling parameters
Intps:ifcheatshectseries.owasp.orgicheatsheets/GraphQL_Cheat_Sheet himl sineGrapnOL - OWASP Cheat Sheet Series
Bug bounty writeup about GraphQL
Security talk about Abusing GraphQL
Real world attacks against GraphQL in the past
‘¢ Attack examples against GraphQl
Intps:ifcheatshectseries.owasp.orgicheatsheets/GraphQL_Cheat_Sheet himl