зеркало из https://github.com/github/codeql.git
Python: Add SSRF queries
I've added 2 queries: - one that detects full SSRF, where an attacker can control the full URL, which is always bad - and one for partial SSRF, where an attacker can control parts of an URL (such as the path, query parameters, or fragment), which is not a big problem in many cases (but might still be exploitable) full SSRF should run by default, and partial SSRF should not (but makes it easy to see the other results). Some elements of the full SSRF queries needs a bit more polishing, like being able to detect `"https://" + user_input` is in fact controlling the full URL.
This commit is contained in:
Родитель
579de0c3f0
Коммит
1cc5e54357
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* Provides a taint-tracking configuration for detecting "Server-side request forgery" vulnerabilities.
|
||||
*
|
||||
* Note, for performance reasons: only import this file if
|
||||
* `ServerSideRequestForgery::Configuration` is needed, otherwise
|
||||
* `ServerSideRequestForgeryCustomizations` should be imported instead.
|
||||
*/
|
||||
|
||||
private import python
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import semmle.python.dataflow.new.TaintTracking
|
||||
|
||||
/**
|
||||
* Provides a taint-tracking configuration for detecting "Server-side request forgery" vulnerabilities.
|
||||
*
|
||||
* This configuration has a sanitizer to limit results to cases where attacker has full control of URL.
|
||||
* See `PartialServerSideRequestForgery` for a variant without this requirement.
|
||||
*/
|
||||
module FullServerSideRequestForgery {
|
||||
import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for detecting "Server-side request forgery" vulnerabilities.
|
||||
*/
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "FullServerSideRequestForgery" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
node instanceof Sanitizer
|
||||
or
|
||||
node instanceof FullUrlControlSanitizer
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
|
||||
guard instanceof SanitizerGuard
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a taint-tracking configuration for detecting "Server-side request forgery" vulnerabilities.
|
||||
*
|
||||
* This configuration has results, even when the attacker does not have full control over the URL.
|
||||
* See `FullServerSideRequestForgery` for variant that has this requirement.
|
||||
*/
|
||||
module PartialServerSideRequestForgery {
|
||||
import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for detecting "Server-side request forgery" vulnerabilities.
|
||||
*/
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "PartialServerSideRequestForgery" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
|
||||
guard instanceof SanitizerGuard
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
* "Server-side request forgery"
|
||||
* vulnerabilities, as well as extension points for adding your own.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.dataflow.new.BarrierGuards
|
||||
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
* "Server-side request forgery"
|
||||
* vulnerabilities, as well as extension points for adding your own.
|
||||
*/
|
||||
module ServerSideRequestForgery {
|
||||
/**
|
||||
* A data flow source for "Server-side request forgery" vulnerabilities.
|
||||
*/
|
||||
abstract class Source extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A data flow sink for "Server-side request forgery" vulnerabilities.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer for "Server-side request forgery" vulnerabilities.
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer for "Server-side request forgery" vulnerabilities,
|
||||
* that ensures the attacker does not have full control of the URL. (that is, might
|
||||
* still be able to control path or query parameters).
|
||||
*/
|
||||
abstract class FullUrlControlSanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer guard for "Server-side request forgery" vulnerabilities.
|
||||
*/
|
||||
abstract class SanitizerGuard extends DataFlow::BarrierGuard { }
|
||||
|
||||
/**
|
||||
* A source of remote user input, considered as a flow source.
|
||||
*/
|
||||
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
|
||||
|
||||
/** The URL of an HTTP request, considered as a sink. */
|
||||
class HttpRequestUrlAsSink extends Sink {
|
||||
HttpRequestUrlAsSink() {
|
||||
exists(HTTP::Client::Request req | req.getAUrlPart() = this) and
|
||||
// Since we find sinks inside stdlib, we need to exclude them manually. See
|
||||
// comment for command injection sinks for more details.
|
||||
not this.getScope().getEnclosingModule().getName() in ["http.client", "httplib"]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A comparison with a constant string, considered as a sanitizer-guard.
|
||||
*/
|
||||
class StringConstCompareAsSanitizerGuard extends SanitizerGuard, StringConstCompare { }
|
||||
|
||||
/**
|
||||
* A string construction (concat, format, f-string) where the left side is not
|
||||
* user-controlled.
|
||||
*/
|
||||
class StringConstructioneAsFullUrlControlSanitizer extends FullUrlControlSanitizer {
|
||||
StringConstructioneAsFullUrlControlSanitizer() {
|
||||
// string concat
|
||||
exists(BinaryExprNode add |
|
||||
add.getOp() instanceof Add and
|
||||
add.getRight() = this.asCfgNode()
|
||||
)
|
||||
or
|
||||
// % formatting
|
||||
exists(BinaryExprNode fmt |
|
||||
fmt.getOp() instanceof Mod and
|
||||
fmt.getRight() = this.asCfgNode()
|
||||
)
|
||||
or
|
||||
// arguments to a format call
|
||||
exists(DataFlow::MethodCallNode call |
|
||||
call.getMethodName() = "format" and
|
||||
this in [call.getArg(_), call.getArgByName(_)]
|
||||
)
|
||||
or
|
||||
// f-string
|
||||
exists(Fstring fstring | fstring.getValue(any(int i | i > 0)) = this.asExpr())
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* @name Full server-side request forgery
|
||||
* @description Making a network request to a URL that is fully user-controlled allows for request forgery attacks.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @security-severity 9.1
|
||||
* @precision high
|
||||
* @id py/full-ssrf
|
||||
* @tags security
|
||||
* external/cwe/cwe-918
|
||||
*/
|
||||
|
||||
import python
|
||||
import semmle.python.security.dataflow.ServerSideRequestForgery
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from
|
||||
FullServerSideRequestForgery::Configuration config, DataFlow::PathNode source,
|
||||
DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "The full URL of this request depends on $@.",
|
||||
source.getNode(), "a user-provided value"
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* @name Partial server-side request forgery
|
||||
* @description Making a network request to a URL that is partially user-controlled allows for request forgery attacks.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @security-severity 9.1
|
||||
* @precision medium
|
||||
* @id py/partial-ssrf
|
||||
* @tags security
|
||||
* external/cwe/cwe-918
|
||||
*/
|
||||
|
||||
import python
|
||||
import semmle.python.security.dataflow.ServerSideRequestForgery
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from
|
||||
FullServerSideRequestForgery::Configuration fullConfig,
|
||||
PartialServerSideRequestForgery::Configuration partialConfig, DataFlow::PathNode source,
|
||||
DataFlow::PathNode sink
|
||||
where
|
||||
partialConfig.hasFlowPath(source, sink) and
|
||||
not fullConfig.hasFlow(source.getNode(), sink.getNode())
|
||||
select sink.getNode(), source, sink, "Part of the URL of this request depends on $@.",
|
||||
source.getNode(), "a user-provided value"
|
|
@ -0,0 +1,147 @@
|
|||
edges
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:8:17:8:23 | ControlFlowNode for request |
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:8:17:8:28 | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:13:18:13:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:19:18:19:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:23:18:23:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:28:18:28:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:31:18:31:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:34:18:34:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:39:18:39:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:42:18:42:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:44:38:44:58 | ControlFlowNode for Tuple |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:50:18:50:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:53:18:53:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:56:18:56:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:8:17:8:23 | ControlFlowNode for request | full_partial_test.py:8:17:8:28 | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:8:17:8:28 | ControlFlowNode for Attribute | full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript | full_partial_test.py:23:18:23:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript | full_partial_test.py:34:18:34:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript | full_partial_test.py:44:38:44:58 | ControlFlowNode for Tuple |
|
||||
| full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript | full_partial_test.py:56:18:56:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:44:38:44:58 | ControlFlowNode for Tuple | full_partial_test.py:45:18:45:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:24 | ControlFlowNode for request | full_partial_test.py:60:18:60:29 | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:60:18:60:29 | ControlFlowNode for Attribute | full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:63:18:63:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:66:18:66:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:69:18:69:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:72:18:72:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:78:18:78:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:81:18:81:20 | ControlFlowNode for url |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:19:10:25 | ControlFlowNode for request |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:19:10:25 | ControlFlowNode for request |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:11:18:11:24 | ControlFlowNode for request |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | test_http_client.py:17:27:17:37 | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | test_http_client.py:17:27:17:37 | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:11:18:11:24 | ControlFlowNode for request |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute | test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute | test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:11:18:11:24 | ControlFlowNode for request | test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute | test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | test_http_client.py:25:25:25:28 | ControlFlowNode for path |
|
||||
| test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | test_http_client.py:29:25:29:28 | ControlFlowNode for path |
|
||||
| test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute |
|
||||
| test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute |
|
||||
| test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | test_requests.py:6:18:6:48 | ControlFlowNode for Subscript |
|
||||
| test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | test_requests.py:6:18:6:48 | ControlFlowNode for Subscript |
|
||||
| test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | test_requests.py:8:18:8:27 | ControlFlowNode for user_input |
|
||||
| test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | test_requests.py:8:18:8:27 | ControlFlowNode for user_input |
|
||||
nodes
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:8:17:8:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| full_partial_test.py:8:17:8:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input |
|
||||
| full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input |
|
||||
| full_partial_test.py:13:18:13:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:19:18:19:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:23:18:23:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:28:18:28:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:31:18:31:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:34:18:34:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:39:18:39:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:42:18:42:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:44:38:44:58 | ControlFlowNode for Tuple | semmle.label | ControlFlowNode for Tuple |
|
||||
| full_partial_test.py:45:18:45:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:50:18:50:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:53:18:53:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:56:18:56:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| full_partial_test.py:60:18:60:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:63:18:63:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:66:18:66:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:69:18:69:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:72:18:72:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:78:18:78:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:81:18:81:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:17:27:17:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:17:27:17:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:25:25:25:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
|
||||
| test_http_client.py:29:25:29:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
|
||||
| test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input |
|
||||
| test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input |
|
||||
subpaths
|
||||
#select
|
||||
| full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | The full URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | The full URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:10:19:10:25 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:17:27:17:37 | ControlFlowNode for unsafe_host | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:17:27:17:37 | ControlFlowNode for unsafe_host | The full URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:10:19:10:25 | ControlFlowNode for request | a user-provided value |
|
||||
| test_requests.py:8:18:8:27 | ControlFlowNode for user_input | test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | The full URL of this request depends on $@. | test_requests.py:6:18:6:24 | ControlFlowNode for request | a user-provided value |
|
|
@ -0,0 +1 @@
|
|||
Security/CWE-918/FullServerSideRequestForgery.ql
|
|
@ -0,0 +1,167 @@
|
|||
edges
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:8:17:8:23 | ControlFlowNode for request |
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:8:17:8:28 | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:13:18:13:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:19:18:19:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:23:18:23:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:28:18:28:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:31:18:31:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:34:18:34:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:39:18:39:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:42:18:42:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:44:38:44:58 | ControlFlowNode for Tuple |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:50:18:50:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:53:18:53:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | full_partial_test.py:56:18:56:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:8:17:8:23 | ControlFlowNode for request | full_partial_test.py:8:17:8:28 | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:8:17:8:28 | ControlFlowNode for Attribute | full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript | full_partial_test.py:23:18:23:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript | full_partial_test.py:34:18:34:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript | full_partial_test.py:44:38:44:58 | ControlFlowNode for Tuple |
|
||||
| full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript | full_partial_test.py:56:18:56:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:44:38:44:58 | ControlFlowNode for Tuple | full_partial_test.py:45:18:45:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:24 | ControlFlowNode for request | full_partial_test.py:60:18:60:29 | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:60:18:60:29 | ControlFlowNode for Attribute | full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:63:18:63:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:66:18:66:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:69:18:69:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:72:18:72:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:78:18:78:20 | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | full_partial_test.py:81:18:81:20 | ControlFlowNode for url |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:19:10:25 | ControlFlowNode for request |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:19:10:25 | ControlFlowNode for request |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:11:18:11:24 | ControlFlowNode for request |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | test_http_client.py:17:27:17:37 | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | test_http_client.py:17:27:17:37 | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:11:18:11:24 | ControlFlowNode for request |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute | test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute | test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:11:18:11:24 | ControlFlowNode for request | test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute | test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | test_http_client.py:25:25:25:28 | ControlFlowNode for path |
|
||||
| test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | test_http_client.py:29:25:29:28 | ControlFlowNode for path |
|
||||
| test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute |
|
||||
| test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute |
|
||||
| test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | test_requests.py:6:18:6:48 | ControlFlowNode for Subscript |
|
||||
| test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | test_requests.py:6:18:6:48 | ControlFlowNode for Subscript |
|
||||
| test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | test_requests.py:8:18:8:27 | ControlFlowNode for user_input |
|
||||
| test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | test_requests.py:8:18:8:27 | ControlFlowNode for user_input |
|
||||
nodes
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:7:18:7:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:8:17:8:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| full_partial_test.py:8:17:8:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:8:17:8:41 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input |
|
||||
| full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input |
|
||||
| full_partial_test.py:13:18:13:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:19:18:19:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:23:18:23:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:28:18:28:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:31:18:31:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:34:18:34:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:39:18:39:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:42:18:42:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:44:38:44:58 | ControlFlowNode for Tuple | semmle.label | ControlFlowNode for Tuple |
|
||||
| full_partial_test.py:45:18:45:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:50:18:50:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:53:18:53:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:56:18:56:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:60:18:60:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| full_partial_test.py:60:18:60:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| full_partial_test.py:60:18:60:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| full_partial_test.py:63:18:63:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:66:18:66:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:69:18:69:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:72:18:72:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:78:18:78:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| full_partial_test.py:81:18:81:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:9:19:9:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_http_client.py:10:19:10:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:10:19:10:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:17:27:17:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:17:27:17:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host |
|
||||
| test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:21:25:21:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path |
|
||||
| test_http_client.py:25:25:25:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
|
||||
| test_http_client.py:29:25:29:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
|
||||
| test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input |
|
||||
| test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input |
|
||||
subpaths
|
||||
#select
|
||||
| full_partial_test.py:13:18:13:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:13:18:13:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:19:18:19:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:19:18:19:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:23:18:23:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:23:18:23:20 | ControlFlowNode for url | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:28:18:28:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:28:18:28:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:31:18:31:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:31:18:31:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:34:18:34:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:34:18:34:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:34:18:34:20 | ControlFlowNode for url | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | full_partial_test.py:34:18:34:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:39:18:39:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:39:18:39:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:42:18:42:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:42:18:42:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:45:18:45:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:45:18:45:20 | ControlFlowNode for url | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:50:18:50:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:50:18:50:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:53:18:53:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:53:18:53:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:56:18:56:20 | ControlFlowNode for url | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:56:18:56:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:56:18:56:20 | ControlFlowNode for url | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | full_partial_test.py:56:18:56:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:63:18:63:20 | ControlFlowNode for url | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | full_partial_test.py:63:18:63:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:66:18:66:20 | ControlFlowNode for url | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | full_partial_test.py:66:18:66:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:69:18:69:20 | ControlFlowNode for url | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | full_partial_test.py:69:18:69:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:72:18:72:20 | ControlFlowNode for url | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | full_partial_test.py:72:18:72:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:78:18:78:20 | ControlFlowNode for url | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | full_partial_test.py:78:18:78:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | a user-provided value |
|
||||
| full_partial_test.py:81:18:81:20 | ControlFlowNode for url | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | full_partial_test.py:81:18:81:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:60:18:60:24 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:25:25:25:28 | ControlFlowNode for path | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:25:25:25:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:25:25:25:28 | ControlFlowNode for path | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:25:25:25:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:10:19:10:25 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:25:25:25:28 | ControlFlowNode for path | test_http_client.py:11:18:11:24 | ControlFlowNode for request | test_http_client.py:25:25:25:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:11:18:11:24 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:29:25:29:28 | ControlFlowNode for path | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:29:25:29:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:29:25:29:28 | ControlFlowNode for path | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:29:25:29:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:10:19:10:25 | ControlFlowNode for request | a user-provided value |
|
||||
| test_http_client.py:29:25:29:28 | ControlFlowNode for path | test_http_client.py:11:18:11:24 | ControlFlowNode for request | test_http_client.py:29:25:29:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:11:18:11:24 | ControlFlowNode for request | a user-provided value |
|
|
@ -0,0 +1 @@
|
|||
Security/CWE-918/PartialServerSideRequestForgery.ql
|
|
@ -0,0 +1,81 @@
|
|||
from flask import request
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def full_ssrf():
|
||||
user_input = request.args['untrusted_input']
|
||||
query_val = request.args['query_val']
|
||||
|
||||
requests.get(user_input) # NOT OK -- user has full control
|
||||
|
||||
url = "https://" + user_input
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
# although the path `/foo` is added here, this can be circumvented such that the
|
||||
# final URL is `https://evil.com/#/foo" -- since the fragment (#) is not sent to the
|
||||
# server.
|
||||
url = "https://" + user_input + "/foo"
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
# this might seem like a dummy test, but it serves to check how our sanitizers work.
|
||||
url = "https://" + user_input + "/foo?key=" + query_val
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
|
||||
# using .format
|
||||
url = "https://{}".format(user_input)
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
url = "https://{}/foo".format(user_input)
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
url = "https://{}/foo?key={}".format(user_input, query_val)
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
|
||||
# using %-formatting
|
||||
url = "https://%s" % user_input
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
url = "https://%s/foo" % user_input
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
url = "https://%s/foo/key=%s" % (user_input, query_val)
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
|
||||
# using f-strings
|
||||
url = f"https://{user_input}"
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
url = f"https://{user_input}/foo"
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
url = f"https://{user_input}/foo?key={query_val}"
|
||||
requests.get(url) # NOT OK -- user has full control
|
||||
|
||||
|
||||
def partial_ssrf():
|
||||
user_input = request.args['untrusted_input']
|
||||
|
||||
url = "https://example.com/foo?" + user_input
|
||||
requests.get(url) # NOT OK -- user controls query parameters
|
||||
|
||||
url = "https://example.com/" + user_input
|
||||
requests.get(url) # NOT OK -- user controls path
|
||||
|
||||
url = "https://example.com/" + user_input
|
||||
requests.get(url) # NOT OK -- user controls path
|
||||
|
||||
url = "https://example.com/foo#{}".format(user_input)
|
||||
requests.get(url) # NOT OK -- user contollred fragment
|
||||
|
||||
# this is probably the least interesting one, since it's only the fragment that is
|
||||
# controlled
|
||||
|
||||
url = "https://example.com/foo#%s" % user_input
|
||||
requests.get(url) # NOT OK -- user contollred fragment
|
||||
|
||||
url = f"https://example.com/foo#{user_input}"
|
||||
requests.get(url) # NOT OK -- user only controlled fragment
|
|
@ -0,0 +1 @@
|
|||
semmle-extractor-options: --lang=3 --max-import-depth=1
|
|
@ -0,0 +1,29 @@
|
|||
from flask import Flask, request
|
||||
|
||||
from http.client import HTTPConnection
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/ssrf_test") # $ routeSetup="/ssrf_test"
|
||||
def ssrf_test():
|
||||
unsafe_host = request.args["host"]
|
||||
unsafe_path = request.args["path"]
|
||||
user_input = request.args['untrusted_input']
|
||||
|
||||
conn = HTTPConnection(unsafe_host)
|
||||
conn.request("GET", unsafe_path) # NOT OK -- user has full control
|
||||
|
||||
# the rest are partial SSRF
|
||||
conn = HTTPConnection(unsafe_host)
|
||||
conn.request("GET", "/foo") # NOT OK -- user controlled domain
|
||||
|
||||
conn = HTTPConnection("example.com")
|
||||
conn.request("GET", unsafe_path) # NOT OK -- user controlled path
|
||||
|
||||
path = "foo?" + user_input
|
||||
conn = HTTPConnection("example.com")
|
||||
conn.request("GET", path) # NOT OK -- user controlled query parameters
|
||||
|
||||
path = "foo#" + user_input
|
||||
conn = HTTPConnection("example.com")
|
||||
conn.request("GET", path) # NOT OK -- user controlled fragment
|
|
@ -0,0 +1,11 @@
|
|||
from flask import request
|
||||
|
||||
import requests
|
||||
|
||||
def ssrf_test():
|
||||
user_input = request.args['untrusted_input']
|
||||
|
||||
requests.get(user_input) # NOT OK -- user has full control
|
||||
|
||||
# since `requests`` always uses complete URLs, it's not interesting to test more of
|
||||
# the framework directly. See `full_partial_test.py` for different ways to do SSRF.
|
Загрузка…
Ссылка в новой задаче