Corrections

This commit is contained in:
Kevin Stubbings
2024-08-26 22:06:12 -07:00
parent 8bf8893307
commit 1db7865d49
5 changed files with 60 additions and 30 deletions

View File

@@ -1425,11 +1425,14 @@ module Http {
string middleware_name() { result = super.middleware_name() }
/**
* Gets the boolean value corresponding to if CORS credentials is enabled
* (`true`) or disabled (`false`) by this node.
* Gets the dataflow node corresponding to the allowed CORS origins
*/
DataFlow::Node allowed_origins() { result = super.allowed_origins() }
/**
* Gets the boolean value corresponding to if CORS credentials is enabled
* (`true`) or disabled (`false`) by this node.
*/
DataFlow::Node allowed_credentials() { result = super.allowed_credentials() }
}

View File

@@ -43,16 +43,30 @@ module FastApi {
* A call to `app.add_middleware` adding CORSMiddleware.
*/
class AddCorsMiddlewareCall extends Http::Server::CorsMiddleware::Range, AddMiddlewareCall {
/**
* Gets the string corresponding to the middleware
*/
override string middleware_name() { result = this.getArg(0).asExpr().(Name).toString() }
/**
* Gets the dataflow node corresponding to the allowed CORS origins
*/
override DataFlow::Node allowed_origins() { result = this.getArgByName("allow_origins") }
/**
* Gets the boolean value corresponding to if CORS credentials is enabled
* (`true`) or disabled (`false`) by this node.
*/
override DataFlow::Node allowed_credentials() {
result = this.getArgByName("allow_credentials")
}
/**
* Gets the dataflow node corresponding to the allowed CORS methods
*/
DataFlow::Node allowed_methods() { result = this.getArgByName("allow_methods") }
/**
* Gets the dataflow node corresponding to the allowed CORS headers
*/
DataFlow::Node allowed_headers() { result = this.getArgByName("allow_headers") }
}

View File

@@ -28,12 +28,13 @@ module Starlette {
/**
* Provides models for the `starlette.app` class
*
* See https://www.starlette.io/websockets/.
*
*/
module App {
/** Gets import of `starlette.app`. */
API::Node cls() { result = API::moduleImport("starlette").getMember("app") }
/** Gets a reference to a FastAPI application (an instance of `fastapi.FastAPI`). */
/** Gets a reference to a Starlette application (an instance of `starlette.app`). */
API::Node instance() { result = cls().getReturn() }
}
@@ -52,6 +53,10 @@ module Starlette {
* A call to any of the execute methods on a `app.add_middleware` with CORSMiddleware.
*/
class AddCorsMiddlewareCall extends AddMiddlewareCall, Http::Server::CorsMiddleware::Range {
/**
* Gets the string corresponding to the middleware
*/
override string middleware_name() { result = this.getArg(0).asExpr().(Name).toString() }
override DataFlow::Node allowed_origins() { result = this.getArgByName("allow_origins") }
@@ -59,9 +64,14 @@ module Starlette {
override DataFlow::Node allowed_credentials() {
result = this.getArgByName("allow_credentials")
}
/**
* Gets the dataflow node corresponding to the allowed CORS methods
*/
DataFlow::Node allowed_methods() { result = this.getArgByName("allow_methods") }
/**
* Gets the dataflow node corresponding to the allowed CORS headers
*/
DataFlow::Node allowed_headers() { result = this.getArgByName("allow_headers") }
}

View File

@@ -4,7 +4,7 @@
<qhelp>
<overview>
<p>
Web browsers, by default, disallow cross-origin resource sharing via direct HTTP requests (i.e. using a JavaScript HTTP client).
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").

View File

@@ -11,26 +11,29 @@
* external/cwe/cwe-352
*/
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().matches("*")) or
(array.asExpr().(StringLiteral).getText().matches(["*", "null"]))
import python
import semmle.python.Concepts
private import semmle.python.dataflow.new.DataFlow
}
predicate isCorsMiddleware(Http::Server::CorsMiddleware middleware){
middleware.middleware_name().matches("CORSMiddleware")
}
predicate credentialsAllowed(Http::Server::CorsMiddleware middleware){
middleware.allowed_credentials().asExpr() instanceof True
}
from Http::Server::CorsMiddleware a
where credentialsAllowed(a) and
containsStar(a.allowed_origins().getALocalSource()) and
isCorsMiddleware(a)
select a, "This CORS middleware uses a vulnerable configuration that leaves it open to attacks from arbitrary websites"
predicate containsStar(DataFlow::Node array) {
array.asExpr() instanceof List and
array.asExpr().getASubExpression().(StringLiteral).getText() = ["*", "null"]
or
array.asExpr().(StringLiteral).getText() = ["*", "null"]
}
predicate isCorsMiddleware(Http::Server::CorsMiddleware middleware) {
middleware.middleware_name().matches("CORSMiddleware")
}
predicate credentialsAllowed(Http::Server::CorsMiddleware middleware) {
middleware.allowed_credentials().asExpr() instanceof True
}
from Http::Server::CorsMiddleware a
where
credentialsAllowed(a) and
containsStar(a.allowed_origins().getALocalSource()) and
isCorsMiddleware(a)
select a,
"This CORS middleware uses a vulnerable configuration that leaves it open to attacks from arbitrary websites"