corydolphin / flask-cors

Cross Origin Resource Sharing ( CORS ) support for Flask
https://flask-cors.readthedocs.io/en/latest/index.html
MIT License
880 stars 139 forks source link

Potential vulnerability from returning Origin value as Access-Control-Allow-Origin #364

Closed dimo414 closed 1 week ago

dimo414 commented 3 weeks ago

It appears that flask-cors (by default?) sets the response Access-Control-Allow-Origin to the value of the request's Origin. I understand from https://fetch.spec.whatwg.org/#http-access-control-allow-origin that this is typical, however pentesting resources like https://blog.vidocsecurity.com/blog/cross-origin-resource-sharing-vulnerabilities/ indicate that "Dynamically reflecting origins from requests could be easily exploitable by a malicious actor."

I confess I don't fully understand the semantics of this header, nor the potential ramifications of a malicious actor exploiting the Origin header, but this behavior has been pointed out to me as a security vulnerability and so I'm trying to evaluate how or if it can be mitigated within flask-cors.

Thanks for the help, and apologies if this has already been discussed elsewhere, I did search the repo's issues but didn't see any obviously-related issues.

raj-patra commented 3 weeks ago

Yep, also seeing this issue being pointed out by Snyk just today as a "High" vulnerability. Overview from Snyk is as follows:

Affected versions of this package are vulnerable to Improper Access Control due to the default configuration of the Access-Control-Allow-Private-Network CORS header. An attacker can expose private network resources to unauthorized external access by leveraging this default setting.

Can't really use the package in any production deployments until this is patched.

andersskog commented 2 weeks ago

From Dependabot:

A vulnerability in corydolphin/flask-cors version 4.0.1 allows the Access-Control-Allow-Private-Network CORS header to be set to true by default, without any configuration option. This behavior can expose private network resources to unauthorized external access, leading to significant security risks such as data breaches, unauthorized access to sensitive information, and potential network intrusions.

ThiefMaster commented 2 weeks ago

The main difference between setting it to * and to the actual origin received by the client is that the former prohibits sendign a CORS request that has withCredentials enabled (ie active session cookies etc. are kept).

For an API this is irrelevant, because you typically do not have anything stateful. It's more dangerous if you just enable CORS on a regular website, because then one could impersonate the user who's currently logged-in by sending CORS requests that inherit their session.

dimo414 commented 2 weeks ago

The Access-Control-Allow-Private-Network vulnerability is a separate issue, discussed in #337

corydolphin commented 1 week ago

Thanks y'all. Yes, the behavior for Access-Control-Allow-Private-Header has been adjusted in versions 4.0.2 and 5.0.0 to be secure by default.

Fundamentally it is up to users to choose and configure how they would like to return CORS headers. I'm open to proposed changes to the strategy https://github.com/corydolphin/flask-cors/issues/320#issuecomment-1327909435