Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws-apigateway: Allowed origins for CORS preflight are treated as regular expressions #26623

Closed
cyraxx opened this issue Aug 3, 2023 · 2 comments · Fixed by #26648
Closed
Labels
@aws-cdk/aws-apigateway Related to Amazon API Gateway bug This issue is a bug. effort/small Small work item – less than a day of effort p1

Comments

@cyraxx
Copy link

cyraxx commented Aug 3, 2023

Describe the bug

The CDK constructs for API Gateway allow supplying multiple trusted origins to be used in the auto-generated OPTIONS method handlers for CORS preflight responses (CorsOptions interface).

The CORS specification only allows for a single origin in the response headers, so what CDK does in this case is generate a response template that modifies the response based on the origin that the client is requesting. It checks each of the supplied origins (beyond the first one) to see if it matches the Origin request header, and if it does, it sets the Access-Control-Allow-Origin response header to the origin that was supplied in the request.

However, this check treats the configured origin as a regular expression (the code in question). Therefore, if https://www.company.com has been configured as an allowed origin, an attacker could register the domain https://wwwxcompany.com. A crafted request from this origin will match the regular expression and the preflight request succeeds.

It's possible that this is intended behavior, however the documentation doesn't mention anything to that effect. It would also be inconsistent as it does not apply to the first specified origin, only additional ones.

Expected Behavior

Given an API Gateway resource configured with the CORS preflight origins "https://www.firstorigin.com", "https://www.secondorigin.com":

An OPTIONS request to the resource with a request header of Origin: https://wwwXsecondorigin.com should lead to a response header similar to Access-Control-Allow-Origin: https://www.firstorigin.com, i.e. not allowing the invalid origin from the request.

Current Behavior

The OPTIONS request leads to a response header of Access-Control-Allow-Origin: https://wwwXsecondorigin.com, signaling to the requesting browser that the requested origin from is valid.

Reproduction Steps

Create a POC stack such as:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';

export class CorsPocStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new apigateway.RestApi(this, 'api', {
      defaultCorsPreflightOptions: {
        allowOrigins: ['https://www.firstorigin.com', 'https://www.secondorigin.com'],
      }
    })
      .root
      .addResource('hello')
      .addMethod('GET', new apigateway.MockIntegration({}));
  }
}

Deploy the stack.

Call the CORS preflight method, e.g. using httpie:
http OPTIONS https://xxx.execute-api.xxx.amazonaws.com/prod/hello "Origin: https://wwwXsecondorigin.com"

Examine the response and see that it includes the header: Access-Control-Allow-Origin: https://wwwXsecondorigin.com

Possible Solution

Change $origin.matches("${o}") to $origin == "${o}"

Additional Information/Context

No response

CDK CLI Version

2.89.0 (build 2ad6683)

Framework Version

No response

Node.js Version

v20.2.0

OS

macOS

Language

Typescript

Language Version

TypeScript (5.1.6)

Other information

No response

@cyraxx cyraxx added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Aug 3, 2023
@github-actions github-actions bot added the @aws-cdk/aws-apigateway Related to Amazon API Gateway label Aug 3, 2023
@pahud pahud self-assigned this Aug 4, 2023
@pahud
Copy link
Contributor

pahud commented Aug 4, 2023

Thank you for the call-out. Yes I can reproduce this behavior and we should fix that.

const condition = origins.map(o => `$origin.matches("${o}")`).join(' || ');

Are you interested to submit a PR for that?

@pahud pahud added p1 needs-review and removed needs-triage This issue or PR still needs to be triaged. labels Aug 4, 2023
@pahud pahud removed their assignment Aug 4, 2023
@pahud pahud added effort/medium Medium work item – several days of effort effort/small Small work item – less than a day of effort and removed effort/medium Medium work item – several days of effort labels Aug 4, 2023
mergify bot added a commit to lpizzinidev/aws-cdk that referenced this issue Aug 10, 2023
@mergify mergify bot closed this as completed in #26648 Aug 10, 2023
mergify bot pushed a commit that referenced this issue Aug 10, 2023
#26648)

Allowed origins for CORS preflight were treated like regular expressions in the checking condition.

For example, with this spec:
```
new apigateway.RestApi(this, 'api', {
      defaultCorsPreflightOptions: {
        allowOrigins: ['https://www.firstorigin.com', 'https://www.secondorigin.com'],
      }
    })
      .root
      .addResource('hello')
      .addMethod('GET', new apigateway.MockIntegration({}));
```

Calling:
```
http OPTIONS https://xxx.execute-api.xxx.amazonaws.com/prod/hello "Origin: https://wwwXsecondorigin.com"
```

The response header would include the header (allowing the invalid origin from the request):
```
Access-Control-Allow-Origin: https://wwwXsecondorigin.com
```

This fix solves the issue.

Closes #26623.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-apigateway Related to Amazon API Gateway bug This issue is a bug. effort/small Small work item – less than a day of effort p1
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants