-
Notifications
You must be signed in to change notification settings - Fork 421
Support multiple Allowed Origins in CORS #1006
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
Comments
Thanks for opening your first issue here! We'll come back to you as soon as we can. |
This will rely on using the FYI @heitorlessa |
Hey @straygar thanks a lot for raising this idea with us! I'd be careful on relying on As 2 can become tedious and error-prone, it opens the door for these sort of attacks that are quite common: https://we45.com/blog/3-ways-to-exploit-cors-misconfiguration I'd like to wait for more customers demand before we look into it, so we can think of additional factors besides Update after @michaelbrewer reach out to prevent ambiguityThe safest alternative is to use multiple APIs however painful this is. If creating multiple APIs isn't an option, the second safest option is below.
Sample annotated function to handle pre-flight CORS so you don't have to update every other routing function. from aws_lambda_powertools.event_handler.api_gateway import ApiGatewayResolver, CORSConfig
from aws_lambda_powertools.event_handler.exceptions import UnauthorizedError
# Default CORS for a prod environment
trusted_origins = ["<your static list>"]
cors_config = CORSConfig(allow_origin="https://prod.my.domain", max_age=100) # NOTE: never '*'
app = ApiGatewayResolver(cors=cors_config)
@app.route(method="OPTIONS", rule=".*") # Matches any pre-flight request coming from API Gateway
def preflight_handler():
"""Handles multi-origin preflight requests"""
origin = app.current_event.get_header_value(name="Origin", default_value="")
if origin in trusted_origins:
app._cors.allow_origin = origin
raise UnauthorizedError("Nope") # NOTE: do not return a default header to prevent abuse |
Optimal CORS configuration is always tricky. Classical solutions are a plenty via nginx configurations at allow for a set of regex origins. Not sure why there is a gap here for API GW. But it sounds like spinning up multiple endpoints is what is recommended. Better to be safe. |
@heitorlessa this is what the linked article does. I am just saying we could also do it in behave of the client. |
@heitorlessa NOTE using |
Just for comment i put up a PR: from aws_lambda_powertools.event_handler.api_gateway import ApiGatewayResolver, CORSConfig
from aws_lambda_powertools.event_handler.exceptions import UnauthorizedError
# allow_origin - default origin and fall through origin
# allow_origins - additional trusted origins
cors_config = CORSConfig(allow_origin="https://stg1.my.domain/", allow_origins=["https://stg2.my.domain/"])
app = ApiGatewayResolver(cors=cors_config)
print(app({"path": "/another-one", "httpMethod": "GET", "headers": {}}, None))
# {'statusCode': 404, 'headers': {'Access-Control-Allow-Origin': 'https://stg1.my.domain/', 'Access-Control-Allow-Headers': 'Authorization,Content-Type,X-Amz-Date,X-Amz-Security-Token,X-Api-Key', 'Content-Type': 'application/json'}, 'body': '{"statusCode":404,"message":"Not found"}', 'isBase64Encoded': False}
print(app({"path": "/another-one", "httpMethod": "GET", "headers": {"Origin": "https://stg2.my.domain/"}}, None))
# {'statusCode': 404, 'headers': {'Access-Control-Allow-Origin': 'https://stg2.my.domain/', 'Access-Control-Allow-Headers': 'Authorization,Content-Type,X-Amz-Date,X-Amz-Security-Token,X-Api-Key', 'Content-Type': 'application/json'}, 'body': '{"statusCode":404,"message":"Not found"}', 'isBase64Encoded': False} |
Moving this issue from Ideas to Backlog to start working on it soon. |
My current understanding of the situation is:
So it's a little bit of messy situation. We can of course add support to multiple origins when using a custom Lambda Preflight, but it can also be hard to set it up correctly. If we're going to move forward, I suggest we keep the existing API and add a new Then we can add a new issue for Powertools V3 where we combine both arguments into a @heitorlessa thoughts? SecuritySupporting multiple origins should not cause any additional security concerns. Those mainly come from using dynamic origins (e.g: regexes). We should also not leak information by returning an origin when one is not passed -- CORS backend should just accept or reject a requested origin. |
|
This is now released under 2.16.1 version! |
Is your feature request related to a problem? Please describe.
In some cases, we would like to support multiple origins in CORS when defining an API Gateway/ALB event handler (e.g. support calling an API from "localhost" in dev, or webapps living in different origins calling the same API).
Describe the solution you'd like
Allow providing a list of origins
CORSConfig(allow_origins=[])
(source). If the client'sOrigin
is in that list, that value is returned in the response header. Otherwise - an arbitrary (e.g. 1st) value from the list can be returned.The text was updated successfully, but these errors were encountered: