mirror of
https://github.com/github/codeql.git
synced 2026-04-26 17:25:19 +02:00
JS: Port ClientSideRequestForgery
This commit is contained in:
@@ -14,7 +14,34 @@ import RequestForgeryCustomizations::RequestForgery
|
||||
/**
|
||||
* A taint tracking configuration for client-side request forgery.
|
||||
*/
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
module ClientSideRequestForgeryConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(Source src |
|
||||
source = src and
|
||||
not src.isServerSide()
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate isBarrierOut(DataFlow::Node node) { sanitizingPrefixEdge(node, _) }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
isAdditionalRequestForgeryStep(pred, succ)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Taint tracking for client-side request forgery.
|
||||
*/
|
||||
module ClientSideRequestForgeryFlow = TaintTracking::Global<ClientSideRequestForgeryConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `ClientSideRequestForgeryFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ClientSideRequestForgery" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
|
||||
@@ -13,11 +13,13 @@
|
||||
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.ClientSideRequestForgeryQuery
|
||||
import DataFlow::PathGraph
|
||||
import ClientSideRequestForgeryFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node request
|
||||
from
|
||||
ClientSideRequestForgeryFlow::PathNode source, ClientSideRequestForgeryFlow::PathNode sink,
|
||||
DataFlow::Node request
|
||||
where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
ClientSideRequestForgeryFlow::flowPath(source, sink) and
|
||||
request = sink.getNode().(Sink).getARequest()
|
||||
select request, source, sink, "The $@ of this request depends on a $@.", sink.getNode(),
|
||||
sink.getNode().(Sink).getKind(), source, "user-provided value"
|
||||
|
||||
@@ -1,50 +1,34 @@
|
||||
nodes
|
||||
| clientSide.js:11:11:11:53 | query |
|
||||
| clientSide.js:11:19:11:40 | window. ... .search |
|
||||
| clientSide.js:11:19:11:40 | window. ... .search |
|
||||
| clientSide.js:11:19:11:53 | window. ... ring(1) |
|
||||
| clientSide.js:12:13:12:54 | 'https: ... + '/id' |
|
||||
| clientSide.js:12:13:12:54 | 'https: ... + '/id' |
|
||||
| clientSide.js:12:42:12:46 | query |
|
||||
| clientSide.js:14:13:14:63 | 'https: ... .search |
|
||||
| clientSide.js:14:13:14:63 | 'https: ... .search |
|
||||
| clientSide.js:14:42:14:63 | window. ... .search |
|
||||
| clientSide.js:14:42:14:63 | window. ... .search |
|
||||
| clientSide.js:16:11:16:54 | fragment |
|
||||
| clientSide.js:16:22:16:41 | window.location.hash |
|
||||
| clientSide.js:16:22:16:41 | window.location.hash |
|
||||
| clientSide.js:16:22:16:54 | window. ... ring(1) |
|
||||
| clientSide.js:17:13:17:57 | 'https: ... + '/id' |
|
||||
| clientSide.js:17:13:17:57 | 'https: ... + '/id' |
|
||||
| clientSide.js:17:42:17:49 | fragment |
|
||||
| clientSide.js:20:11:20:28 | name |
|
||||
| clientSide.js:20:18:20:28 | window.name |
|
||||
| clientSide.js:20:18:20:28 | window.name |
|
||||
| clientSide.js:21:13:21:53 | 'https: ... + '/id' |
|
||||
| clientSide.js:21:13:21:53 | 'https: ... + '/id' |
|
||||
| clientSide.js:21:42:21:45 | name |
|
||||
edges
|
||||
| clientSide.js:11:11:11:53 | query | clientSide.js:12:42:12:46 | query |
|
||||
| clientSide.js:11:19:11:40 | window. ... .search | clientSide.js:11:19:11:53 | window. ... ring(1) |
|
||||
| clientSide.js:11:19:11:40 | window. ... .search | clientSide.js:11:19:11:53 | window. ... ring(1) |
|
||||
| clientSide.js:11:19:11:53 | window. ... ring(1) | clientSide.js:11:11:11:53 | query |
|
||||
| clientSide.js:12:42:12:46 | query | clientSide.js:12:13:12:54 | 'https: ... + '/id' |
|
||||
| clientSide.js:12:42:12:46 | query | clientSide.js:12:13:12:54 | 'https: ... + '/id' |
|
||||
| clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search |
|
||||
| clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search |
|
||||
| clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search |
|
||||
| clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search |
|
||||
| clientSide.js:16:11:16:54 | fragment | clientSide.js:17:42:17:49 | fragment |
|
||||
| clientSide.js:16:22:16:41 | window.location.hash | clientSide.js:16:22:16:54 | window. ... ring(1) |
|
||||
| clientSide.js:16:22:16:41 | window.location.hash | clientSide.js:16:22:16:54 | window. ... ring(1) |
|
||||
| clientSide.js:16:22:16:54 | window. ... ring(1) | clientSide.js:16:11:16:54 | fragment |
|
||||
| clientSide.js:17:42:17:49 | fragment | clientSide.js:17:13:17:57 | 'https: ... + '/id' |
|
||||
| clientSide.js:17:42:17:49 | fragment | clientSide.js:17:13:17:57 | 'https: ... + '/id' |
|
||||
| clientSide.js:20:11:20:28 | name | clientSide.js:21:42:21:45 | name |
|
||||
| clientSide.js:20:18:20:28 | window.name | clientSide.js:20:11:20:28 | name |
|
||||
| clientSide.js:20:18:20:28 | window.name | clientSide.js:20:11:20:28 | name |
|
||||
| clientSide.js:21:42:21:45 | name | clientSide.js:21:13:21:53 | 'https: ... + '/id' |
|
||||
| clientSide.js:21:42:21:45 | name | clientSide.js:21:13:21:53 | 'https: ... + '/id' |
|
||||
nodes
|
||||
| clientSide.js:11:11:11:53 | query | semmle.label | query |
|
||||
| clientSide.js:11:19:11:40 | window. ... .search | semmle.label | window. ... .search |
|
||||
| clientSide.js:11:19:11:53 | window. ... ring(1) | semmle.label | window. ... ring(1) |
|
||||
| clientSide.js:12:13:12:54 | 'https: ... + '/id' | semmle.label | 'https: ... + '/id' |
|
||||
| clientSide.js:12:42:12:46 | query | semmle.label | query |
|
||||
| clientSide.js:14:13:14:63 | 'https: ... .search | semmle.label | 'https: ... .search |
|
||||
| clientSide.js:14:42:14:63 | window. ... .search | semmle.label | window. ... .search |
|
||||
| clientSide.js:16:11:16:54 | fragment | semmle.label | fragment |
|
||||
| clientSide.js:16:22:16:41 | window.location.hash | semmle.label | window.location.hash |
|
||||
| clientSide.js:16:22:16:54 | window. ... ring(1) | semmle.label | window. ... ring(1) |
|
||||
| clientSide.js:17:13:17:57 | 'https: ... + '/id' | semmle.label | 'https: ... + '/id' |
|
||||
| clientSide.js:17:42:17:49 | fragment | semmle.label | fragment |
|
||||
| clientSide.js:20:11:20:28 | name | semmle.label | name |
|
||||
| clientSide.js:20:18:20:28 | window.name | semmle.label | window.name |
|
||||
| clientSide.js:21:13:21:53 | 'https: ... + '/id' | semmle.label | 'https: ... + '/id' |
|
||||
| clientSide.js:21:42:21:45 | name | semmle.label | name |
|
||||
subpaths
|
||||
#select
|
||||
| clientSide.js:12:5:12:55 | request ... '/id') | clientSide.js:11:19:11:40 | window. ... .search | clientSide.js:12:13:12:54 | 'https: ... + '/id' | The $@ of this request depends on a $@. | clientSide.js:12:13:12:54 | 'https: ... + '/id' | URL | clientSide.js:11:19:11:40 | window. ... .search | user-provided value |
|
||||
| clientSide.js:14:5:14:64 | request ... search) | clientSide.js:14:42:14:63 | window. ... .search | clientSide.js:14:13:14:63 | 'https: ... .search | The $@ of this request depends on a $@. | clientSide.js:14:13:14:63 | 'https: ... .search | URL | clientSide.js:14:42:14:63 | window. ... .search | user-provided value |
|
||||
|
||||
@@ -4,14 +4,22 @@ import semmle.javascript.security.dataflow.ClientSideRequestForgeryQuery as Clie
|
||||
import testUtilities.ConsistencyChecking
|
||||
|
||||
query predicate resultInWrongFile(DataFlow::Node node) {
|
||||
exists(DataFlow::Configuration cfg, string filePattern |
|
||||
cfg instanceof RequestForgery::Configuration and
|
||||
exists(string filePattern |
|
||||
RequestForgery::RequestForgeryFlow::flowTo(node) and
|
||||
filePattern = ".*serverSide.*"
|
||||
or
|
||||
cfg instanceof ClientSideRequestForgery::Configuration and
|
||||
ClientSideRequestForgery::ClientSideRequestForgeryFlow::flowTo(node) and
|
||||
filePattern = ".*clientSide.*"
|
||||
|
|
||||
cfg.hasFlow(_, node) and
|
||||
not node.getFile().getRelativePath().regexpMatch(filePattern)
|
||||
)
|
||||
}
|
||||
|
||||
class Consistency extends ConsistencyConfiguration {
|
||||
Consistency() { this = "Consistency" }
|
||||
|
||||
override DataFlow::Node getAnAlert() {
|
||||
RequestForgery::RequestForgeryFlow::flowTo(result) or
|
||||
ClientSideRequestForgery::ClientSideRequestForgeryFlow::flowTo(result)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user