JS: Port experimental CorsPermissiveConfiguration to ConfigSig

The tests show a new (source, sink) pair for an already-flagged sink.

Not sure why it was not flagged originally since the data flow path seems valid, given the steps provided by our models.
This commit is contained in:
Asger F
2024-11-28 11:46:56 +01:00
parent f5a6485ef2
commit 871bc3b84a
3 changed files with 56 additions and 51 deletions

View File

@@ -12,9 +12,10 @@
import javascript
import CorsPermissiveConfigurationQuery
import DataFlow::PathGraph
import CorsPermissiveConfigurationFlow::PathGraph
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
from
CorsPermissiveConfigurationFlow::PathNode source, CorsPermissiveConfigurationFlow::PathNode sink
where CorsPermissiveConfigurationFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "CORS Origin misconfiguration due to a $@.", source.getNode(),
"too permissive or user controlled value"

View File

@@ -14,10 +14,10 @@ import CorsPermissiveConfigurationCustomizations::CorsPermissiveConfiguration
/**
* A data flow configuration for overly permissive CORS configuration.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "CorsPermissiveConfiguration" }
module CorsPermissiveConfigurationConfig implements DataFlow::StateConfigSig {
class FlowState = DataFlow::FlowLabel;
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
source instanceof TrueNullValue and label = truenullLabel()
or
source instanceof WildcardValue and label = wildcardLabel()
@@ -25,15 +25,35 @@ class Configuration extends TaintTracking::Configuration {
source instanceof RemoteFlowSource and label = DataFlow::FlowLabel::taint()
}
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
sink instanceof CorsApolloServer and label = [DataFlow::FlowLabel::taint(), truenullLabel()]
or
sink instanceof ExpressCors and label = [DataFlow::FlowLabel::taint(), wildcardLabel()]
}
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}
module CorsPermissiveConfigurationFlow =
TaintTracking::GlobalWithState<CorsPermissiveConfigurationConfig>;
/**
* DEPRECATED. Use the `CorsPermissiveConfigurationFlow` module instead.
*/
deprecated class Configuration extends TaintTracking::Configuration {
Configuration() { this = "CorsPermissiveConfiguration" }
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
CorsPermissiveConfigurationConfig::isSource(source, label)
}
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
CorsPermissiveConfigurationConfig::isSink(sink, label)
}
override predicate isSanitizer(DataFlow::Node node) {
super.isSanitizer(node) or
node instanceof Sanitizer
CorsPermissiveConfigurationConfig::isBarrier(node)
}
}

View File

@@ -1,50 +1,34 @@
nodes
| apollo-test.js:8:9:8:59 | user_origin |
| apollo-test.js:8:23:8:46 | url.par ... , true) |
| apollo-test.js:8:23:8:52 | url.par ... ).query |
| apollo-test.js:8:23:8:59 | url.par ... .origin |
| apollo-test.js:8:33:8:39 | req.url |
| apollo-test.js:8:33:8:39 | req.url |
| apollo-test.js:11:25:11:28 | true |
| apollo-test.js:11:25:11:28 | true |
| apollo-test.js:11:25:11:28 | true |
| apollo-test.js:21:25:21:28 | null |
| apollo-test.js:21:25:21:28 | null |
| apollo-test.js:21:25:21:28 | null |
| apollo-test.js:26:25:26:35 | user_origin |
| apollo-test.js:26:25:26:35 | user_origin |
| express-test.js:10:9:10:59 | user_origin |
| express-test.js:10:23:10:46 | url.par ... , true) |
| express-test.js:10:23:10:52 | url.par ... ).query |
| express-test.js:10:23:10:59 | url.par ... .origin |
| express-test.js:10:33:10:39 | req.url |
| express-test.js:10:33:10:39 | req.url |
| express-test.js:26:17:26:19 | '*' |
| express-test.js:26:17:26:19 | '*' |
| express-test.js:26:17:26:19 | '*' |
| express-test.js:33:17:33:27 | user_origin |
| express-test.js:33:17:33:27 | user_origin |
edges
| apollo-test.js:8:9:8:59 | user_origin | apollo-test.js:26:25:26:35 | user_origin |
| apollo-test.js:8:9:8:59 | user_origin | apollo-test.js:26:25:26:35 | user_origin |
| apollo-test.js:8:23:8:46 | url.par ... , true) | apollo-test.js:8:23:8:52 | url.par ... ).query |
| apollo-test.js:8:23:8:52 | url.par ... ).query | apollo-test.js:8:23:8:59 | url.par ... .origin |
| apollo-test.js:8:23:8:59 | url.par ... .origin | apollo-test.js:8:9:8:59 | user_origin |
| apollo-test.js:8:33:8:39 | req.url | apollo-test.js:8:23:8:46 | url.par ... , true) |
| apollo-test.js:8:33:8:39 | req.url | apollo-test.js:8:23:8:46 | url.par ... , true) |
| apollo-test.js:11:25:11:28 | true | apollo-test.js:11:25:11:28 | true |
| apollo-test.js:21:25:21:28 | null | apollo-test.js:21:25:21:28 | null |
| express-test.js:10:9:10:59 | user_origin | express-test.js:33:17:33:27 | user_origin |
| express-test.js:10:9:10:59 | user_origin | express-test.js:33:17:33:27 | user_origin |
| express-test.js:10:23:10:46 | url.par ... , true) | express-test.js:10:23:10:52 | url.par ... ).query |
| express-test.js:10:23:10:52 | url.par ... ).query | express-test.js:10:23:10:59 | url.par ... .origin |
| express-test.js:10:23:10:59 | url.par ... .origin | express-test.js:10:9:10:59 | user_origin |
| express-test.js:10:33:10:39 | req.url | express-test.js:10:23:10:46 | url.par ... , true) |
| express-test.js:10:33:10:39 | req.url | express-test.js:10:23:10:46 | url.par ... , true) |
| express-test.js:26:17:26:19 | '*' | express-test.js:26:17:26:19 | '*' |
| apollo-test.js:8:9:8:59 | user_origin | apollo-test.js:26:25:26:35 | user_origin | provenance | |
| apollo-test.js:8:9:8:59 | user_origin | apollo-test.js:26:25:26:35 | user_origin | provenance | |
| apollo-test.js:8:23:8:46 | url.par ... , true) | apollo-test.js:8:9:8:59 | user_origin | provenance | |
| apollo-test.js:8:23:8:46 | url.par ... , true) | apollo-test.js:8:9:8:59 | user_origin | provenance | |
| apollo-test.js:8:33:8:39 | req.url | apollo-test.js:8:23:8:46 | url.par ... , true) | provenance | |
| apollo-test.js:8:42:8:45 | true | apollo-test.js:8:23:8:46 | url.par ... , true) | provenance | |
| express-test.js:10:9:10:59 | user_origin | express-test.js:33:17:33:27 | user_origin | provenance | |
| express-test.js:10:23:10:46 | url.par ... , true) | express-test.js:10:9:10:59 | user_origin | provenance | |
| express-test.js:10:33:10:39 | req.url | express-test.js:10:23:10:46 | url.par ... , true) | provenance | |
nodes
| apollo-test.js:8:9:8:59 | user_origin | semmle.label | user_origin |
| apollo-test.js:8:9:8:59 | user_origin | semmle.label | user_origin |
| apollo-test.js:8:23:8:46 | url.par ... , true) | semmle.label | url.par ... , true) |
| apollo-test.js:8:23:8:46 | url.par ... , true) | semmle.label | url.par ... , true) |
| apollo-test.js:8:33:8:39 | req.url | semmle.label | req.url |
| apollo-test.js:8:42:8:45 | true | semmle.label | true |
| apollo-test.js:11:25:11:28 | true | semmle.label | true |
| apollo-test.js:21:25:21:28 | null | semmle.label | null |
| apollo-test.js:26:25:26:35 | user_origin | semmle.label | user_origin |
| apollo-test.js:26:25:26:35 | user_origin | semmle.label | user_origin |
| express-test.js:10:9:10:59 | user_origin | semmle.label | user_origin |
| express-test.js:10:23:10:46 | url.par ... , true) | semmle.label | url.par ... , true) |
| express-test.js:10:33:10:39 | req.url | semmle.label | req.url |
| express-test.js:26:17:26:19 | '*' | semmle.label | '*' |
| express-test.js:33:17:33:27 | user_origin | semmle.label | user_origin |
subpaths
#select
| apollo-test.js:11:25:11:28 | true | apollo-test.js:11:25:11:28 | true | apollo-test.js:11:25:11:28 | true | CORS Origin misconfiguration due to a $@. | apollo-test.js:11:25:11:28 | true | too permissive or user controlled value |
| apollo-test.js:21:25:21:28 | null | apollo-test.js:21:25:21:28 | null | apollo-test.js:21:25:21:28 | null | CORS Origin misconfiguration due to a $@. | apollo-test.js:21:25:21:28 | null | too permissive or user controlled value |
| apollo-test.js:26:25:26:35 | user_origin | apollo-test.js:8:33:8:39 | req.url | apollo-test.js:26:25:26:35 | user_origin | CORS Origin misconfiguration due to a $@. | apollo-test.js:8:33:8:39 | req.url | too permissive or user controlled value |
| apollo-test.js:26:25:26:35 | user_origin | apollo-test.js:8:42:8:45 | true | apollo-test.js:26:25:26:35 | user_origin | CORS Origin misconfiguration due to a $@. | apollo-test.js:8:42:8:45 | true | too permissive or user controlled value |
| express-test.js:26:17:26:19 | '*' | express-test.js:26:17:26:19 | '*' | express-test.js:26:17:26:19 | '*' | CORS Origin misconfiguration due to a $@. | express-test.js:26:17:26:19 | '*' | too permissive or user controlled value |
| express-test.js:33:17:33:27 | user_origin | express-test.js:10:33:10:39 | req.url | express-test.js:33:17:33:27 | user_origin | CORS Origin misconfiguration due to a $@. | express-test.js:10:33:10:39 | req.url | too permissive or user controlled value |