From 67cc3a3935a05e0381ee8374c6cb5b1bc8621b31 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 25 Aug 2023 17:23:50 +0200 Subject: [PATCH] Python: Move experimental `ReflectedXSS` to new dataflow API --- .../experimental/Security/CWE-079/ReflectedXSS.ql | 6 +++--- .../python/security/dataflow/ReflectedXSS.qll | 15 ++++++++------- .../Security/CWE-079/ReflectedXSS.expected | 4 +++- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-079/ReflectedXSS.ql b/python/ql/src/experimental/Security/CWE-079/ReflectedXSS.ql index 468cef01f7d..1f5cc601c09 100644 --- a/python/ql/src/experimental/Security/CWE-079/ReflectedXSS.ql +++ b/python/ql/src/experimental/Security/CWE-079/ReflectedXSS.ql @@ -16,9 +16,9 @@ // determine precision above import python import experimental.semmle.python.security.dataflow.ReflectedXSS -import DataFlow::PathGraph +import ReflectedXSSFlow::PathGraph -from ReflectedXssConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +from ReflectedXSSFlow::PathNode source, ReflectedXSSFlow::PathNode sink +where ReflectedXSSFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.", source.getNode(), "a user-provided value" diff --git a/python/ql/src/experimental/semmle/python/security/dataflow/ReflectedXSS.qll b/python/ql/src/experimental/semmle/python/security/dataflow/ReflectedXSS.qll index b35cb405dc0..b12f54dedf8 100644 --- a/python/ql/src/experimental/semmle/python/security/dataflow/ReflectedXSS.qll +++ b/python/ql/src/experimental/semmle/python/security/dataflow/ReflectedXSS.qll @@ -16,20 +16,18 @@ import semmle.python.ApiGraphs * A taint-tracking configuration for detecting reflected server-side cross-site * scripting vulnerabilities. */ -class ReflectedXssConfiguration extends TaintTracking::Configuration { - ReflectedXssConfiguration() { this = "ReflectedXssConfiguration" } +private module ReflectedXSSConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSink(DataFlow::Node sink) { sink = any(EmailSender email).getHtmlBody() } - override predicate isSink(DataFlow::Node sink) { sink = any(EmailSender email).getHtmlBody() } - - override predicate isSanitizer(DataFlow::Node sanitizer) { + predicate isBarrier(DataFlow::Node sanitizer) { sanitizer = any(HtmlEscaping esc).getOutput() or sanitizer instanceof StringConstCompareBarrier } - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { exists(DataFlow::CallCfgNode htmlContentCall | htmlContentCall = API::moduleImport("sendgrid") @@ -42,3 +40,6 @@ class ReflectedXssConfiguration extends TaintTracking::Configuration { ) } } + +/** Global taint-tracking for detecting "TODO" vulnerabilities. */ +module ReflectedXSSFlow = TaintTracking::Global; diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.expected b/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.expected index 7f16b6dcdac..02fed5424cc 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.expected @@ -12,7 +12,8 @@ edges | sendgrid_mail.py:1:19:1:25 | GSSA Variable request | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | | sendgrid_mail.py:1:19:1:25 | GSSA Variable request | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | -| sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | +| sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | sendgrid_mail.py:26:34:26:61 | ControlFlowNode for Subscript | +| sendgrid_mail.py:26:34:26:61 | ControlFlowNode for Subscript | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | GSSA Variable request | | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | GSSA Variable request | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | @@ -52,6 +53,7 @@ nodes | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | semmle.label | ControlFlowNode for HtmlContent() | | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| sendgrid_mail.py:26:34:26:61 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |