This document discusses how Cross-Origin Resource Sharing (CORS) is intended to allow cross-domain requests but can impact security if misconfigured. CORS uses HTTP headers to enable controlled cross-domain access and is supported by services like Amazon S3, CloudFront, API Gateway, and Lambda. While CORS allows legitimate cross-domain content sharing, misconfigurations can bypass the same-origin policy and allow attackers to steal user sessions, credentials, or other sensitive data across domains. The document provides examples of how CORS has been exploited in the past and cautions that even minor CORS issues can become major security vulnerabilities when user contexts are involved.
3. Introduction
● What is CORS?
● How does it work?
● Where does CORS fit in the cloud?
● How can CORS impact my security posture?
● How can it go wrong?
4. What is CORS?
CORS - cross origin resource sharing - is a mechanism which uses HTTP
headers to tell a browser to let a web application running at one origin
(domain) have permission to access selected resources from a server at a
different origin.
This functionality exists in cases where an application developer would
want to deliberately ignore a same origin policy (SOP) which mitigates
many common attacks against browsers (notably cross-site scripting)
5. Same-origin what now?
The Same-Origin Policy is a security
control which seeks to prevent
malicious actors from injecting
malicious scripts from an attacker
controlled domain into a legitimate
session.
Image via trustedsec.com/2018/04/cors-findings
6. So what is a cross-origin request?
A cross origin request is a request made to:
● A different domain (example.com to test.com)
● A different subdomain (example.com to test.example.com)
● A different port (example.com to example.com:8080)
● A different protocol (https://example.com to http://example.com)
7. Why use CORS?
In some cases, you may want to bypass the same-origin policy to share
content from a CDN, an S3 bucket, or an on-prem server.
● If you host your website in S3, but want to use JavaScript to be able to
make authenticated GET and PUT requests against the same bucket
by using the Amazon S3 API endpoint for the bucket.
● Loading a web font.
● Loading dynamic content from another webpage.
● Making an authenticated GET request to an on-prem server.
8. How does CORS work?
There are two associated HTTP headers:
Access-Control-Allow-Origin
Access-Control-Allow-Credentials
Access-Control-Allow-Credentials is a boolean field. It tells the browser
that it’s okay for the allowed origins to read the information in this response
even if cookies were used.
Access-Control-Allow-Origin can accept many potential inputs which tell
the browser what origins are allowed to be in cross-origin requests.
9. Access-Control-Allow-Origin
The allow-origin access control header accepts:
● Domains and subdomains (http://blah.stuff.ninja, https://stuff.ninja)
● Wildcards (*)
● null
Wildcards seem promising, but there is a “kill-switch” which does not allow
Access-Control-Allow-Credentials to be true when Access-Control-Allow-
Origin is *.
10. The ‘null’ origin
The null origin is supported by a lot of applications (formerly including
Google’s PDF reader) and per the specification, is often needed to support
redirects.
Notably, the choice of the keyword ‘null’ makes it so that for some
applications, failure to configure a whitelist ultimately allows the ‘null’
origin.
11. Generated Origins
In many cases, the origin is parsed by the application and the access-
control-allow-origin header is generated programmatically. This is common
due to the difficulties associated with specifying multiple allowed domains
in CORS configurations.
Many applications make no effort to validate the provided origin before
reflecting it in the header, essentially allowing users (and attackers!) to
provide their own whitelist for the origin.
12. How does this affect AWS?
A short list of AWS services which support CORS:
● S3
● CloudFront
● API Gateway
● Lambda
13. CORS in S3
CORS can be enabled in the S3 console, or via API/SDK.
CORS configurations are required to use CORS (duh) and up to 100 rules
are supported.
CORS in S3 can be tricky because of the other factors at play for a bucket
(ACL, policy, etc.)
Using Cloudfront, you can simplify your CORS configuration.
References:
1. https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html
2. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomO
rigin.html#request-custom-cors
14. CORS in API Gateway/Lambda
If you need CORS for an API Gateway and it is not a “simple” request, you
need to enable CORS support.
CORS support is where the majority of observed exploitable
misconfigurations occur.
In order to enable CORS support for Lambda or HTTP Proxy integrations,
a Lambda function must be provided which builds the allowed origin
headers. References:
1. https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html
15. How does CORS hurt security?
By creating a place to bypass the single origin policy, you create
opportunities for attackers to do the same.
A CORS misconfiguration can easily turn a simple cross-site scripting
vulnerability into a major issue.
16. How can it go wrong?
In the cases of origins being generated on the fly:
● DoD website had an improper access control in CORS which allowed
an attacker to steal user sessions. (hackerone.com/reports/470298)
● Bitcoin exchange had a vulnerability which could steal users’ private
API key, allowing all of their BTC to be transferred to an arbitrary
address(https://portswigger.net/blog/exploiting-cors-misconfigurations-
for-bitcoins-and-bounties)
17. How can it go wrong?
The case of the null origin is unique.
The specification suggests that it can be triggered by redirects and is
generally associated with local files - so it’s widely whitelisted.
Any website can easily obtain the null origin using a sandboxed iframe,
and this has been used to compromise a bitcoin exchange.
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src='data:text/html,<script>#SOMETHING BAD
HERE#</script>’></iframe>
18. How can it go wrong… in AWS?
If you host any sessionized app where a user logs in, a CORS
misconfiguration can allow for session hijacking.
Mywebsite
.com
API Gateway
provides
interface to
DynamoDB
Lambda
handles
CORS
requests
19. How can it go wrong… in AWS?
Mywebsite.
com
User
User
logs in
Lambda
parses query
and sends to
DynamoDB
Lambda validates
origin and passes
access-control-allow-
origin header
User is
provided
resources
from cross-
domain
request to
DynamoDB
20. How can it go wrong… in AWS?
Mywebsite.
com
User
Mywebsite.c
om.Badwebp
age.evil
User gets
sent to bad
webpage
(phish,
watering hole,
whatever)
CORS allows
credentials to
be sent
incorrectly
cross-domain
Evil website
impersonates user
Receives
valid creds
from
compromised
user
Returns the
requested
data to the
attacker
21. Conclusion
CORS can be a real pain to configure correctly but it is critical to protecting
your business and your users
Even though its’ a seemingly benign thing to misconfigure, it amplifies the
severity of any other bug