Skip to main content

GET based CSRF

Description

CSRF (Cross-Site Request Forgery) occurs when an external website has the ability to make API calls impersonating a user by visiting the website while being authenticated to your API.

Allowing API calls through GET requests can lead to CSRF attacks because cookies are added automatically to GET requests made by the browser.

Note that CSRF is an attack vector that specifically target requests where the browser automatically provides authentication (typically through Cookie or Basic Authentication).

Especially, if your application is attaching the credentials via an Authorization header then the browser can't automatically authenticate the requests, and CSRF isn't possible.

Remediation

Forbid API calls through GET requests to prevent CSRF attacks.

Apollo

Pass csrfPrevention: true to new ApolloServer().

Check out the the CSRF prevention documentation for the best CSRF prevention techniques.

Awsappsync

Make sure that your API does not use Cookie-based authentication.

There are many other ways to authenticate a user with AppSync:

  • API Keys
  • Amazon Cognito User Pools
  • OpenID Connect
  • AWS Identity and Access Management (IAM)
  • AWS Lamba custom authentication

AppSync: Authorization and Authentication

Whichever method you use, verify that authentication occurs through headers because authentication headers are not automatically added by the targeted user browser (while Cookies are).

To avoid any risk, you can block every GET request and allow only POST requests, which are immune to this attack, but it comes at a cost. (see AWS pricing for the corresponding services)

  • Block GET requests with AWS API Gateway (prefered method):

Put your AppSync API behind an API Gateway.

API Gateway Documentation

You can then configure the API Gateway to act as an HTTP Proxy to your AppSync endpoint and configure it to allow only POST requests.

  • Block GET requests with AWS Web Application Firewall:

Add the following Web ACL rule in the AWS WAF Console to block every GET request to the API:

{
"Name": "block-get",
"Priority": 0,
"Statement": {
"ByteMatchStatement": {
"SearchString": "GET",
"FieldToMatch": {
"Method": {}
},
"TextTransformations": [
{
"Priority": 0,
"Type": "NONE"
}
],
"PositionalConstraint": "EXACTLY"
}
},
"Action": {
"Block": {}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "add-headers"
}
}

You can also configure it manually by using the following field values :

If:

  • Field to match = HTTP method
  • Positional constraint = Exactly matches string
  • Search string = GET

Then:

  • Block

See: AppSync API with AWS WAF.

To learn more on AWS WAF, see: AWS WAF.

Configuration

CheckId: request_forgery/get_based_csrf

Examples

Ignoring this check

{
"checks": {
"request_forgery/get_based_csrf": {
"skip": true
}
}
}

Score

  • Escape Severity: HIGH
  • OWASP: A02:2023
  • PCI DSS: 6.5.9
  • CWE
    • 345
    • 346
    • 352
    • 693
  • WASC: 9

CVSS

  • CVSS_VECTOR: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N/E:H/RL:O/RC:C
  • CVSS_SCORE: 7.2

References

https://blog.doyensec.com/2021/05/20/graphql-csrf.html