-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17305 from Kwstubbs/CORSMiddleware-Starlette
Python: Add Support for CORS Middlewares
- Loading branch information
Showing
15 changed files
with
389 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
python/ql/src/change-notes/2024-08-26-Cors-misconfiguration-middleware.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
category: newQuery | ||
--- | ||
* The `py/cors-misconfiguration-with-credentials` query, which finds insecure CORS middleware configurations. |
64 changes: 64 additions & 0 deletions
64
python/ql/src/experimental/Security/CWE-942/CorsMisconfigurationMiddleware.qhelp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<!DOCTYPE qhelp PUBLIC | ||
"-//Semmle//qhelp//EN" | ||
"qhelp.dtd"> | ||
<qhelp> | ||
<overview> | ||
<p> | ||
Web browsers, by default, disallow cross-origin resource sharing via direct HTTP requests. | ||
Still, to satisfy some needs that arose with the growth of the web, an expedient was created to make exceptions possible. | ||
CORS (Cross-origin resource sharing) is a mechanism that allows resources of a web endpoint (let's call it "Peer A") | ||
to be accessed from another web page belonging to a different domain ("Peer B"). | ||
</p> | ||
<p> | ||
For that to happen, Peer A needs to make available its CORS configuration via special headers on the desired endpoint | ||
via the OPTIONS method. | ||
</p> | ||
<p> | ||
This configuration can also allow the inclusion of cookies on the cross-origin request, | ||
(i.e. when the <code>Access-Control-Allow-Credentials</code> header is set to true) | ||
meaning that Peer B can send a request to Peer A that will include the cookies as if the request was executed by the user. | ||
</p> | ||
<p> | ||
That can have dangerous effects if the origin of Peer B is not restricted correctly. | ||
An example of a dangerous scenario is when <code>Access-Control-Allow-Origin</code> header is set to a value obtained from the request made by Peer B | ||
(and not correctly validated), or is set to special values such as <code>*</code> or <code>null</code>. | ||
The above values can allow any Peer B to send requests to the misconfigured Peer A on behalf of the user. | ||
</p> | ||
<p> | ||
Example scenario: | ||
User is client of a bank that has its API misconfigured to accept CORS requests from any domain. | ||
When the user loads an evil page, the evil page sends a request to the bank's API to transfer all funds | ||
to evil party's account. | ||
Given that the user was already logged in to the bank website, and had its session cookies set, | ||
the evil party's request succeeds. | ||
</p> | ||
</overview> | ||
<recommendation> | ||
<p> | ||
When configuring CORS that allow credentials passing, | ||
it's best not to use user-provided values for the allowed origins response header, | ||
especially if the cookies grant session permissions on the user's account. | ||
</p> | ||
<p> | ||
It also can be very dangerous to set the allowed origins to <code>null</code> (which can be bypassed). | ||
</p> | ||
</recommendation> | ||
<example> | ||
<p> | ||
The first example shows a possible CORS misconfiguration case: | ||
</p> | ||
<sample src="CorsMisconfigurationMiddlewareBad.py"/> | ||
<p> | ||
The second example shows a better configuration: | ||
</p> | ||
<sample src="CorsMisconfigurationMiddlewareGood.py"/> | ||
</example> | ||
<references> | ||
<li> | ||
Reference 1: <a href="https://portswigger.net/web-security/cors">PortSwigger Web Security Academy on CORS</a>. | ||
</li> | ||
<li> | ||
Reference 2: <a href="https://www.youtube.com/watch?v=wgkj4ZgxI4c">AppSec EU 2017 Exploiting CORS Misconfigurations For Bitcoins And Bounties by James Kettle</a>. | ||
</li> | ||
</references> | ||
</qhelp> |
39 changes: 39 additions & 0 deletions
39
python/ql/src/experimental/Security/CWE-942/CorsMisconfigurationMiddleware.ql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* @name Cors misconfiguration with credentials | ||
* @description Disabling or weakening SOP protection may make the application | ||
* vulnerable to a CORS attack. | ||
* @kind problem | ||
* @problem.severity warning | ||
* @security-severity 8.8 | ||
* @precision high | ||
* @id py/cors-misconfiguration-with-credentials | ||
* @tags security | ||
* external/cwe/cwe-942 | ||
*/ | ||
|
||
import python | ||
import semmle.python.Concepts | ||
private import semmle.python.dataflow.new.DataFlow | ||
|
||
predicate containsStar(DataFlow::Node array) { | ||
array.asExpr() instanceof List and | ||
array.asExpr().getASubExpression().(StringLiteral).getText() in ["*", "null"] | ||
or | ||
array.asExpr().(StringLiteral).getText() in ["*", "null"] | ||
} | ||
|
||
predicate isCorsMiddleware(Http::Server::CorsMiddleware middleware) { | ||
middleware.getMiddlewareName() = "CORSMiddleware" | ||
} | ||
|
||
predicate credentialsAllowed(Http::Server::CorsMiddleware middleware) { | ||
middleware.getCredentialsAllowed().asExpr() instanceof True | ||
} | ||
|
||
from Http::Server::CorsMiddleware a | ||
where | ||
credentialsAllowed(a) and | ||
containsStar(a.getOrigins().getALocalSource()) and | ||
isCorsMiddleware(a) | ||
select a, | ||
"This CORS middleware uses a vulnerable configuration that allows arbitrary websites to make authenticated cross-site requests" |
21 changes: 21 additions & 0 deletions
21
python/ql/src/experimental/Security/CWE-942/CorsMisconfigurationMiddlewareBad.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from fastapi import FastAPI | ||
from fastapi.middleware.cors import CORSMiddleware | ||
|
||
app = FastAPI() | ||
|
||
origins = [ | ||
"*" | ||
] | ||
|
||
app.add_middleware( | ||
CORSMiddleware, | ||
allow_origins=origins, | ||
allow_credentials=True, | ||
allow_methods=["*"], | ||
allow_headers=["*"], | ||
) | ||
|
||
|
||
@app.get("/") | ||
async def main(): | ||
return {"message": "Hello World"} |
24 changes: 24 additions & 0 deletions
24
python/ql/src/experimental/Security/CWE-942/CorsMisconfigurationMiddlewareGood.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from fastapi import FastAPI | ||
from fastapi.middleware.cors import CORSMiddleware | ||
|
||
app = FastAPI() | ||
|
||
origins = [ | ||
"http://localhost.tiangolo.com", | ||
"https://localhost.tiangolo.com", | ||
"http://localhost", | ||
"http://localhost:8080", | ||
] | ||
|
||
app.add_middleware( | ||
CORSMiddleware, | ||
allow_origins=origins, | ||
allow_credentials=True, | ||
allow_methods=["*"], | ||
allow_headers=["*"], | ||
) | ||
|
||
|
||
@app.get("/") | ||
async def main(): | ||
return {"message": "Hello World"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
python/ql/test/library-tests/frameworks/fastapi/middleware.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from fastapi import FastAPI | ||
from fastapi.middleware.cors import CORSMiddleware | ||
|
||
app = FastAPI() | ||
|
||
origins = [ | ||
"*" | ||
] | ||
|
||
app.add_middleware(CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"]) # $ CorsMiddleware=CORSMiddleware |
Oops, something went wrong.