You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The package that is meant to be an example of enabling CORS, is actually inherently insecure too!
It defaults to disable CORS protections, not demonstration enabling CORS
I.e. putting Access-Control-Allow-Origin: * is not enabling CORS, it is telling the browser to disable same-origin policy protections for CORS and allow all origins, not allow a specific cross-origin to share resources with.
That use of @cross_origin() implies enabling CORS, but without the attribute origins it just means there are no allowed origins, and it will use the decorator default origin setting to allow all origins..
all origins is an important semantic because CORS is a protection to permit only allowed origins to share resources with, so enabling CORS should add this protection of only allowed origins! When you allow all origins, not just a permitted origin, you effectively disable CORS protections and force the behaviour no cross-origin resource sharing because, public is just public, it's not cross-origin when all origins are ignored and the resources are just shared to any origin.
What the demo actually does
Firstly it's easy to see that /protected has not enabled any CORS configuration to protect anything, the default disabled same-origin policy and allowed all origins, so the method is deliberately unprotected - ergo /unprotected, and there is no part of the demo app that has any actual protected paths to be exploited.
There is no way to demo an exploit if there's nothing to exploit in the demo..
What would make this demo, an actual demo of exploiting CORS
If there was a protected path in this demo, to exploit, CORS would actually be enabled
As long as the @app.after_request to always send Access-Control-Allow-Origin: *
The confusion is /allowed , what is the intention? it uses @cross_origin() without an origin, so does that mean it intended it to be same-origin? We covered above that it doesn't act this way by default, so does that mean the demo intended this /allowed path to be all origins? If that is the intention then using @cross_origin() is redundant and if you delete the decorator the behaviour is completely unchanged because you have @app.after_request to always send Access-Control-Allow-Origin: * (which is default for @cross_origin())
Which in itself is a massive problem because the entire demo will always respond with Access-Control-Allow-Origin: * and importing cross_origin at all is redundant, even my example improved /protected method that defined an allowed origin is redundant because @app.after_request makes all origins always allowed!
A better demo
To actually have a demo that shows an exploitation of CORS, you must first have a server-side demonstration of using CORS to permit only an allowed origin to the /protected path. Then the exploit would need to demonstrate how to access the /protected path from a malicious origin (which is not actually possible using a browser, but can be demonstrated using cURL or other non-browser clients)
Be honest, not a leet haxor exploit demo..
Misconfiguration demo is still a very good demo, it doesn't need to be called an exploit!
Just be honest, and say that the demo is showing how an intentionally insecure by-design app, that completely misconfigures CORS, can be exposing parts of your app you assumed were protected.
There is no exploit but rather an honest demo, without all the hyperbolic hacker nonesense, just a truthful humble demo of what a misconfiguration looks like. And the entire demo language changes to something that a developer (and most normal people) can relate too, and therefore actually find useful and learn from.
The text was updated successfully, but these errors were encountered:
The main problem is the entire demo relies on this package, and is default insecure.
skf-labs/X-allow-origin/X-Allow-origin.py
Lines 4 to 13 in 839042c
The package that is meant to be an example of enabling CORS, is actually inherently insecure too!
It defaults to disable CORS protections, not demonstration enabling CORS
I.e. putting
Access-Control-Allow-Origin: *
is not enabling CORS, it is telling the browser to disable same-origin policy protections for CORS and allow all origins, not allow a specific cross-origin to share resources with.Essentially this demo snippet:
This is not enabling CORS, or protected by CORS protections. it is unprotected by design.
The next snippet in the demo implies the application has enabled CORS:
That use of
@cross_origin()
implies enabling CORS, but without the attributeorigins
it just means there are no allowed origins, and it will use the decorator default origin setting to allow all origins..all origins is an important semantic because CORS is a protection to permit only allowed origins to share resources with, so enabling CORS should add this protection of only allowed origins! When you allow all origins, not just a permitted origin, you effectively disable CORS protections and force the behaviour no cross-origin resource sharing because, public is just public, it's not cross-origin when all origins are ignored and the resources are just shared to any origin.
What the demo actually does
Firstly it's easy to see that
/protected
has not enabled any CORS configuration to protect anything, the default disabled same-origin policy and allowed all origins, so the method is deliberately unprotected - ergo/unprotected
, and there is no part of the demo app that has any actual protected paths to be exploited.There is no way to demo an exploit if there's nothing to exploit in the demo..
What would make this demo, an actual demo of exploiting CORS
If there was a protected path in this demo, to exploit, CORS would actually be enabled
NB: the list for
origins
is misleading, only 1 origin is a valid value: corydolphin/flask-cors#300Current demo can never be a good demo
As long as the
@app.after_request
to always sendAccess-Control-Allow-Origin: *
The confusion is
/allowed
, what is the intention? it uses@cross_origin()
without an origin, so does that mean it intended it to be same-origin? We covered above that it doesn't act this way by default, so does that mean the demo intended this/allowed
path to be all origins? If that is the intention then using@cross_origin()
is redundant and if you delete the decorator the behaviour is completely unchanged because you have@app.after_request
to always sendAccess-Control-Allow-Origin: *
(which is default for@cross_origin()
)Which in itself is a massive problem because the entire demo will always respond with
Access-Control-Allow-Origin: *
and importingcross_origin
at all is redundant, even my example improved/protected
method that defined an allowed origin is redundant because@app.after_request
makes all origins always allowed!A better demo
To actually have a demo that shows an exploitation of CORS, you must first have a server-side demonstration of using CORS to permit only an allowed origin to the
/protected
path. Then the exploit would need to demonstrate how to access the/protected
path from a malicious origin (which is not actually possible using a browser, but can be demonstrated using cURL or other non-browser clients)Be honest, not a leet haxor exploit demo..
Misconfiguration demo is still a very good demo, it doesn't need to be called an exploit!
Just be honest, and say that the demo is showing how an intentionally insecure by-design app, that completely misconfigures CORS, can be exposing parts of your app you assumed were protected.
There is no exploit but rather an honest demo, without all the hyperbolic hacker nonesense, just a truthful humble demo of what a misconfiguration looks like. And the entire demo language changes to something that a developer (and most normal people) can relate too, and therefore actually find useful and learn from.
The text was updated successfully, but these errors were encountered: