From b95566b02ae1a87f90b5cebf01ecda2d7b66359e Mon Sep 17 00:00:00 2001 From: tyage Date: Thu, 29 Sep 2022 17:44:00 +0900 Subject: [PATCH 01/82] make json stringify tainted with arg's property --- .../javascript/dataflow/TaintTracking.qll | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 5147bcf7f2a..4b6a9d2fc16 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -716,11 +716,40 @@ module TaintTracking { */ private class JsonStringifyTaintStep extends SharedTaintStep { override predicate serializeStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(JsonStringifyCall call | - pred = call.getArgument(0) and + exists(JsonStringifyCall call, DataFlow::Node arg | + arg = call.getArgument(0) and + ( + pred = arg or + findInObject(arg.asExpr(), pred.asExpr()) + ) and succ = call ) } + + // find target in root object recursively + private predicate findInObject(Expr root, Expr target) { + // when root is Object + exists(ObjectExpr object, Property property, Expr propertyVal | + object = root and + property = object.getAProperty() and + propertyVal = property.getInit() and + ( + target = property.getNameExpr() or + target = propertyVal or + findInObject(propertyVal, target) + ) + ) + or + // when root is Array + exists(ArrayExpr array, Expr child | + array = root and + child = array.getAChildExpr() and + ( + target = child or + findInObject(child, target) + ) + ) + } } /** From 0cb8e121e97f6039554ad5e56fcbb8e28a0754a7 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 29 Sep 2022 17:41:21 +0200 Subject: [PATCH 02/82] Python: Fix flask request modeling This takes us part of the way. We still get multiple paths for the same alert, but that will be fixed in a different PR. --- python/ql/lib/semmle/python/frameworks/Flask.qll | 8 +------- .../src/change-notes/2022-09-29-flask-source-modeling.md | 4 ++++ 2 files changed, 5 insertions(+), 7 deletions(-) create mode 100644 python/ql/src/change-notes/2022-09-29-flask-source-modeling.md diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll index 2f272723182..a8291826577 100644 --- a/python/ql/lib/semmle/python/frameworks/Flask.qll +++ b/python/ql/lib/semmle/python/frameworks/Flask.qll @@ -354,13 +354,7 @@ module Flask { * See https://flask.palletsprojects.com/en/1.1.x/api/#flask.Request */ private class FlaskRequestSource extends RemoteFlowSource::Range { - FlaskRequestSource() { - this = request().getAValueReachableFromSource() and - not any(Import imp).contains(this.asExpr()) and - not exists(ControlFlowNode def | this.asVar().getSourceVariable().hasDefiningNode(def) | - any(Import imp).contains(def.getNode()) - ) - } + FlaskRequestSource() { this = request().asSource() } override string getSourceType() { result = "flask.request" } } diff --git a/python/ql/src/change-notes/2022-09-29-flask-source-modeling.md b/python/ql/src/change-notes/2022-09-29-flask-source-modeling.md new file mode 100644 index 00000000000..59774242825 --- /dev/null +++ b/python/ql/src/change-notes/2022-09-29-flask-source-modeling.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed how `flask.request` is modeled as a RemoteFlowSource, such that we show fewer duplicated alert messages for Code Scanning alerts. The import, such as `from flask import request`, will now be shown as the first step in a path explanation. From b01a0ae6969fafe4c0165909401d26ea80cf67b8 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Mon, 3 Oct 2022 20:35:49 +0200 Subject: [PATCH 03/82] Python: Adjust `.expected` after flask source change It's really hard to audit that this is all good.. I tried my best with `icdiff` though -- and there is a problem with ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql that needs to be fixed in the next commit --- .../Security/CWE-079/ReflectedXSS.expected | 62 +++++++++--- .../Security/CWE-113/HeaderInjection.expected | 17 +++- .../Security/CWE-1236/CsvInjection.expected | 13 ++- ...ientSuppliedIpUsedInSecurityCheck.expected | 8 -- .../CWE-522/LDAPInsecureAuth.expected | 8 +- .../Security/CWE-614/CookieInjection.expected | 33 ++++--- .../Security/CWE-943/NoSQLInjection.expected | 56 ++++++++--- .../UntrustedDataToExternalAPI.expected | 8 +- .../PathInjection.expected | 60 ++++++++---- .../CommandInjection.expected | 24 +++-- .../CommandInjection.expected | 39 +++++--- .../ReflectedXss.expected | 14 ++- .../LdapInjection.expected | 60 +++++++++--- .../CodeInjection.expected | 15 ++- .../LogInjection.expected | 17 +++- .../UnsafeDeserialization.expected | 14 ++- .../CWE-601-UrlRedirect/UrlRedirect.expected | 29 ++++-- .../Security/CWE-611-Xxe/Xxe.expected | 11 ++- .../XpathInjection.expected | 20 +++- .../PolynomialReDoS.expected | 10 +- .../RegexInjection.expected | 14 ++- .../Security/CWE-776-XmlBomb/XmlBomb.expected | 8 +- .../FullServerSideRequestForgery.expected | 95 +++++++++++++++---- .../PartialServerSideRequestForgery.expected | 85 +++++++++++++---- 24 files changed, 533 insertions(+), 187 deletions(-) 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 f787dfa43fc..77dafce4a10 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 @@ -1,4 +1,9 @@ edges +| flask_mail.py:0:0:0:0 | ModuleVariableNode for flask_mail.request | flask_mail.py:13:22:13:28 | ControlFlowNode for request | +| flask_mail.py:0:0:0:0 | ModuleVariableNode for flask_mail.request | flask_mail.py:18:14:18:20 | ControlFlowNode for request | +| flask_mail.py:0:0:0:0 | ModuleVariableNode for flask_mail.request | flask_mail.py:31:24:31:30 | ControlFlowNode for request | +| flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | flask_mail.py:1:19:1:25 | GSSA Variable request | +| flask_mail.py:1:19:1:25 | GSSA Variable request | flask_mail.py:0:0:0:0 | ModuleVariableNode for flask_mail.request | | flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:13:22:13:33 | ControlFlowNode for Attribute | | flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:18:14:18:25 | ControlFlowNode for Attribute | | flask_mail.py:13:22:13:33 | ControlFlowNode for Attribute | flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | @@ -6,6 +11,11 @@ edges | flask_mail.py:18:14:18:25 | ControlFlowNode for Attribute | flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | | flask_mail.py:31:24:31:30 | ControlFlowNode for request | flask_mail.py:31:24:31:35 | ControlFlowNode for Attribute | | flask_mail.py:31:24:31:35 | ControlFlowNode for Attribute | flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | +| sendgrid_mail.py:0:0:0:0 | ModuleVariableNode for sendgrid_mail.request | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | +| sendgrid_mail.py:0:0:0:0 | ModuleVariableNode for sendgrid_mail.request | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | +| sendgrid_mail.py:0:0:0:0 | ModuleVariableNode for sendgrid_mail.request | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | +| sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | sendgrid_mail.py:1:19:1:25 | GSSA Variable request | +| sendgrid_mail.py:1:19:1:25 | GSSA Variable request | sendgrid_mail.py:0:0:0:0 | ModuleVariableNode for sendgrid_mail.request | | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | sendgrid_mail.py:14:22:14:33 | ControlFlowNode for Attribute | | sendgrid_mail.py:14:22:14:33 | ControlFlowNode for Attribute | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | sendgrid_mail.py:26:34:26:45 | ControlFlowNode for Attribute | @@ -13,6 +23,11 @@ edges | 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:52 | ControlFlowNode for Attribute | | sendgrid_mail.py:37:41:37:52 | ControlFlowNode for Attribute | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | +| sendgrid_via_mail_send_post_request_body_bad.py:0:0:0:0 | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | +| sendgrid_via_mail_send_post_request_body_bad.py:0:0:0:0 | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | +| sendgrid_via_mail_send_post_request_body_bad.py:0:0:0:0 | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:62 | ControlFlowNode for Attribute | | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:61 | ControlFlowNode for Attribute | | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute | @@ -25,9 +40,15 @@ edges | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute | | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:78 | ControlFlowNode for Subscript | | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:78 | ControlFlowNode for Subscript | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | +| smtplib_bad_subparts.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_subparts.request | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | +| smtplib_bad_subparts.py:2:26:2:32 | ControlFlowNode for ImportMember | smtplib_bad_subparts.py:2:26:2:32 | GSSA Variable request | +| smtplib_bad_subparts.py:2:26:2:32 | GSSA Variable request | smtplib_bad_subparts.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_subparts.request | | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | smtplib_bad_subparts.py:17:12:17:23 | ControlFlowNode for Attribute | | smtplib_bad_subparts.py:17:12:17:23 | ControlFlowNode for Attribute | smtplib_bad_subparts.py:17:12:17:33 | ControlFlowNode for Subscript | | smtplib_bad_subparts.py:17:12:17:33 | ControlFlowNode for Subscript | smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | +| smtplib_bad_via_attach.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_via_attach.request | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | +| smtplib_bad_via_attach.py:2:26:2:32 | ControlFlowNode for ImportMember | smtplib_bad_via_attach.py:2:26:2:32 | GSSA Variable request | +| smtplib_bad_via_attach.py:2:26:2:32 | GSSA Variable request | smtplib_bad_via_attach.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_via_attach.request | | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | smtplib_bad_via_attach.py:20:12:20:23 | ControlFlowNode for Attribute | | smtplib_bad_via_attach.py:20:12:20:23 | ControlFlowNode for Attribute | smtplib_bad_via_attach.py:20:12:20:31 | ControlFlowNode for Subscript | | smtplib_bad_via_attach.py:20:12:20:31 | ControlFlowNode for Subscript | smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | @@ -35,6 +56,9 @@ nodes | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| flask_mail.py:0:0:0:0 | ModuleVariableNode for flask_mail.request | semmle.label | ModuleVariableNode for flask_mail.request | +| flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_mail.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | flask_mail.py:13:22:13:28 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_mail.py:13:22:13:33 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -44,6 +68,9 @@ nodes | flask_mail.py:31:24:31:30 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_mail.py:31:24:31:35 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| sendgrid_mail.py:0:0:0:0 | ModuleVariableNode for sendgrid_mail.request | semmle.label | ModuleVariableNode for sendgrid_mail.request | +| sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| sendgrid_mail.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | sendgrid_mail.py:14:22:14:33 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -54,6 +81,9 @@ nodes | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | sendgrid_mail.py:37:41:37:52 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| sendgrid_via_mail_send_post_request_body_bad.py:0:0:0:0 | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | semmle.label | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | +| sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | GSSA Variable request | semmle.label | GSSA Variable request | | sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:62 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -66,10 +96,16 @@ nodes | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:78 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| smtplib_bad_subparts.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_subparts.request | semmle.label | ModuleVariableNode for smtplib_bad_subparts.request | +| smtplib_bad_subparts.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| smtplib_bad_subparts.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | smtplib_bad_subparts.py:17:12:17:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | smtplib_bad_subparts.py:17:12:17:33 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | semmle.label | ControlFlowNode for html | +| smtplib_bad_via_attach.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_via_attach.request | semmle.label | ModuleVariableNode for smtplib_bad_via_attach.request | +| smtplib_bad_via_attach.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| smtplib_bad_via_attach.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | smtplib_bad_via_attach.py:20:12:20:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | smtplib_bad_via_attach.py:20:12:20:31 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -79,18 +115,14 @@ subpaths | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | a user-provided value | | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | a user-provided value | | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | a user-provided value | -| flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:13:22:13:28 | ControlFlowNode for request | a user-provided value | -| flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:13:22:13:28 | ControlFlowNode for request | a user-provided value | -| flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | flask_mail.py:18:14:18:20 | ControlFlowNode for request | flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:18:14:18:20 | ControlFlowNode for request | a user-provided value | -| flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | flask_mail.py:31:24:31:30 | ControlFlowNode for request | flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:31:24:31:30 | ControlFlowNode for request | a user-provided value | -| sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | a user-provided value | -| sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | a user-provided value | -| sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | a user-provided value | -| smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | Cross-site scripting vulnerability due to $@. | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | a user-provided value | -| smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | Cross-site scripting vulnerability due to $@. | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | a user-provided value | +| flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | 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:16:26:16:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | 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:27:25:27:77 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | 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:41:25:41:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | a user-provided value | +| smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | smtplib_bad_subparts.py:2:26:2:32 | ControlFlowNode for ImportMember | smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | Cross-site scripting vulnerability due to $@. | smtplib_bad_subparts.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | +| smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | smtplib_bad_via_attach.py:2:26:2:32 | ControlFlowNode for ImportMember | smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | Cross-site scripting vulnerability due to $@. | smtplib_bad_via_attach.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-113/HeaderInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-113/HeaderInjection.expected index 100beb0f4b3..588c9ea3bb5 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-113/HeaderInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-113/HeaderInjection.expected @@ -1,6 +1,12 @@ edges | django_bad.py:5:18:5:58 | ControlFlowNode for Attribute() | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | | django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:9:18:9:24 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:19:18:19:24 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:27:18:27:24 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:35:18:35:24 | ControlFlowNode for request | +| flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_bad.py:1:29:1:35 | GSSA Variable request | +| flask_bad.py:1:29:1:35 | GSSA Variable request | flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | | flask_bad.py:9:18:9:24 | ControlFlowNode for request | flask_bad.py:9:18:9:29 | ControlFlowNode for Attribute | | flask_bad.py:9:18:9:29 | ControlFlowNode for Attribute | flask_bad.py:9:18:9:43 | ControlFlowNode for Subscript | | flask_bad.py:9:18:9:43 | ControlFlowNode for Subscript | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | @@ -18,6 +24,9 @@ nodes | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header | | django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | semmle.label | ModuleVariableNode for flask_bad.request | +| flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_bad.py:1:29:1:35 | GSSA Variable request | semmle.label | GSSA Variable request | | flask_bad.py:9:18:9:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_bad.py:9:18:9:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_bad.py:9:18:9:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -38,7 +47,7 @@ subpaths #select | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | django_bad.py:5:18:5:58 | ControlFlowNode for Attribute() | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | This | django_bad.py:5:18:5:58 | ControlFlowNode for Attribute() | user-provided value | | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | This | django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | user-provided value | -| flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | flask_bad.py:9:18:9:24 | ControlFlowNode for request | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | This | flask_bad.py:9:18:9:24 | ControlFlowNode for request | user-provided value | -| flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | flask_bad.py:19:18:19:24 | ControlFlowNode for request | flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | This | flask_bad.py:19:18:19:24 | ControlFlowNode for request | user-provided value | -| flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | flask_bad.py:27:18:27:24 | ControlFlowNode for request | flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | This | flask_bad.py:27:18:27:24 | ControlFlowNode for request | user-provided value | -| flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | flask_bad.py:35:18:35:24 | ControlFlowNode for request | flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | This | flask_bad.py:35:18:35:24 | ControlFlowNode for request | user-provided value | +| flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | This | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | user-provided value | +| flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | This | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | user-provided value | +| flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | This | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | user-provided value | +| flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | This | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected index 2b6fb18f47b..5b6b8a4bc24 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected @@ -1,10 +1,17 @@ edges +| csv_bad.py:0:0:0:0 | ModuleVariableNode for csv_bad.request | csv_bad.py:16:16:16:22 | ControlFlowNode for request | +| csv_bad.py:0:0:0:0 | ModuleVariableNode for csv_bad.request | csv_bad.py:24:16:24:22 | ControlFlowNode for request | +| csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:9:19:9:25 | GSSA Variable request | +| csv_bad.py:9:19:9:25 | GSSA Variable request | csv_bad.py:0:0:0:0 | ModuleVariableNode for csv_bad.request | | csv_bad.py:16:16:16:22 | ControlFlowNode for request | csv_bad.py:16:16:16:27 | ControlFlowNode for Attribute | | csv_bad.py:16:16:16:27 | ControlFlowNode for Attribute | csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | | csv_bad.py:16:16:16:27 | ControlFlowNode for Attribute | csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | | csv_bad.py:24:16:24:22 | ControlFlowNode for request | csv_bad.py:24:16:24:27 | ControlFlowNode for Attribute | | csv_bad.py:24:16:24:27 | ControlFlowNode for Attribute | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | nodes +| csv_bad.py:0:0:0:0 | ModuleVariableNode for csv_bad.request | semmle.label | ModuleVariableNode for csv_bad.request | +| csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| csv_bad.py:9:19:9:25 | GSSA Variable request | semmle.label | GSSA Variable request | | csv_bad.py:16:16:16:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | csv_bad.py:16:16:16:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | semmle.label | ControlFlowNode for csv_data | @@ -14,6 +21,6 @@ nodes | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | semmle.label | ControlFlowNode for csv_data | subpaths #select -| csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | csv_bad.py:16:16:16:22 | ControlFlowNode for request | csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:16:16:16:22 | ControlFlowNode for request | this user input | -| csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | csv_bad.py:16:16:16:22 | ControlFlowNode for request | csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:16:16:16:22 | ControlFlowNode for request | this user input | -| csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | csv_bad.py:24:16:24:22 | ControlFlowNode for request | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:24:16:24:22 | ControlFlowNode for request | this user input | +| csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | +| csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | +| csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected b/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected index a432cf5053f..fd5bbf319dc 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected @@ -1,16 +1,8 @@ edges -| flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip | -| flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip | | tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip | nodes -| flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip | semmle.label | ControlFlowNode for client_ip | -| flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip | semmle.label | ControlFlowNode for client_ip | | tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip | semmle.label | ControlFlowNode for client_ip | subpaths #select -| flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip | flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip | IP address spoofing might include code from $@. | flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | this user input | -| flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip | flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip | IP address spoofing might include code from $@. | flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | this user input | | tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip | tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip | IP address spoofing might include code from $@. | tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | this user input | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.expected b/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.expected index 24784f039e7..425b00a85c7 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.expected @@ -1,4 +1,7 @@ edges +| ldap3_remote.py:0:0:0:0 | ModuleVariableNode for ldap3_remote.request | ldap3_remote.py:138:21:138:27 | ControlFlowNode for request | +| ldap3_remote.py:2:19:2:25 | ControlFlowNode for ImportMember | ldap3_remote.py:2:19:2:25 | GSSA Variable request | +| ldap3_remote.py:2:19:2:25 | GSSA Variable request | ldap3_remote.py:0:0:0:0 | ModuleVariableNode for ldap3_remote.request | | ldap3_remote.py:101:12:101:49 | ControlFlowNode for BinaryExpr | ldap3_remote.py:102:18:102:21 | ControlFlowNode for host | | ldap3_remote.py:114:12:114:49 | ControlFlowNode for BinaryExpr | ldap3_remote.py:115:18:115:21 | ControlFlowNode for host | | ldap3_remote.py:126:12:126:31 | ControlFlowNode for BinaryExpr | ldap3_remote.py:127:18:127:21 | ControlFlowNode for host | @@ -8,6 +11,9 @@ edges nodes | ldap2_remote.py:45:41:45:60 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | ldap2_remote.py:56:41:56:60 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| ldap3_remote.py:0:0:0:0 | ModuleVariableNode for ldap3_remote.request | semmle.label | ModuleVariableNode for ldap3_remote.request | +| ldap3_remote.py:2:19:2:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| ldap3_remote.py:2:19:2:25 | GSSA Variable request | semmle.label | GSSA Variable request | | ldap3_remote.py:101:12:101:49 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | ldap3_remote.py:102:18:102:21 | ControlFlowNode for host | semmle.label | ControlFlowNode for host | | ldap3_remote.py:114:12:114:49 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | @@ -25,4 +31,4 @@ subpaths | ldap3_remote.py:102:18:102:21 | ControlFlowNode for host | ldap3_remote.py:101:12:101:49 | ControlFlowNode for BinaryExpr | ldap3_remote.py:102:18:102:21 | ControlFlowNode for host | $@ is authenticated insecurely. | ldap3_remote.py:102:18:102:21 | ControlFlowNode for host | This LDAP host | | ldap3_remote.py:115:18:115:21 | ControlFlowNode for host | ldap3_remote.py:114:12:114:49 | ControlFlowNode for BinaryExpr | ldap3_remote.py:115:18:115:21 | ControlFlowNode for host | $@ is authenticated insecurely. | ldap3_remote.py:115:18:115:21 | ControlFlowNode for host | This LDAP host | | ldap3_remote.py:127:18:127:21 | ControlFlowNode for host | ldap3_remote.py:126:12:126:31 | ControlFlowNode for BinaryExpr | ldap3_remote.py:127:18:127:21 | ControlFlowNode for host | $@ is authenticated insecurely. | ldap3_remote.py:127:18:127:21 | ControlFlowNode for host | This LDAP host | -| ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | ldap3_remote.py:138:21:138:27 | ControlFlowNode for request | ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | $@ is authenticated insecurely. | ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | This LDAP host | +| ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | ldap3_remote.py:2:19:2:25 | ControlFlowNode for ImportMember | ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | $@ is authenticated insecurely. | ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | This LDAP host | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-614/CookieInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-614/CookieInjection.expected index d246f8b14d6..5cc54fbdad2 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-614/CookieInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-614/CookieInjection.expected @@ -1,6 +1,12 @@ edges | django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:24:21:24:27 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:24:49:24:55 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:32:37:32:43 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:32:60:32:66 | ControlFlowNode for request | +| flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:1:26:1:32 | GSSA Variable request | +| flask_bad.py:1:26:1:32 | GSSA Variable request | flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:21:24:32 | ControlFlowNode for Attribute | | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:49:24:60 | ControlFlowNode for Attribute | | flask_bad.py:24:21:24:32 | ControlFlowNode for Attribute | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | @@ -19,6 +25,9 @@ nodes | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | semmle.label | ControlFlowNode for Fstring | | django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | semmle.label | ModuleVariableNode for flask_bad.request | +| flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_bad.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | flask_bad.py:24:21:24:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_bad.py:24:21:24:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -46,18 +55,12 @@ subpaths | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its httponly flag is not properly set. | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | user-supplied input | | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its samesite flag is not properly set. | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | user-supplied input | | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its secure flag is not properly set. | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | user-supplied input | -| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:49:24:55 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:24:49:24:55 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:49:24:55 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:24:49:24:55 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:49:24:55 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:24:49:24:55 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:37:32:43 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:32:37:32:43 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:37:32:43 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:32:37:32:43 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:37:32:43 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:32:37:32:43 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:60:32:66 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:32:60:32:66 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:60:32:66 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:32:60:32:66 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:60:32:66 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:32:60:32:66 | ControlFlowNode for request | user-supplied input | +| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-943/NoSQLInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-943/NoSQLInjection.expected index 2922cc9f97e..54948a2d17f 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-943/NoSQLInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-943/NoSQLInjection.expected @@ -1,4 +1,8 @@ edges +| flask_mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for flask_mongoengine_bad.request | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | +| flask_mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for flask_mongoengine_bad.request | flask_mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | +| flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_mongoengine_bad.py:1:26:1:32 | GSSA Variable request | +| flask_mongoengine_bad.py:1:26:1:32 | GSSA Variable request | flask_mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for flask_mongoengine_bad.request | | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | flask_mongoengine_bad.py:19:21:19:32 | ControlFlowNode for Attribute | | flask_mongoengine_bad.py:19:21:19:32 | ControlFlowNode for Attribute | flask_mongoengine_bad.py:19:21:19:42 | ControlFlowNode for Subscript | | flask_mongoengine_bad.py:19:21:19:42 | ControlFlowNode for Subscript | flask_mongoengine_bad.py:20:30:20:42 | ControlFlowNode for unsafe_search | @@ -9,11 +13,22 @@ edges | flask_mongoengine_bad.py:26:21:26:42 | ControlFlowNode for Subscript | flask_mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | | flask_mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | +| flask_pymongo_bad.py:0:0:0:0 | ModuleVariableNode for flask_pymongo_bad.request | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | +| flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_pymongo_bad.py:1:26:1:32 | GSSA Variable request | +| flask_pymongo_bad.py:1:26:1:32 | GSSA Variable request | flask_pymongo_bad.py:0:0:0:0 | ModuleVariableNode for flask_pymongo_bad.request | | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | flask_pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | | flask_pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | flask_pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | | flask_pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | +| mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:1:26:1:32 | GSSA Variable request | +| mongoengine_bad.py:1:26:1:32 | GSSA Variable request | mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | mongoengine_bad.py:18:21:18:32 | ControlFlowNode for Attribute | | mongoengine_bad.py:18:21:18:32 | ControlFlowNode for Attribute | mongoengine_bad.py:18:21:18:42 | ControlFlowNode for Subscript | | mongoengine_bad.py:18:21:18:42 | ControlFlowNode for Subscript | mongoengine_bad.py:19:30:19:42 | ControlFlowNode for unsafe_search | @@ -44,6 +59,11 @@ edges | mongoengine_bad.py:57:21:57:42 | ControlFlowNode for Subscript | mongoengine_bad.py:58:30:58:42 | ControlFlowNode for unsafe_search | | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | | mongoengine_bad.py:58:30:58:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | +| pymongo_test.py:0:0:0:0 | ModuleVariableNode for pymongo_test.request | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | +| pymongo_test.py:0:0:0:0 | ModuleVariableNode for pymongo_test.request | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | +| pymongo_test.py:0:0:0:0 | ModuleVariableNode for pymongo_test.request | pymongo_test.py:39:27:39:33 | ControlFlowNode for request | +| pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | pymongo_test.py:1:26:1:32 | GSSA Variable request | +| pymongo_test.py:1:26:1:32 | GSSA Variable request | pymongo_test.py:0:0:0:0 | ModuleVariableNode for pymongo_test.request | | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | pymongo_test.py:12:21:12:32 | ControlFlowNode for Attribute | | pymongo_test.py:12:21:12:32 | ControlFlowNode for Attribute | pymongo_test.py:12:21:12:42 | ControlFlowNode for Subscript | | pymongo_test.py:12:21:12:42 | ControlFlowNode for Subscript | pymongo_test.py:13:30:13:42 | ControlFlowNode for unsafe_search | @@ -58,6 +78,9 @@ edges | pymongo_test.py:39:27:39:38 | ControlFlowNode for Attribute | pymongo_test.py:39:27:39:50 | ControlFlowNode for Subscript | | pymongo_test.py:39:27:39:50 | ControlFlowNode for Subscript | pymongo_test.py:39:16:39:51 | ControlFlowNode for Attribute() | nodes +| flask_mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for flask_mongoengine_bad.request | semmle.label | ModuleVariableNode for flask_mongoengine_bad.request | +| flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_mongoengine_bad.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_mongoengine_bad.py:19:21:19:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_mongoengine_bad.py:19:21:19:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -70,12 +93,18 @@ nodes | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | flask_mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| flask_pymongo_bad.py:0:0:0:0 | ModuleVariableNode for flask_pymongo_bad.request | semmle.label | ModuleVariableNode for flask_pymongo_bad.request | +| flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_pymongo_bad.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | semmle.label | ModuleVariableNode for mongoengine_bad.request | +| mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| mongoengine_bad.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | mongoengine_bad.py:18:21:18:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | mongoengine_bad.py:18:21:18:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -112,6 +141,9 @@ nodes | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:58:30:58:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| pymongo_test.py:0:0:0:0 | ModuleVariableNode for pymongo_test.request | semmle.label | ModuleVariableNode for pymongo_test.request | +| pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| pymongo_test.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | pymongo_test.py:12:21:12:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | pymongo_test.py:12:21:12:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -130,15 +162,15 @@ nodes | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | subpaths #select -| flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | $@ NoSQL query contains an unsanitized $@ | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | This | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | user-provided value | -| flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | flask_mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | This | flask_mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | user-provided value | -| flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | This | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | This | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | This | mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | user-provided value | -| pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | This | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | user-provided value | -| pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | This | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | user-provided value | -| pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | pymongo_test.py:39:27:39:33 | ControlFlowNode for request | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | This | pymongo_test.py:39:27:39:33 | ControlFlowNode for request | user-provided value | +| flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | $@ NoSQL query contains an unsanitized $@ | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | This | flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | This | flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | This | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | This | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | This | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | This | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected index fcb2d3103eb..c64a6943813 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected @@ -1,10 +1,16 @@ edges +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:13:16:13:22 | ControlFlowNode for request | +| test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:5:26:5:32 | GSSA Variable request | +| test.py:5:26:5:32 | GSSA Variable request | test.py:0:0:0:0 | ModuleVariableNode for test.request | | test.py:13:16:13:22 | ControlFlowNode for request | test.py:13:16:13:27 | ControlFlowNode for Attribute | | test.py:13:16:13:27 | ControlFlowNode for Attribute | test.py:15:36:15:39 | ControlFlowNode for data | nodes +| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| test.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | | test.py:13:16:13:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test.py:13:16:13:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:15:36:15:39 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | subpaths #select -| test.py:15:36:15:39 | ControlFlowNode for data | test.py:13:16:13:22 | ControlFlowNode for request | test.py:15:36:15:39 | ControlFlowNode for data | Call to hmac.new [param 1] with untrusted data from $@. | test.py:13:16:13:22 | ControlFlowNode for request | ControlFlowNode for request | +| test.py:15:36:15:39 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:15:36:15:39 | ControlFlowNode for data | Call to hmac.new [param 1] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected b/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected index 49c173f6fe9..64fe441dc64 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected @@ -1,6 +1,22 @@ edges +| flask_path_injection.py:0:0:0:0 | ModuleVariableNode for flask_path_injection.request | flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | +| flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_path_injection.py:1:26:1:32 | GSSA Variable request | +| flask_path_injection.py:1:26:1:32 | GSSA Variable request | flask_path_injection.py:0:0:0:0 | ModuleVariableNode for flask_path_injection.request | | flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | | flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:12:16:12:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:19:16:19:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:27:16:27:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:46:16:46:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:63:16:63:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:84:16:84:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:107:16:107:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:118:16:118:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:129:16:129:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:138:16:138:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:149:16:149:22 | ControlFlowNode for request | +| path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:3:26:3:32 | GSSA Variable request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | | path_injection.py:12:16:12:22 | ControlFlowNode for request | path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | | path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | | path_injection.py:19:16:19:22 | ControlFlowNode for request | path_injection.py:19:16:19:27 | ControlFlowNode for Attribute | @@ -33,6 +49,9 @@ edges | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | path_injection.py:142:14:142:17 | ControlFlowNode for path | | path_injection.py:149:16:149:22 | ControlFlowNode for request | path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | | path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | path_injection.py:152:18:152:21 | ControlFlowNode for path | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:9:12:9:18 | ControlFlowNode for request | +| test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:3:26:3:32 | GSSA Variable request | +| test.py:3:26:3:32 | GSSA Variable request | test.py:0:0:0:0 | ModuleVariableNode for test.request | | test.py:9:12:9:18 | ControlFlowNode for request | test.py:9:12:9:23 | ControlFlowNode for Attribute | | test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:9:12:9:39 | ControlFlowNode for Attribute() | | test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:18:9:18:16 | ControlFlowNode for source() | @@ -52,9 +71,15 @@ edges | test.py:48:23:48:23 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | | test.py:48:23:48:23 | ControlFlowNode for x | test.py:48:13:48:24 | ControlFlowNode for normalize() | nodes +| flask_path_injection.py:0:0:0:0 | ModuleVariableNode for flask_path_injection.request | semmle.label | ModuleVariableNode for flask_path_injection.request | +| flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_path_injection.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | semmle.label | ControlFlowNode for dirname | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | semmle.label | ModuleVariableNode for path_injection.request | +| path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| path_injection.py:3:26:3:32 | GSSA Variable request | semmle.label | GSSA Variable request | | path_injection.py:12:16:12:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | @@ -100,6 +125,9 @@ nodes | path_injection.py:149:16:149:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | path_injection.py:152:18:152:21 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| test.py:3:26:3:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test.py:3:26:3:32 | GSSA Variable request | semmle.label | GSSA Variable request | | test.py:9:12:9:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:9:12:9:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | @@ -122,21 +150,21 @@ subpaths | test.py:25:19:25:19 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:25:9:25:20 | ControlFlowNode for normalize() | | test.py:48:23:48:23 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:48:13:48:24 | ControlFlowNode for normalize() | #select -| flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | This path depends on $@. | flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | a user-provided value | -| path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | path_injection.py:12:16:12:22 | ControlFlowNode for request | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | This path depends on $@. | path_injection.py:12:16:12:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:21:14:21:18 | ControlFlowNode for npath | path_injection.py:19:16:19:22 | ControlFlowNode for request | path_injection.py:21:14:21:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:19:16:19:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:31:14:31:18 | ControlFlowNode for npath | path_injection.py:27:16:27:22 | ControlFlowNode for request | path_injection.py:31:14:31:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:27:16:27:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:48:14:48:18 | ControlFlowNode for npath | path_injection.py:46:16:46:22 | ControlFlowNode for request | path_injection.py:48:14:48:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:46:16:46:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:65:14:65:18 | ControlFlowNode for npath | path_injection.py:63:16:63:22 | ControlFlowNode for request | path_injection.py:65:14:65:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:63:16:63:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | This path depends on $@. | path_injection.py:84:16:84:22 | ControlFlowNode for request | a user-provided value | +| flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | This path depends on $@. | flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | This path depends on $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| path_injection.py:21:14:21:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:21:14:21:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| path_injection.py:31:14:31:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:31:14:31:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| path_injection.py:48:14:48:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:48:14:48:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| path_injection.py:65:14:65:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:65:14:65:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | This path depends on $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | | path_injection.py:94:14:94:17 | ControlFlowNode for path | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | path_injection.py:94:14:94:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | a user-provided value | | path_injection.py:102:14:102:17 | ControlFlowNode for path | path_injection.py:98:20:98:22 | ControlFlowNode for foo | path_injection.py:102:14:102:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:98:20:98:22 | ControlFlowNode for foo | a user-provided value | -| path_injection.py:113:14:113:17 | ControlFlowNode for path | path_injection.py:107:16:107:22 | ControlFlowNode for request | path_injection.py:113:14:113:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:107:16:107:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:124:14:124:17 | ControlFlowNode for path | path_injection.py:118:16:118:22 | ControlFlowNode for request | path_injection.py:124:14:124:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:118:16:118:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | path_injection.py:129:16:129:22 | ControlFlowNode for request | path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | This path depends on $@. | path_injection.py:129:16:129:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:142:14:142:17 | ControlFlowNode for path | path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:142:14:142:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:138:16:138:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:152:18:152:21 | ControlFlowNode for path | path_injection.py:149:16:149:22 | ControlFlowNode for request | path_injection.py:152:18:152:21 | ControlFlowNode for path | This path depends on $@. | path_injection.py:149:16:149:22 | ControlFlowNode for request | a user-provided value | -| test.py:19:10:19:10 | ControlFlowNode for x | test.py:9:12:9:18 | ControlFlowNode for request | test.py:19:10:19:10 | ControlFlowNode for x | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value | -| test.py:26:10:26:10 | ControlFlowNode for y | test.py:9:12:9:18 | ControlFlowNode for request | test.py:26:10:26:10 | ControlFlowNode for y | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value | -| test.py:33:14:33:14 | ControlFlowNode for x | test.py:9:12:9:18 | ControlFlowNode for request | test.py:33:14:33:14 | ControlFlowNode for x | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value | -| test.py:49:14:49:14 | ControlFlowNode for y | test.py:9:12:9:18 | ControlFlowNode for request | test.py:49:14:49:14 | ControlFlowNode for y | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value | +| path_injection.py:113:14:113:17 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:113:14:113:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| path_injection.py:124:14:124:17 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:124:14:124:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | This path depends on $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| path_injection.py:142:14:142:17 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:142:14:142:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| path_injection.py:152:18:152:21 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:152:18:152:21 | ControlFlowNode for path | This path depends on $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:19:10:19:10 | ControlFlowNode for x | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:19:10:19:10 | ControlFlowNode for x | This path depends on $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:26:10:26:10 | ControlFlowNode for y | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:26:10:26:10 | ControlFlowNode for y | This path depends on $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:33:14:33:14 | ControlFlowNode for x | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:33:14:33:14 | ControlFlowNode for x | This path depends on $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:49:14:49:14 | ControlFlowNode for y | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:49:14:49:14 | ControlFlowNode for y | This path depends on $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected index 8d26b3f6d5c..c86a2a28688 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected @@ -1,4 +1,7 @@ edges +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:18:13:18:19 | ControlFlowNode for request | +| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:5:26:5:32 | GSSA Variable request | +| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | @@ -10,6 +13,9 @@ edges | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | nodes +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | semmle.label | ModuleVariableNode for command_injection.request | +| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| command_injection.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | | command_injection.py:18:13:18:19 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | @@ -23,12 +29,12 @@ nodes | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | subpaths #select -| command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | +| command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected index cce39a976db..71b8d19b2cd 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected @@ -1,4 +1,14 @@ edges +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:11:13:11:19 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:18:13:18:19 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:25:11:25:17 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:31:13:31:19 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:38:15:38:21 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:54:15:54:21 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:71:12:71:18 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:78:12:78:18 | ControlFlowNode for request | +| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:5:26:5:32 | GSSA Variable request | +| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | | command_injection.py:11:13:11:19 | ControlFlowNode for request | command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | | command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | @@ -21,6 +31,9 @@ edges | command_injection.py:78:12:78:18 | ControlFlowNode for request | command_injection.py:78:12:78:23 | ControlFlowNode for Attribute | | command_injection.py:78:12:78:23 | ControlFlowNode for Attribute | command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | nodes +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | semmle.label | ModuleVariableNode for command_injection.request | +| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| command_injection.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | | command_injection.py:11:13:11:19 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | @@ -52,16 +65,16 @@ nodes | command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | subpaths #select -| command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | command_injection.py:11:13:11:19 | ControlFlowNode for request | command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:11:13:11:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:26:23:26:25 | ControlFlowNode for cmd | command_injection.py:25:11:25:17 | ControlFlowNode for request | command_injection.py:26:23:26:25 | ControlFlowNode for cmd | This command line depends on $@. | command_injection.py:25:11:25:17 | ControlFlowNode for request | a user-provided value | -| command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | command_injection.py:31:13:31:19 | ControlFlowNode for request | command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:31:13:31:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:41:15:41:21 | ControlFlowNode for command | command_injection.py:38:15:38:21 | ControlFlowNode for request | command_injection.py:41:15:41:21 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:38:15:38:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:42:15:42:21 | ControlFlowNode for command | command_injection.py:38:15:38:21 | ControlFlowNode for request | command_injection.py:42:15:42:21 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:38:15:38:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:55:15:55:21 | ControlFlowNode for command | command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:55:15:55:21 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:54:15:54:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:56:14:56:20 | ControlFlowNode for command | command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:56:14:56:20 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:54:15:54:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:57:21:57:27 | ControlFlowNode for command | command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:57:21:57:27 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:54:15:54:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:58:27:58:33 | ControlFlowNode for command | command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:58:27:58:33 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:54:15:54:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:59:20:59:26 | ControlFlowNode for command | command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:59:20:59:26 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:54:15:54:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | command_injection.py:71:12:71:18 | ControlFlowNode for request | command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:71:12:71:18 | ControlFlowNode for request | a user-provided value | -| command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | command_injection.py:78:12:78:18 | ControlFlowNode for request | command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:78:12:78:18 | ControlFlowNode for request | a user-provided value | +| command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:26:23:26:25 | ControlFlowNode for cmd | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:26:23:26:25 | ControlFlowNode for cmd | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:41:15:41:21 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:41:15:41:21 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:42:15:42:21 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:42:15:42:21 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:55:15:55:21 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:55:15:55:21 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:56:14:56:20 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:56:14:56:20 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:57:21:57:27 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:57:21:57:27 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:58:27:58:33 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:58:27:58:33 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:59:20:59:26 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:59:20:59:26 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | +| command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected index 39c2bb3778f..5dc0fc3e5d7 100644 --- a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected +++ b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected @@ -1,4 +1,9 @@ edges +| reflected_xss.py:0:0:0:0 | ModuleVariableNode for reflected_xss.request | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | +| reflected_xss.py:0:0:0:0 | ModuleVariableNode for reflected_xss.request | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | +| reflected_xss.py:0:0:0:0 | ModuleVariableNode for reflected_xss.request | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | +| reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:2:26:2:32 | GSSA Variable request | +| reflected_xss.py:2:26:2:32 | GSSA Variable request | reflected_xss.py:0:0:0:0 | ModuleVariableNode for reflected_xss.request | | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | reflected_xss.py:9:18:9:29 | ControlFlowNode for Attribute | | reflected_xss.py:9:18:9:29 | ControlFlowNode for Attribute | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | reflected_xss.py:21:23:21:34 | ControlFlowNode for Attribute | @@ -6,6 +11,9 @@ edges | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | reflected_xss.py:27:23:27:34 | ControlFlowNode for Attribute | | reflected_xss.py:27:23:27:34 | ControlFlowNode for Attribute | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | nodes +| reflected_xss.py:0:0:0:0 | ModuleVariableNode for reflected_xss.request | semmle.label | ModuleVariableNode for reflected_xss.request | +| reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| reflected_xss.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | reflected_xss.py:9:18:9:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | @@ -17,6 +25,6 @@ nodes | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | subpaths #select -| reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | Cross-site scripting vulnerability due to $@. | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | a user-provided value | -| reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | a user-provided value | -| reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | a user-provided value | +| reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | Cross-site scripting vulnerability due to $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | +| reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | +| reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.expected b/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.expected index 7dcddaaae83..53fd7478f44 100644 --- a/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.expected @@ -1,4 +1,14 @@ edges +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:14:21:14:27 | ControlFlowNode for request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:31:21:31:27 | ControlFlowNode for request | +| ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:1:19:1:25 | GSSA Variable request | +| ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:1:19:1:25 | GSSA Variable request | +| ldap3_bad.py:1:19:1:25 | GSSA Variable request | ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | +| ldap3_bad.py:1:19:1:25 | GSSA Variable request | ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | ldap3_bad.py:13:17:13:28 | ControlFlowNode for Attribute | | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | ldap3_bad.py:14:21:14:32 | ControlFlowNode for Attribute | | ldap3_bad.py:13:17:13:28 | ControlFlowNode for Attribute | ldap3_bad.py:13:17:13:34 | ControlFlowNode for Subscript | @@ -13,6 +23,19 @@ edges | ldap3_bad.py:31:21:31:27 | ControlFlowNode for request | ldap3_bad.py:31:21:31:32 | ControlFlowNode for Attribute | | ldap3_bad.py:31:21:31:32 | ControlFlowNode for Attribute | ldap3_bad.py:31:21:31:44 | ControlFlowNode for Subscript | | ldap3_bad.py:31:21:31:44 | ControlFlowNode for Subscript | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:14:21:14:27 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:31:21:31:27 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:48:21:48:27 | ControlFlowNode for request | +| ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:1:19:1:25 | GSSA Variable request | +| ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:1:19:1:25 | GSSA Variable request | +| ldap_bad.py:1:19:1:25 | GSSA Variable request | ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | +| ldap_bad.py:1:19:1:25 | GSSA Variable request | ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | ldap_bad.py:13:17:13:28 | ControlFlowNode for Attribute | | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | ldap_bad.py:14:21:14:32 | ControlFlowNode for Attribute | | ldap_bad.py:13:17:13:28 | ControlFlowNode for Attribute | ldap_bad.py:13:17:13:34 | ControlFlowNode for Subscript | @@ -35,6 +58,12 @@ edges | ldap_bad.py:48:21:48:32 | ControlFlowNode for Attribute | ldap_bad.py:48:21:48:44 | ControlFlowNode for Subscript | | ldap_bad.py:48:21:48:44 | ControlFlowNode for Subscript | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | nodes +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | semmle.label | ModuleVariableNode for ldap3_bad.request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | semmle.label | ModuleVariableNode for ldap3_bad.request | +| ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| ldap3_bad.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| ldap3_bad.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | ldap3_bad.py:13:17:13:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -53,6 +82,12 @@ nodes | ldap3_bad.py:31:21:31:44 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | semmle.label | ControlFlowNode for dn | | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | semmle.label | ControlFlowNode for search_filter | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | semmle.label | ModuleVariableNode for ldap_bad.request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | semmle.label | ModuleVariableNode for ldap_bad.request | +| ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| ldap_bad.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| ldap_bad.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | ldap_bad.py:13:17:13:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -82,18 +117,13 @@ nodes | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | semmle.label | ControlFlowNode for search_filter | subpaths #select -| ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | $@ depends on $@. | ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | a user-provided value | -| ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | a user-provided value | -| ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | ldap3_bad.py:14:21:14:27 | ControlFlowNode for request | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:14:21:14:27 | ControlFlowNode for request | a user-provided value | -| ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | $@ depends on $@. | ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | a user-provided value | -| ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | a user-provided value | -| ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | ldap3_bad.py:31:21:31:27 | ControlFlowNode for request | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:31:21:31:27 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | ldap_bad.py:14:21:14:27 | ControlFlowNode for request | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:14:21:14:27 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | ldap_bad.py:31:21:31:27 | ControlFlowNode for request | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:31:21:31:27 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | ldap_bad.py:48:21:48:27 | ControlFlowNode for request | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:48:21:48:27 | ControlFlowNode for request | a user-provided value | +| ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | $@ depends on $@. | ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | $@ depends on $@. | ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected b/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected index 97f5bc54118..a1911a6331e 100644 --- a/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected @@ -1,4 +1,8 @@ edges +| code_injection.py:0:0:0:0 | ModuleVariableNode for code_injection.request | code_injection.py:6:12:6:18 | ControlFlowNode for request | +| code_injection.py:0:0:0:0 | ModuleVariableNode for code_injection.request | code_injection.py:18:16:18:22 | ControlFlowNode for request | +| code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:1:26:1:32 | GSSA Variable request | +| code_injection.py:1:26:1:32 | GSSA Variable request | code_injection.py:0:0:0:0 | ModuleVariableNode for code_injection.request | | code_injection.py:6:12:6:18 | ControlFlowNode for request | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:7:10:7:13 | ControlFlowNode for code | | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:8:10:8:13 | ControlFlowNode for code | @@ -6,6 +10,9 @@ edges | code_injection.py:18:16:18:22 | ControlFlowNode for request | code_injection.py:18:16:18:27 | ControlFlowNode for Attribute | | code_injection.py:18:16:18:27 | ControlFlowNode for Attribute | code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | nodes +| code_injection.py:0:0:0:0 | ModuleVariableNode for code_injection.request | semmle.label | ModuleVariableNode for code_injection.request | +| code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| code_injection.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | code_injection.py:6:12:6:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | code_injection.py:7:10:7:13 | ControlFlowNode for code | semmle.label | ControlFlowNode for code | @@ -16,7 +23,7 @@ nodes | code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | semmle.label | ControlFlowNode for obj_name | subpaths #select -| code_injection.py:7:10:7:13 | ControlFlowNode for code | code_injection.py:6:12:6:18 | ControlFlowNode for request | code_injection.py:7:10:7:13 | ControlFlowNode for code | This code execution depends on $@. | code_injection.py:6:12:6:18 | ControlFlowNode for request | a user-provided value | -| code_injection.py:8:10:8:13 | ControlFlowNode for code | code_injection.py:6:12:6:18 | ControlFlowNode for request | code_injection.py:8:10:8:13 | ControlFlowNode for code | This code execution depends on $@. | code_injection.py:6:12:6:18 | ControlFlowNode for request | a user-provided value | -| code_injection.py:10:10:10:12 | ControlFlowNode for cmd | code_injection.py:6:12:6:18 | ControlFlowNode for request | code_injection.py:10:10:10:12 | ControlFlowNode for cmd | This code execution depends on $@. | code_injection.py:6:12:6:18 | ControlFlowNode for request | a user-provided value | -| code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | code_injection.py:18:16:18:22 | ControlFlowNode for request | code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | This code execution depends on $@. | code_injection.py:18:16:18:22 | ControlFlowNode for request | a user-provided value | +| code_injection.py:7:10:7:13 | ControlFlowNode for code | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:7:10:7:13 | ControlFlowNode for code | This code execution depends on $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| code_injection.py:8:10:8:13 | ControlFlowNode for code | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:8:10:8:13 | ControlFlowNode for code | This code execution depends on $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| code_injection.py:10:10:10:12 | ControlFlowNode for cmd | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:10:10:10:12 | ControlFlowNode for cmd | This code execution depends on $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | This code execution depends on $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected index 9641f49e3e2..d4138316fc2 100644 --- a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected @@ -1,4 +1,10 @@ edges +| LogInjectionBad.py:0:0:0:0 | ModuleVariableNode for LogInjectionBad.request | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | +| LogInjectionBad.py:0:0:0:0 | ModuleVariableNode for LogInjectionBad.request | LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | +| LogInjectionBad.py:0:0:0:0 | ModuleVariableNode for LogInjectionBad.request | LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | +| LogInjectionBad.py:0:0:0:0 | ModuleVariableNode for LogInjectionBad.request | LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | +| LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:7:19:7:25 | GSSA Variable request | +| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | LogInjectionBad.py:0:0:0:0 | ModuleVariableNode for LogInjectionBad.request | | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute | | LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | | LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | LogInjectionBad.py:23:12:23:23 | ControlFlowNode for Attribute | @@ -8,6 +14,9 @@ edges | LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | LogInjectionBad.py:35:12:35:23 | ControlFlowNode for Attribute | | LogInjectionBad.py:35:12:35:23 | ControlFlowNode for Attribute | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | nodes +| LogInjectionBad.py:0:0:0:0 | ModuleVariableNode for LogInjectionBad.request | semmle.label | ModuleVariableNode for LogInjectionBad.request | +| LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | semmle.label | GSSA Variable request | | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | @@ -22,7 +31,7 @@ nodes | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | subpaths #select -| LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | a user-provided value | -| LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | a user-provided value | -| LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | a user-provided value | -| LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | a user-provided value | +| LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | a user-provided value | +| LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | a user-provided value | +| LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | a user-provided value | +| LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected index 9cab4ce7d16..dc536fa9e7e 100644 --- a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected +++ b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected @@ -1,10 +1,16 @@ edges +| unsafe_deserialization.py:0:0:0:0 | ModuleVariableNode for unsafe_deserialization.request | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | +| unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:8:26:8:32 | GSSA Variable request | +| unsafe_deserialization.py:8:26:8:32 | GSSA Variable request | unsafe_deserialization.py:0:0:0:0 | ModuleVariableNode for unsafe_deserialization.request | | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | nodes +| unsafe_deserialization.py:0:0:0:0 | ModuleVariableNode for unsafe_deserialization.request | semmle.label | ModuleVariableNode for unsafe_deserialization.request | +| unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| unsafe_deserialization.py:8:26:8:32 | GSSA Variable request | semmle.label | GSSA Variable request | | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | @@ -13,7 +19,7 @@ nodes | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | subpaths #select -| unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | a user-provided value | -| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | a user-provided value | -| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | a user-provided value | -| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | a user-provided value | +| unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | a user-provided value | +| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | a user-provided value | +| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | a user-provided value | +| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected index 750e61d048d..19f96791e87 100644 --- a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected +++ b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected @@ -1,4 +1,14 @@ edges +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:7:14:7:20 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:30:17:30:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:37:17:37:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:44:17:44:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:60:17:60:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:67:17:67:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:74:17:74:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:81:17:81:23 | ControlFlowNode for request | +| test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:1:26:1:32 | GSSA Variable request | +| test.py:1:26:1:32 | GSSA Variable request | test.py:0:0:0:0 | ModuleVariableNode for test.request | | test.py:7:14:7:20 | ControlFlowNode for request | test.py:7:14:7:25 | ControlFlowNode for Attribute | | test.py:7:14:7:25 | ControlFlowNode for Attribute | test.py:8:21:8:26 | ControlFlowNode for target | | test.py:30:17:30:23 | ControlFlowNode for request | test.py:30:17:30:28 | ControlFlowNode for Attribute | @@ -16,6 +26,9 @@ edges | test.py:81:17:81:23 | ControlFlowNode for request | test.py:81:17:81:28 | ControlFlowNode for Attribute | | test.py:81:17:81:28 | ControlFlowNode for Attribute | test.py:83:21:83:26 | ControlFlowNode for unsafe | nodes +| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| test.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | test.py:7:14:7:20 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test.py:7:14:7:25 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:8:21:8:26 | ControlFlowNode for target | semmle.label | ControlFlowNode for target | @@ -42,11 +55,11 @@ nodes | test.py:83:21:83:26 | ControlFlowNode for unsafe | semmle.label | ControlFlowNode for unsafe | subpaths #select -| test.py:8:21:8:26 | ControlFlowNode for target | test.py:7:14:7:20 | ControlFlowNode for request | test.py:8:21:8:26 | ControlFlowNode for target | Untrusted URL redirection depends on $@. | test.py:7:14:7:20 | ControlFlowNode for request | a user-provided value | -| test.py:32:21:32:24 | ControlFlowNode for safe | test.py:30:17:30:23 | ControlFlowNode for request | test.py:32:21:32:24 | ControlFlowNode for safe | Untrusted URL redirection depends on $@. | test.py:30:17:30:23 | ControlFlowNode for request | a user-provided value | -| test.py:39:21:39:24 | ControlFlowNode for safe | test.py:37:17:37:23 | ControlFlowNode for request | test.py:39:21:39:24 | ControlFlowNode for safe | Untrusted URL redirection depends on $@. | test.py:37:17:37:23 | ControlFlowNode for request | a user-provided value | -| test.py:46:21:46:24 | ControlFlowNode for safe | test.py:44:17:44:23 | ControlFlowNode for request | test.py:46:21:46:24 | ControlFlowNode for safe | Untrusted URL redirection depends on $@. | test.py:44:17:44:23 | ControlFlowNode for request | a user-provided value | -| test.py:62:21:62:26 | ControlFlowNode for unsafe | test.py:60:17:60:23 | ControlFlowNode for request | test.py:62:21:62:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:60:17:60:23 | ControlFlowNode for request | a user-provided value | -| test.py:69:21:69:26 | ControlFlowNode for unsafe | test.py:67:17:67:23 | ControlFlowNode for request | test.py:69:21:69:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:67:17:67:23 | ControlFlowNode for request | a user-provided value | -| test.py:76:21:76:26 | ControlFlowNode for unsafe | test.py:74:17:74:23 | ControlFlowNode for request | test.py:76:21:76:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:74:17:74:23 | ControlFlowNode for request | a user-provided value | -| test.py:83:21:83:26 | ControlFlowNode for unsafe | test.py:81:17:81:23 | ControlFlowNode for request | test.py:83:21:83:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:81:17:81:23 | ControlFlowNode for request | a user-provided value | +| test.py:8:21:8:26 | ControlFlowNode for target | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:8:21:8:26 | ControlFlowNode for target | Untrusted URL redirection depends on $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:32:21:32:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:32:21:32:24 | ControlFlowNode for safe | Untrusted URL redirection depends on $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:39:21:39:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:39:21:39:24 | ControlFlowNode for safe | Untrusted URL redirection depends on $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:46:21:46:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:46:21:46:24 | ControlFlowNode for safe | Untrusted URL redirection depends on $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:62:21:62:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:62:21:62:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:69:21:69:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:69:21:69:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:76:21:76:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:76:21:76:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:83:21:83:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:83:21:83:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.expected b/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.expected index 402ee97db09..3421155d992 100644 --- a/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.expected +++ b/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.expected @@ -1,4 +1,8 @@ edges +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:8:19:8:25 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:19:19:19:25 | ControlFlowNode for request | +| test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:1:26:1:32 | GSSA Variable request | +| test.py:1:26:1:32 | GSSA Variable request | test.py:0:0:0:0 | ModuleVariableNode for test.request | | test.py:8:19:8:25 | ControlFlowNode for request | test.py:8:19:8:30 | ControlFlowNode for Attribute | | test.py:8:19:8:30 | ControlFlowNode for Attribute | test.py:8:19:8:45 | ControlFlowNode for Subscript | | test.py:8:19:8:45 | ControlFlowNode for Subscript | test.py:9:34:9:44 | ControlFlowNode for xml_content | @@ -6,6 +10,9 @@ edges | test.py:19:19:19:30 | ControlFlowNode for Attribute | test.py:19:19:19:45 | ControlFlowNode for Subscript | | test.py:19:19:19:45 | ControlFlowNode for Subscript | test.py:30:34:30:44 | ControlFlowNode for xml_content | nodes +| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| test.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | test.py:8:19:8:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test.py:8:19:8:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:8:19:8:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -16,5 +23,5 @@ nodes | test.py:30:34:30:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content | subpaths #select -| test.py:9:34:9:44 | ControlFlowNode for xml_content | test.py:8:19:8:25 | ControlFlowNode for request | test.py:9:34:9:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against external entity expansion. | test.py:8:19:8:25 | ControlFlowNode for request | a user-provided value | -| test.py:30:34:30:44 | ControlFlowNode for xml_content | test.py:19:19:19:25 | ControlFlowNode for request | test.py:30:34:30:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against external entity expansion. | test.py:19:19:19:25 | ControlFlowNode for request | a user-provided value | +| test.py:9:34:9:44 | ControlFlowNode for xml_content | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:9:34:9:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against external entity expansion. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:30:34:30:44 | ControlFlowNode for xml_content | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:30:34:30:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against external entity expansion. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected index d0068a4b872..a33e851828d 100644 --- a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected @@ -2,6 +2,13 @@ edges | xpathBad.py:9:7:9:13 | ControlFlowNode for request | xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | | xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | | xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | +| xpathFlow.py:0:0:0:0 | ModuleVariableNode for xpathFlow.request | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | +| xpathFlow.py:0:0:0:0 | ModuleVariableNode for xpathFlow.request | xpathFlow.py:20:18:20:24 | ControlFlowNode for request | +| xpathFlow.py:0:0:0:0 | ModuleVariableNode for xpathFlow.request | xpathFlow.py:30:18:30:24 | ControlFlowNode for request | +| xpathFlow.py:0:0:0:0 | ModuleVariableNode for xpathFlow.request | xpathFlow.py:39:18:39:24 | ControlFlowNode for request | +| xpathFlow.py:0:0:0:0 | ModuleVariableNode for xpathFlow.request | xpathFlow.py:47:18:47:24 | ControlFlowNode for request | +| xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:2:26:2:32 | GSSA Variable request | +| xpathFlow.py:2:26:2:32 | GSSA Variable request | xpathFlow.py:0:0:0:0 | ModuleVariableNode for xpathFlow.request | | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | | xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | | xpathFlow.py:20:18:20:24 | ControlFlowNode for request | xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | @@ -17,6 +24,9 @@ nodes | xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| xpathFlow.py:0:0:0:0 | ModuleVariableNode for xpathFlow.request | semmle.label | ModuleVariableNode for xpathFlow.request | +| xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| xpathFlow.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | @@ -35,8 +45,8 @@ nodes subpaths #select | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | xpathBad.py:9:7:9:13 | ControlFlowNode for request | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | XPath expression depends on $@. | xpathBad.py:9:7:9:13 | ControlFlowNode for request | a user-provided value | -| xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | a user-provided value | -| xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | xpathFlow.py:20:18:20:24 | ControlFlowNode for request | xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:20:18:20:24 | ControlFlowNode for request | a user-provided value | -| xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | xpathFlow.py:30:18:30:24 | ControlFlowNode for request | xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:30:18:30:24 | ControlFlowNode for request | a user-provided value | -| xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | xpathFlow.py:39:18:39:24 | ControlFlowNode for request | xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:39:18:39:24 | ControlFlowNode for request | a user-provided value | -| xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | xpathFlow.py:47:18:47:24 | ControlFlowNode for request | xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:47:18:47:24 | ControlFlowNode for request | a user-provided value | +| xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | +| xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | +| xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | +| xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | +| xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected index 7f5cf5926c0..4646f9c03e9 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected @@ -1,13 +1,19 @@ edges +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:7:12:7:18 | ControlFlowNode for request | +| test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:2:26:2:32 | GSSA Variable request | +| test.py:2:26:2:32 | GSSA Variable request | test.py:0:0:0:0 | ModuleVariableNode for test.request | | test.py:7:12:7:18 | ControlFlowNode for request | test.py:7:12:7:23 | ControlFlowNode for Attribute | | test.py:7:12:7:23 | ControlFlowNode for Attribute | test.py:8:30:8:33 | ControlFlowNode for text | | test.py:7:12:7:23 | ControlFlowNode for Attribute | test.py:9:32:9:35 | ControlFlowNode for text | nodes +| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| test.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | | test.py:7:12:7:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test.py:7:12:7:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:8:30:8:33 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | | test.py:9:32:9:35 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | subpaths #select -| test.py:8:30:8:33 | ControlFlowNode for text | test.py:7:12:7:18 | ControlFlowNode for request | test.py:8:30:8:33 | ControlFlowNode for text | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | test.py:8:21:8:23 | \\s+ | regular expression | test.py:7:12:7:18 | ControlFlowNode for request | a user-provided value | -| test.py:9:32:9:35 | ControlFlowNode for text | test.py:7:12:7:18 | ControlFlowNode for request | test.py:9:32:9:35 | ControlFlowNode for text | This $@ that depends on $@ may run slow on strings with many repetitions of '99'. | test.py:9:27:9:29 | \\d+ | regular expression | test.py:7:12:7:18 | ControlFlowNode for request | a user-provided value | +| test.py:8:30:8:33 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:8:30:8:33 | ControlFlowNode for text | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | test.py:8:21:8:23 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:9:32:9:35 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:9:32:9:35 | ControlFlowNode for text | This $@ that depends on $@ may run slow on strings with many repetitions of '99'. | test.py:9:27:9:29 | \\d+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-730-RegexInjection/RegexInjection.expected b/python/ql/test/query-tests/Security/CWE-730-RegexInjection/RegexInjection.expected index 317815142fe..bbc01aab4be 100644 --- a/python/ql/test/query-tests/Security/CWE-730-RegexInjection/RegexInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-730-RegexInjection/RegexInjection.expected @@ -1,4 +1,9 @@ edges +| re_bad.py:0:0:0:0 | ModuleVariableNode for re_bad.request | re_bad.py:13:22:13:28 | ControlFlowNode for request | +| re_bad.py:0:0:0:0 | ModuleVariableNode for re_bad.request | re_bad.py:24:22:24:28 | ControlFlowNode for request | +| re_bad.py:0:0:0:0 | ModuleVariableNode for re_bad.request | re_bad.py:36:22:36:28 | ControlFlowNode for request | +| re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | re_bad.py:1:19:1:25 | GSSA Variable request | +| re_bad.py:1:19:1:25 | GSSA Variable request | re_bad.py:0:0:0:0 | ModuleVariableNode for re_bad.request | | re_bad.py:13:22:13:28 | ControlFlowNode for request | re_bad.py:13:22:13:33 | ControlFlowNode for Attribute | | re_bad.py:13:22:13:33 | ControlFlowNode for Attribute | re_bad.py:13:22:13:44 | ControlFlowNode for Subscript | | re_bad.py:13:22:13:44 | ControlFlowNode for Subscript | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | @@ -9,6 +14,9 @@ edges | re_bad.py:36:22:36:33 | ControlFlowNode for Attribute | re_bad.py:36:22:36:44 | ControlFlowNode for Subscript | | re_bad.py:36:22:36:44 | ControlFlowNode for Subscript | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | nodes +| re_bad.py:0:0:0:0 | ModuleVariableNode for re_bad.request | semmle.label | ModuleVariableNode for re_bad.request | +| re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| re_bad.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | re_bad.py:13:22:13:28 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | re_bad.py:13:22:13:33 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | re_bad.py:13:22:13:44 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -23,6 +31,6 @@ nodes | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | semmle.label | ControlFlowNode for unsafe_pattern | subpaths #select -| re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | re_bad.py:13:22:13:28 | ControlFlowNode for request | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:13:22:13:28 | ControlFlowNode for request | a user-provided value | re_bad.py:14:5:14:33 | ControlFlowNode for Attribute() | re.search | -| re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | re_bad.py:24:22:24:28 | ControlFlowNode for request | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:24:22:24:28 | ControlFlowNode for request | a user-provided value | re_bad.py:26:5:26:31 | ControlFlowNode for Attribute() | re.search | -| re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | re_bad.py:36:22:36:28 | ControlFlowNode for request | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:36:22:36:28 | ControlFlowNode for request | a user-provided value | re_bad.py:37:5:37:41 | ControlFlowNode for Attribute() | re.search | +| re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | re_bad.py:14:5:14:33 | ControlFlowNode for Attribute() | re.search | +| re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | re_bad.py:26:5:26:31 | ControlFlowNode for Attribute() | re.search | +| re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | re_bad.py:37:5:37:41 | ControlFlowNode for Attribute() | re.search | diff --git a/python/ql/test/query-tests/Security/CWE-776-XmlBomb/XmlBomb.expected b/python/ql/test/query-tests/Security/CWE-776-XmlBomb/XmlBomb.expected index 79ebe0bfef7..99f81737974 100644 --- a/python/ql/test/query-tests/Security/CWE-776-XmlBomb/XmlBomb.expected +++ b/python/ql/test/query-tests/Security/CWE-776-XmlBomb/XmlBomb.expected @@ -1,12 +1,18 @@ edges +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:19:19:19:25 | ControlFlowNode for request | +| test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:1:26:1:32 | GSSA Variable request | +| test.py:1:26:1:32 | GSSA Variable request | test.py:0:0:0:0 | ModuleVariableNode for test.request | | test.py:19:19:19:25 | ControlFlowNode for request | test.py:19:19:19:30 | ControlFlowNode for Attribute | | test.py:19:19:19:30 | ControlFlowNode for Attribute | test.py:19:19:19:45 | ControlFlowNode for Subscript | | test.py:19:19:19:45 | ControlFlowNode for Subscript | test.py:30:34:30:44 | ControlFlowNode for xml_content | nodes +| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| test.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | test.py:19:19:19:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test.py:19:19:19:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:19:19:19:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | test.py:30:34:30:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content | subpaths #select -| test.py:30:34:30:44 | ControlFlowNode for xml_content | test.py:19:19:19:25 | ControlFlowNode for request | test.py:30:34:30:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against uncontrolled entity expansion. | test.py:19:19:19:25 | ControlFlowNode for request | a user-provided value | +| test.py:30:34:30:44 | ControlFlowNode for xml_content | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:30:34:30:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against uncontrolled entity expansion. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected index cc55c8317e1..9de3a7c1182 100644 --- a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected +++ b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected @@ -1,4 +1,26 @@ edges +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:38:17:38:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:72:17:72:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:92:18:92:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:98:18:98:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:104:18:104:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:110:18:110:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | | 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:28 | ControlFlowNode for Attribute | @@ -79,6 +101,15 @@ edges | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:11:18:11:24 | ControlFlowNode for request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | | 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:30 | ControlFlowNode for Attribute | @@ -107,6 +138,12 @@ edges | 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:33:25:33:28 | ControlFlowNode for path | | test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | test_http_client.py:37:25:37:28 | ControlFlowNode for path | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | test_requests.py:6:18:6:24 | ControlFlowNode for request | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | test_requests.py:6:18:6:24 | ControlFlowNode for request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | +| test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | +| test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | | 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 | @@ -114,6 +151,12 @@ edges | 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:0:0:0:0 | ModuleVariableNode for full_partial_test.request | semmle.label | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | semmle.label | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | 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 | @@ -204,6 +247,12 @@ nodes | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | semmle.label | ModuleVariableNode for test_http_client.request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | semmle.label | ModuleVariableNode for test_http_client.request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | 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 | @@ -233,6 +282,12 @@ nodes | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | | test_http_client.py:33:25:33:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | test_http_client.py:37:25:37:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | semmle.label | ModuleVariableNode for test_requests.request | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | semmle.label | ModuleVariableNode for test_requests.request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | 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 | @@ -243,24 +298,22 @@ nodes | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | subpaths #select -| full_partial_test.py:10:5:10:28 | ControlFlowNode for Attribute() | 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 | -| full_partial_test.py:13:5:13:21 | ControlFlowNode for Attribute() | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:13:18:13:20 | ControlFlowNode for url | The full 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:5:19:21 | ControlFlowNode for Attribute() | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:19:18:19:20 | ControlFlowNode for url | The full 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:5:23:21 | ControlFlowNode for Attribute() | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | The full 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:5:42:21 | ControlFlowNode for Attribute() | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:42:18:42:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:45:5:45:21 | ControlFlowNode for Attribute() | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:48:5:48:21 | ControlFlowNode for Attribute() | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:48:18:48:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:51:5:51:21 | ControlFlowNode for Attribute() | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:51:18:51:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:54:5:54:21 | ControlFlowNode for Attribute() | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:54:18:54:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:62:5:62:21 | ControlFlowNode for Attribute() | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:62:18:62:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:65:5:65:21 | ControlFlowNode for Attribute() | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:65:18:65:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:76:5:76:21 | ControlFlowNode for Attribute() | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:79:5:79:21 | ControlFlowNode for Attribute() | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:79:18:79:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:82:5:82:21 | ControlFlowNode for Attribute() | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:82:18:82:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:14:5:14:36 | ControlFlowNode for Attribute() | 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:5:14:36 | ControlFlowNode for Attribute() | 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:5:14:36 | ControlFlowNode for Attribute() | 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:19:5:19:36 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:18:27:18: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:19:5:19:36 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:19:25:19: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:19:5:19:36 | ControlFlowNode for Attribute() | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:19:25:19: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:5:8:28 | ControlFlowNode for Attribute() | 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 | +| full_partial_test.py:10:5:10:28 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:13:5:13:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:13:18:13:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:19:5:19:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:19:18:19:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:23:5:23:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:42:5:42:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:42:18:42:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:45:5:45:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:48:5:48:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:48:18:48:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:51:5:51:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:51:18:51:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:54:5:54:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:54:18:54:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:62:5:62:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:62:18:62:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:65:5:65:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:65:18:65:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:76:5:76:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:79:5:79:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:79:18:79:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:82:5:82:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:82:18:82:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:14:5:14:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | The full URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:14:5:14:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:19:5:19:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | The full URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:19:5:19:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_requests.py:8:5:8:28 | ControlFlowNode for Attribute() | test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | The full URL of this request depends on $@. | test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected index 6206a070a88..7294de47bc2 100644 --- a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected +++ b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected @@ -1,4 +1,26 @@ edges +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:38:17:38:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:72:17:72:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:92:18:92:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:98:18:98:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:104:18:104:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:110:18:110:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | | 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:28 | ControlFlowNode for Attribute | @@ -79,6 +101,15 @@ edges | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:11:18:11:24 | ControlFlowNode for request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | | 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:30 | ControlFlowNode for Attribute | @@ -107,6 +138,12 @@ edges | 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:33:25:33:28 | ControlFlowNode for path | | test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | test_http_client.py:37:25:37:28 | ControlFlowNode for path | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | test_requests.py:6:18:6:24 | ControlFlowNode for request | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | test_requests.py:6:18:6:24 | ControlFlowNode for request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | +| test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | +| test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | | 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 | @@ -114,6 +151,12 @@ edges | 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:0:0:0:0 | ModuleVariableNode for full_partial_test.request | semmle.label | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | semmle.label | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | 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 | @@ -204,6 +247,12 @@ nodes | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | semmle.label | ModuleVariableNode for test_http_client.request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | semmle.label | ModuleVariableNode for test_http_client.request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | 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 | @@ -233,6 +282,12 @@ nodes | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | | test_http_client.py:33:25:33:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | test_http_client.py:37:25:37:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | semmle.label | ModuleVariableNode for test_requests.request | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | semmle.label | ModuleVariableNode for test_requests.request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | 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 | @@ -243,21 +298,15 @@ nodes | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | subpaths #select -| full_partial_test.py:68:5:68:21 | ControlFlowNode for Attribute() | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:68:18:68:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:68:5:68:21 | ControlFlowNode for Attribute() | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | full_partial_test.py:68:18:68:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:89:5:89:21 | ControlFlowNode for Attribute() | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | full_partial_test.py:89:18:89:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:95:5:95:21 | ControlFlowNode for Attribute() | full_partial_test.py:92:18:92:24 | ControlFlowNode for request | full_partial_test.py:95:18:95:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:92:18:92:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:101:5:101:21 | ControlFlowNode for Attribute() | full_partial_test.py:98:18:98:24 | ControlFlowNode for request | full_partial_test.py:101:18:101:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:98:18:98:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:107:5:107:21 | ControlFlowNode for Attribute() | full_partial_test.py:104:18:104:24 | ControlFlowNode for request | full_partial_test.py:107:18:107:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:104:18:104:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:116:5:116:21 | ControlFlowNode for Attribute() | full_partial_test.py:110:18:110:24 | ControlFlowNode for request | full_partial_test.py:116:18:116:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:110:18:110:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:122:5:122:21 | ControlFlowNode for Attribute() | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:22:5:22:31 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | 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:26:5:26:31 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | 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:5:29:36 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_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:5:29:36 | ControlFlowNode for Attribute() | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_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:33:5:33:29 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:33:25:33: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:33:5:33:29 | ControlFlowNode for Attribute() | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:33:25:33: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:33:5:33:29 | ControlFlowNode for Attribute() | test_http_client.py:11:18:11:24 | ControlFlowNode for request | test_http_client.py:33:25:33: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:37:5:37:29 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:37:25:37: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:37:5:37:29 | ControlFlowNode for Attribute() | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:37:25:37: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:37:5:37:29 | ControlFlowNode for Attribute() | test_http_client.py:11:18:11:24 | ControlFlowNode for request | test_http_client.py:37:25:37: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 | +| full_partial_test.py:68:5:68:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:68:18:68:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:89:5:89:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:89:18:89:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:95:5:95:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:95:18:95:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:101:5:101:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:101:18:101:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:107:5:107:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:107:18:107:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:116:5:116:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:116:18:116:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:122:5:122:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:22:5:22:31 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | Part of the URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:26:5:26:31 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | Part of the URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:29:5:29:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | Part of the URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:33:5:33:29 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:33:25:33:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:37:5:37:29 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:37:25:37:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | From d7be27a1c05fe1f91bd85193bb069e2e722e88dd Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Mon, 3 Oct 2022 21:19:30 +0200 Subject: [PATCH 04/82] Python: Fix experimental `py/ip-address-spoofing` I realized the modeling was done in a non-recommended way, so I changed the modeling. It was very nice that I could use API graphs for the flask part, and a little sad when I couldn't for Django/Tornado. --- .../lib/semmle/python/frameworks/Tornado.qll | 7 +- ...ClientSuppliedIpUsedInSecurityCheckLib.qll | 82 ++++++++----------- ...ientSuppliedIpUsedInSecurityCheck.expected | 8 ++ 3 files changed, 45 insertions(+), 52 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Tornado.qll b/python/ql/lib/semmle/python/frameworks/Tornado.qll index 77c60097cb5..9cf258babe9 100644 --- a/python/ql/lib/semmle/python/frameworks/Tornado.qll +++ b/python/ql/lib/semmle/python/frameworks/Tornado.qll @@ -14,10 +14,12 @@ private import semmle.python.frameworks.Stdlib private import semmle.python.frameworks.internal.InstanceTaintStepsHelper /** + * INTERNAL: Do not use. + * * Provides models for the `tornado` PyPI package. * See https://www.tornadoweb.org/en/stable/. */ -private module Tornado { +module Tornado { /** * Provides models for the `tornado.httputil.HTTPHeaders` class * @@ -126,8 +128,7 @@ private module Tornado { abstract class InstanceSource extends DataFlow::LocalSourceNode { } /** The `self` parameter in a method on the `tornado.web.RequestHandler` class or any subclass. */ - private class SelfParam extends InstanceSource, RemoteFlowSource::Range, - DataFlow::ParameterNode { + class SelfParam extends InstanceSource, RemoteFlowSource::Range, DataFlow::ParameterNode { SelfParam() { exists(RequestHandlerClass cls | cls.getAMethod().getArg(0) = this.getParameter()) } diff --git a/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll b/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll index 21e602e5d34..39b69b10004 100644 --- a/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll +++ b/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll @@ -1,73 +1,57 @@ private import python private import semmle.python.Concepts private import semmle.python.ApiGraphs -private import semmle.python.dataflow.new.RemoteFlowSources +private import semmle.python.frameworks.Flask +private import semmle.python.frameworks.Django +private import semmle.python.frameworks.Tornado /** * A data flow source of the client ip obtained according to the remote endpoint identifier specified * (`X-Forwarded-For`, `X-Real-IP`, `Proxy-Client-IP`, etc.) in the header. * * For example: `request.headers.get("X-Forwarded-For")`. + * + * A call to `request.headers.get` or `request.headers.get_all` or `request.headers.getlist`. */ -abstract class ClientSuppliedIpUsedInSecurityCheck extends DataFlow::CallCfgNode { } +abstract class ClientSuppliedIpUsedInSecurityCheck extends DataFlow::Node { } -private class FlaskClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck { +private class FlaskClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck, + DataFlow::MethodCallNode { FlaskClientSuppliedIpUsedInSecurityCheck() { - exists(RemoteFlowSource rfs, DataFlow::AttrRead get | - rfs.getSourceType() = "flask.request" and this.getFunction() = get - | - // `get` is a call to request.headers.get or request.headers.get_all or request.headers.getlist - // request.headers - get.getObject() - .(DataFlow::AttrRead) - // request - .getObject() - .getALocalSource() = rfs and - get.getAttributeName() in ["get", "get_all", "getlist"] and - get.getObject().(DataFlow::AttrRead).getAttributeName() = "headers" and - this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() - ) + this = Flask::request().getMember("headers").getMember(["get", "get_all", "getlist"]).getACall() and + this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() } } -private class DjangoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck { +private class DjangoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck, + DataFlow::MethodCallNode { DjangoClientSuppliedIpUsedInSecurityCheck() { - exists(RemoteFlowSource rfs, DataFlow::AttrRead get | - rfs.getSourceType() = "django.http.request.HttpRequest" and this.getFunction() = get - | - // `get` is a call to request.headers.get or request.META.get - // request.headers - get.getObject() - .(DataFlow::AttrRead) - // request - .getObject() - .getALocalSource() = rfs and - get.getAttributeName() = "get" and - get.getObject().(DataFlow::AttrRead).getAttributeName() in ["headers", "META"] and - this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() - ) + exists(DataFlow::Node req, DataFlow::AttrRead headers | + // a call to request.headers.get or request.META.get + req = PrivateDjango::DjangoImpl::DjangoHttp::Request::HttpRequest::instance() and + headers.getObject().getALocalSource() = req and + headers.getAttributeName() in ["headers", "META"] and + this.calls(headers, "get") + ) and + this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() } } -private class TornadoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck { +private class TornadoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck, + DataFlow::MethodCallNode { TornadoClientSuppliedIpUsedInSecurityCheck() { - exists(RemoteFlowSource rfs, DataFlow::AttrRead get | - rfs.getSourceType() = "tornado.web.RequestHandler" and this.getFunction() = get + // a call to self.request.headers.get or self.request.headers.get_list inside a tornado requesthandler + exists( + Tornado::TornadoModule::Web::RequestHandler::SelfParam selfParam, DataFlow::AttrRead headers, + DataFlow::AttrRead req | - // `get` is a call to `rfs`.request.headers.get - // `rfs`.request.headers - get.getObject() - .(DataFlow::AttrRead) - // `rfs`.request - .getObject() - .(DataFlow::AttrRead) - // `rfs` - .getObject() - .getALocalSource() = rfs and - get.getAttributeName() in ["get", "get_list"] and - get.getObject().(DataFlow::AttrRead).getAttributeName() = "headers" and - this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() - ) + req.getObject().getALocalSource() = selfParam and + req.getAttributeName() = "request" and + headers.getObject().getALocalSource() = req and + headers.getAttributeName() = "headers" and + this.calls(headers, ["get", "get_list"]) + ) and + this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() } } diff --git a/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected b/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected index fd5bbf319dc..a432cf5053f 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.expected @@ -1,8 +1,16 @@ edges +| flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip | +| flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip | | tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip | nodes +| flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip | semmle.label | ControlFlowNode for client_ip | +| flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip | semmle.label | ControlFlowNode for client_ip | | tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip | semmle.label | ControlFlowNode for client_ip | subpaths #select +| flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip | flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip | IP address spoofing might include code from $@. | flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | this user input | +| flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip | flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip | IP address spoofing might include code from $@. | flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | this user input | | tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip | tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip | IP address spoofing might include code from $@. | tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | this user input | From 33d204913c99c491db086bde686b7ab7ded45480 Mon Sep 17 00:00:00 2001 From: tyage Date: Tue, 4 Oct 2022 14:45:09 +0900 Subject: [PATCH 05/82] add test for json stringify xss --- .../XssWithAdditionalSources.expected | 30 ++++++++++++++ .../CWE-079/DomBasedXss/json-stringify.jsx | 40 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/json-stringify.jsx diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index fa65ccbe3df..e09f45e5209 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -1,4 +1,18 @@ nodes +| JsonStringify.jsx:5:9:5:36 | locale | +| JsonStringify.jsx:5:9:5:36 | locale | +| JsonStringify.jsx:5:18:5:36 | req.param("locale") | +| JsonStringify.jsx:5:18:5:36 | req.param("locale") | +| JsonStringify.jsx:5:18:5:36 | req.param("locale") | +| JsonStringify.jsx:14:18:14:60 | `https: ... ocale}` | +| JsonStringify.jsx:14:53:14:58 | locale | +| JsonStringify.jsx:22:18:22:65 | `https: ... ocale}` | +| JsonStringify.jsx:22:58:22:63 | locale | +| JsonStringify.jsx:30:40:30:45 | locale | +| JsonStringify.jsx:30:40:30:45 | locale | +| JsonStringify.jsx:30:40:30:45 | locale | +| JsonStringify.jsx:34:40:34:61 | JSON.st ... jsonLD) | +| JsonStringify.jsx:34:40:34:61 | JSON.st ... jsonLD) | | addEventListener.js:1:43:1:47 | event | | addEventListener.js:1:43:1:47 | event | | addEventListener.js:1:43:1:47 | event | @@ -1154,6 +1168,22 @@ nodes | xmlRequest.js:22:24:22:35 | json.message | | xmlRequest.js:22:24:22:35 | json.message | edges +| JsonStringify.jsx:5:9:5:36 | locale | JsonStringify.jsx:14:53:14:58 | locale | +| JsonStringify.jsx:5:9:5:36 | locale | JsonStringify.jsx:22:58:22:63 | locale | +| JsonStringify.jsx:5:9:5:36 | locale | JsonStringify.jsx:30:40:30:45 | locale | +| JsonStringify.jsx:5:9:5:36 | locale | JsonStringify.jsx:30:40:30:45 | locale | +| JsonStringify.jsx:5:9:5:36 | locale | JsonStringify.jsx:30:40:30:45 | locale | +| JsonStringify.jsx:5:9:5:36 | locale | JsonStringify.jsx:30:40:30:45 | locale | +| JsonStringify.jsx:5:18:5:36 | req.param("locale") | JsonStringify.jsx:5:9:5:36 | locale | +| JsonStringify.jsx:5:18:5:36 | req.param("locale") | JsonStringify.jsx:5:9:5:36 | locale | +| JsonStringify.jsx:5:18:5:36 | req.param("locale") | JsonStringify.jsx:5:9:5:36 | locale | +| JsonStringify.jsx:5:18:5:36 | req.param("locale") | JsonStringify.jsx:5:9:5:36 | locale | +| JsonStringify.jsx:14:18:14:60 | `https: ... ocale}` | JsonStringify.jsx:34:40:34:61 | JSON.st ... jsonLD) | +| JsonStringify.jsx:14:18:14:60 | `https: ... ocale}` | JsonStringify.jsx:34:40:34:61 | JSON.st ... jsonLD) | +| JsonStringify.jsx:14:53:14:58 | locale | JsonStringify.jsx:14:18:14:60 | `https: ... ocale}` | +| JsonStringify.jsx:22:18:22:65 | `https: ... ocale}` | JsonStringify.jsx:34:40:34:61 | JSON.st ... jsonLD) | +| JsonStringify.jsx:22:18:22:65 | `https: ... ocale}` | JsonStringify.jsx:34:40:34:61 | JSON.st ... jsonLD) | +| JsonStringify.jsx:22:58:22:63 | locale | JsonStringify.jsx:22:18:22:65 | `https: ... ocale}` | | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/json-stringify.jsx b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/json-stringify.jsx new file mode 100644 index 00000000000..8d484964ca0 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/json-stringify.jsx @@ -0,0 +1,40 @@ +var express = require("express"); +var app = express(); + +app.get("/some/path", function (req, res) { + const locale = req.param("locale"); + const jsonLD = { + "@context": "https://schema.org", + "@type": "BreadcrumbList", + itemListElement: [ + { + "@type": "ListItem", + position: 1, + item: { + "@id": `https://example.com/some?locale=${locale}`, + name: "Some", + }, + }, + { + "@type": "ListItem", + position: 2, + item: { + "@id": `https://example.com/some/path?locale=${locale}`, + name: "Real Dresses", + }, + }, + ], + }; + // OK }); From 48bdf13c8979cf5688e8c7c884f3ee03e8c60975 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 6 Oct 2022 10:11:23 +0200 Subject: [PATCH 40/82] Ruby: Take overrides into account for singleton methods defined on modules --- .../dataflow/internal/DataFlowDispatch.qll | 23 +++++++++++++++++-- .../library-tests/modules/callgraph.expected | 4 ++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index b7e9b14a910..355b235e926 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -389,7 +389,7 @@ private module Cached { // ``` exists(DataFlow::Node sourceNode, Module m | flowsToMethodCall(call, sourceNode, method) and - singletonMethodOnModule(result, method, m) + result = lookupSingletonMethod(m, method) | // ```rb // def C.singleton; end # <- result @@ -725,7 +725,10 @@ private predicate singletonMethodOnModule(MethodBase method, string name, Module selfInModule(object.(SelfVariableReadAccess).getVariable(), m) ) or - flowsToSingletonMethodObject(trackModuleAccess(m), method, name) + exists(DataFlow::LocalSourceNode sourceNode | + m = resolveConstantReadAccess(sourceNode.asExpr().getExpr()) and + flowsToSingletonMethodObject(sourceNode, method, name) + ) or exists(Module other | extendCallModule(m, other) and @@ -733,6 +736,22 @@ private predicate singletonMethodOnModule(MethodBase method, string name, Module ) } +pragma[nomagic] +private MethodBase lookupSingletonMethod(Module m, string name) { + singletonMethodOnModule(result, name, m) + or + // cannot be part of `singletonMethodOnModule` because it would introduce + // negative recursion below + exists(DataFlow::LocalSourceNode sourceNode | + sourceNode = trackModuleAccess(m) and + not m = resolveConstantReadAccess(sourceNode.asExpr().getExpr()) and + flowsToSingletonMethodObject(sourceNode, result, name) + ) + or + not singletonMethodOnModule(_, name, m) and + result = lookupSingletonMethod(m.getSuperClass(), name) +} + /** * Holds if `method` is a singleton method named `name`, defined on expression * `object`, where `object` is not likely to resolve to a module: diff --git a/ruby/ql/test/library-tests/modules/callgraph.expected b/ruby/ql/test/library-tests/modules/callgraph.expected index 4af83afbe26..df2bffe2933 100644 --- a/ruby/ql/test/library-tests/modules/callgraph.expected +++ b/ruby/ql/test/library-tests/modules/callgraph.expected @@ -161,6 +161,8 @@ getTarget | calls.rb:412:9:412:44 | call to puts | calls.rb:102:5:102:30 | puts | | calls.rb:416:1:416:29 | call to singleton1 | calls.rb:406:9:408:11 | singleton1 | | calls.rb:417:1:417:29 | call to singleton2 | calls.rb:411:5:413:7 | singleton2 | +| calls.rb:418:1:418:34 | call to call_singleton1 | calls.rb:383:9:385:11 | call_singleton1 | +| calls.rb:419:1:419:34 | call to call_singleton2 | calls.rb:392:5:394:7 | call_singleton2 | | calls.rb:424:13:424:48 | call to puts | calls.rb:102:5:102:30 | puts | | calls.rb:429:9:429:44 | call to puts | calls.rb:102:5:102:30 | puts | | calls.rb:432:13:432:48 | call to puts | calls.rb:102:5:102:30 | puts | @@ -290,8 +292,6 @@ unresolvedCall | calls.rb:274:1:274:14 | call to singleton_g | | calls.rb:276:1:276:14 | call to singleton_g | | calls.rb:313:9:313:20 | call to instance | -| calls.rb:418:1:418:34 | call to call_singleton1 | -| calls.rb:419:1:419:34 | call to call_singleton2 | | calls.rb:422:8:422:13 | call to rand | | calls.rb:422:8:422:17 | ... > ... | | calls.rb:439:9:439:10 | call to m3 | From c6b7bb436d6400f11c5fab93a821ec0f8c060f26 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 6 Oct 2022 11:25:22 +0100 Subject: [PATCH 41/82] C++: Make the ql-for-ql checks happy. --- cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql b/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql index f2ae677813a..a378d50b0df 100644 --- a/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql +++ b/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql @@ -60,11 +60,11 @@ class VarargsFunction extends Function { // the terminator is 0 or -1 result = ["0", "-1"] and // at least 80% of calls have the terminator - cnt = trailingArgValueCount(result) and - totalCount = totalCount() and + cnt = this.trailingArgValueCount(result) and + totalCount = this.totalCount() and 100 * cnt / totalCount >= 80 and // terminator value is not used in a non-terminating position - not exists(FunctionCall fc, int index | nonTrailingVarArgValue(fc, index) = result) + not exists(FunctionCall fc, int index | this.nonTrailingVarArgValue(fc, index) = result) } predicate isWhitelisted() { From 169965cfb9318dde36cc6ead8c637882a09eb948 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 6 Oct 2022 13:28:10 +0200 Subject: [PATCH 42/82] make rb/meta/taint-steps into a @kind problem query --- ruby/ql/src/queries/meta/TaintSteps.ql | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/ruby/ql/src/queries/meta/TaintSteps.ql b/ruby/ql/src/queries/meta/TaintSteps.ql index c93322500c3..dfcf2dc9e77 100644 --- a/ruby/ql/src/queries/meta/TaintSteps.ql +++ b/ruby/ql/src/queries/meta/TaintSteps.ql @@ -1,11 +1,11 @@ /** * @name Taint steps - * @description The number of default taint steps. - * @kind metric - * @metricType project - * @metricAggregate sum - * @tags meta + * @description All taint steps. + * @kind problem + * @problem.severity recommendation * @id rb/meta/taint-steps + * @tags meta + * @precision very-low */ import ruby @@ -14,4 +14,8 @@ import codeql.ruby.dataflow.internal.TaintTrackingPublic predicate relevantStep(DataFlow::Node pred, DataFlow::Node succ) { localTaintStep(pred, succ) } -select projectRoot(), count(DataFlow::Node pred, DataFlow::Node succ | relevantStep(pred, succ)) +from DataFlow::Node pred, int numOfSuccessors +where + relevantStep(pred, _) and + numOfSuccessors = count(DataFlow::Node succ | relevantStep(pred, succ)) +select pred, "Step to " + numOfSuccessors + " other nodes." From c1fae91a1f04dab306abf7832bdb0b6d4d6abd46 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 6 Oct 2022 15:19:11 +0200 Subject: [PATCH 43/82] have rb/meta/taint-steps print only one for each file, to limit the size of the output --- ruby/ql/src/queries/meta/TaintSteps.ql | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ruby/ql/src/queries/meta/TaintSteps.ql b/ruby/ql/src/queries/meta/TaintSteps.ql index dfcf2dc9e77..c86a6ba1d3a 100644 --- a/ruby/ql/src/queries/meta/TaintSteps.ql +++ b/ruby/ql/src/queries/meta/TaintSteps.ql @@ -14,8 +14,10 @@ import codeql.ruby.dataflow.internal.TaintTrackingPublic predicate relevantStep(DataFlow::Node pred, DataFlow::Node succ) { localTaintStep(pred, succ) } -from DataFlow::Node pred, int numOfSuccessors +from File file, int numSteps where - relevantStep(pred, _) and - numOfSuccessors = count(DataFlow::Node succ | relevantStep(pred, succ)) -select pred, "Step to " + numOfSuccessors + " other nodes." + numSteps = + strictcount(DataFlow::Node pred, DataFlow::Node succ | + relevantStep(pred, succ) and pred.getLocation().getFile() = file + ) +select file, "File has " + numSteps + " taint steps." From a02dcdc5e16430e93de2bc6b0d9083af1a996e5c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 7 Oct 2022 02:20:28 +0000 Subject: [PATCH 44/82] Release preparation for version 2.11.1 --- cpp/ql/lib/CHANGELOG.md | 4 ++++ cpp/ql/lib/change-notes/released/0.4.1.md | 3 +++ cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 6 +++++ .../ql/src/change-notes/released/0.4.1.md | 7 +++--- cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ++++ .../lib/change-notes/released/1.3.1.md | 3 +++ .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ++++ .../src/change-notes/released/1.3.1.md | 3 +++ .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 7 ++++++ .../2022-09-23-simpletypesanitizer.md | 4 ---- .../0.4.1.md} | 8 ++++--- csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 6 +++++ .../ql/src/change-notes/released/0.4.1.md | 9 ++++---- csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 6 +++++ .../0.3.1.md} | 7 +++--- go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 4 ++++ go/ql/src/change-notes/released/0.3.1.md | 3 +++ go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 6 +++++ .../0.4.1.md} | 7 +++--- java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 12 ++++++++++ .../change-notes/2022-08-25-path-sanitizer.md | 6 ----- .../2022-08-31-webview-dubugging.md | 4 ---- .../change-notes/2022-09-23-alert-messages.md | 4 ---- java/ql/src/change-notes/released/0.4.1.md | 11 +++++++++ java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 7 ++++++ .../0.3.1.md} | 6 ++--- javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 4 ++++ .../ql/src/change-notes/released/0.4.1.md | 3 +++ javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ++++ .../change-notes/released/0.3.1.md | 3 +++ misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 7 ++++++ .../change-notes/2022-09-22-flask-jsonify.md | 4 ---- .../0.6.1.md} | 8 ++++--- python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 4 ++++ python/ql/src/change-notes/released/0.5.1.md | 3 +++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 23 +++++++++++++++++++ .../2022-08-16-protected-methods.md | 5 ---- .../change-notes/2022-08-30-activestorage.md | 6 ----- .../lib/change-notes/2022-09-27-actionview.md | 4 ---- .../2022-09-27-activerecord-create.md | 5 ---- .../2022-09-28-actioncontroller-metal.md | 4 ---- .../2022-09-28-actioncontroller-sendfile.md | 6 ----- ...022-10-04-actionview-controller-renames.md | 11 --------- ruby/ql/lib/change-notes/released/0.4.1.md | 22 ++++++++++++++++++ ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 8 +++++++ .../0.4.1.md} | 9 ++++---- ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ++++ shared/ssa/change-notes/released/0.0.2.md | 3 +++ shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ++++ shared/typos/change-notes/released/0.0.2.md | 3 +++ shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- 88 files changed, 257 insertions(+), 127 deletions(-) create mode 100644 cpp/ql/lib/change-notes/released/0.4.1.md rename csharp/ql/src/change-notes/2022-09-29-alert-messages.md => cpp/ql/src/change-notes/released/0.4.1.md (76%) create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.1.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.1.md delete mode 100644 csharp/ql/lib/change-notes/2022-09-23-simpletypesanitizer.md rename csharp/ql/lib/change-notes/{2022-08-24-aps-net-core-controllers.md => released/0.4.1.md} (65%) rename cpp/ql/src/change-notes/2022-09-23-alert-messages.md => csharp/ql/src/change-notes/released/0.4.1.md (69%) rename go/ql/lib/change-notes/{2022-10-06-beego-request-body-source.md => released/0.3.1.md} (63%) create mode 100644 go/ql/src/change-notes/released/0.3.1.md rename java/ql/lib/change-notes/{2022-09-23-android-service-sources.md => released/0.4.1.md} (66%) delete mode 100644 java/ql/src/change-notes/2022-08-25-path-sanitizer.md delete mode 100644 java/ql/src/change-notes/2022-08-31-webview-dubugging.md delete mode 100644 java/ql/src/change-notes/2022-09-23-alert-messages.md create mode 100644 java/ql/src/change-notes/released/0.4.1.md rename javascript/ql/lib/change-notes/{2022-09-06-type-defs-squashed.md => released/0.3.1.md} (80%) create mode 100644 javascript/ql/src/change-notes/released/0.4.1.md create mode 100644 misc/suite-helpers/change-notes/released/0.3.1.md delete mode 100644 python/ql/lib/change-notes/2022-09-22-flask-jsonify.md rename python/ql/lib/change-notes/{2022-09-28-api-subscript.md => released/0.6.1.md} (69%) create mode 100644 python/ql/src/change-notes/released/0.5.1.md delete mode 100644 ruby/ql/lib/change-notes/2022-08-16-protected-methods.md delete mode 100644 ruby/ql/lib/change-notes/2022-08-30-activestorage.md delete mode 100644 ruby/ql/lib/change-notes/2022-09-27-actionview.md delete mode 100644 ruby/ql/lib/change-notes/2022-09-27-activerecord-create.md delete mode 100644 ruby/ql/lib/change-notes/2022-09-28-actioncontroller-metal.md delete mode 100644 ruby/ql/lib/change-notes/2022-09-28-actioncontroller-sendfile.md delete mode 100644 ruby/ql/lib/change-notes/2022-10-04-actionview-controller-renames.md create mode 100644 ruby/ql/lib/change-notes/released/0.4.1.md rename ruby/ql/src/change-notes/{2022-09-27-libxml-xxe.md => released/0.4.1.md} (80%) create mode 100644 shared/ssa/change-notes/released/0.0.2.md create mode 100644 shared/typos/change-notes/released/0.0.2.md diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index f1dfa53f9ba..5ccbbd8592c 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.1 + +No user-facing changes. + ## 0.4.0 ### Deprecated APIs diff --git a/cpp/ql/lib/change-notes/released/0.4.1.md b/cpp/ql/lib/change-notes/released/0.4.1.md new file mode 100644 index 00000000000..0d865d0571e --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.4.1.md @@ -0,0 +1,3 @@ +## 0.4.1 + +No user-facing changes. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index cb70ba272d3..2746ed855a3 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.4.1-dev +version: 0.4.1 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 54dec3b197f..8da02215877 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. + ## 0.4.0 ### New Queries diff --git a/csharp/ql/src/change-notes/2022-09-29-alert-messages.md b/cpp/ql/src/change-notes/released/0.4.1.md similarity index 76% rename from csharp/ql/src/change-notes/2022-09-29-alert-messages.md rename to cpp/ql/src/change-notes/released/0.4.1.md index c6ce24514b8..f5e1dbf00ed 100644 --- a/csharp/ql/src/change-notes/2022-09-29-alert-messages.md +++ b/cpp/ql/src/change-notes/released/0.4.1.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.4.1 + +### Minor Analysis Improvements + * The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 12c12ffe83e..5bb1b4e6c67 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.4.1-dev +version: 0.4.1 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 49d355ec453..afbbf19794a 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.1 + +No user-facing changes. + ## 1.3.0 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.1.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.1.md new file mode 100644 index 00000000000..8dd9964197c --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.1.md @@ -0,0 +1,3 @@ +## 1.3.1 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index ec16350ed6f..e71b6d081f1 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.0 +lastReleaseVersion: 1.3.1 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 648df77d7ff..2bf4479335c 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.3.1-dev +version: 1.3.1 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 49d355ec453..afbbf19794a 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.1 + +No user-facing changes. + ## 1.3.0 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.1.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.1.md new file mode 100644 index 00000000000..8dd9964197c --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.1.md @@ -0,0 +1,3 @@ +## 1.3.1 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index ec16350ed6f..e71b6d081f1 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.0 +lastReleaseVersion: 1.3.1 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 940cdf055f8..d2bd8afddf1 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.3.1-dev +version: 1.3.1 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 83b9e7b837c..c303fa86a4a 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* `DateTime` expressions are now considered simple type sanitizers. This affects a wide range of security queries. +* ASP.NET Core controller definition has been made more precise. The amount of introduced taint sources or eliminated false positives should be low though, since the most common pattern is to derive all user defined ASP.NET Core controllers from the standard Controller class, which is not affected. + ## 0.4.0 ### Deprecated APIs diff --git a/csharp/ql/lib/change-notes/2022-09-23-simpletypesanitizer.md b/csharp/ql/lib/change-notes/2022-09-23-simpletypesanitizer.md deleted file mode 100644 index a4d7e4cde7a..00000000000 --- a/csharp/ql/lib/change-notes/2022-09-23-simpletypesanitizer.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* `DateTime` expressions are now considered simple type sanitizers. This affects a wide range of security queries. \ No newline at end of file diff --git a/csharp/ql/lib/change-notes/2022-08-24-aps-net-core-controllers.md b/csharp/ql/lib/change-notes/released/0.4.1.md similarity index 65% rename from csharp/ql/lib/change-notes/2022-08-24-aps-net-core-controllers.md rename to csharp/ql/lib/change-notes/released/0.4.1.md index b3b5006bc57..f3bdef7797c 100644 --- a/csharp/ql/lib/change-notes/2022-08-24-aps-net-core-controllers.md +++ b/csharp/ql/lib/change-notes/released/0.4.1.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.4.1 + +### Minor Analysis Improvements + +* `DateTime` expressions are now considered simple type sanitizers. This affects a wide range of security queries. * ASP.NET Core controller definition has been made more precise. The amount of introduced taint sources or eliminated false positives should be low though, since the most common pattern is to derive all user defined ASP.NET Core controllers from the standard Controller class, which is not affected. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 270ae8a65aa..5d5e75ad307 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.4.1-dev +version: 0.4.1 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index bf47d9f7f70..8bd7652a52c 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. + ## 0.4.0 ### Minor Analysis Improvements diff --git a/cpp/ql/src/change-notes/2022-09-23-alert-messages.md b/csharp/ql/src/change-notes/released/0.4.1.md similarity index 69% rename from cpp/ql/src/change-notes/2022-09-23-alert-messages.md rename to csharp/ql/src/change-notes/released/0.4.1.md index de46b7752eb..f5e1dbf00ed 100644 --- a/cpp/ql/src/change-notes/2022-09-23-alert-messages.md +++ b/csharp/ql/src/change-notes/released/0.4.1.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- -* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. \ No newline at end of file +## 0.4.1 + +### Minor Analysis Improvements + +* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index e2721c02552..2a80e25d0b6 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.4.1-dev +version: 0.4.1 groups: - csharp - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 1f851cdf663..c38ebde0723 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.1 + +### Minor Analysis Improvements + +* Added support for `BeegoInput.RequestBody` as a source of untrusted data. + ## 0.3.0 ### Deprecated APIs diff --git a/go/ql/lib/change-notes/2022-10-06-beego-request-body-source.md b/go/ql/lib/change-notes/released/0.3.1.md similarity index 63% rename from go/ql/lib/change-notes/2022-10-06-beego-request-body-source.md rename to go/ql/lib/change-notes/released/0.3.1.md index 9980b0aadd2..be16eed5d3e 100644 --- a/go/ql/lib/change-notes/2022-10-06-beego-request-body-source.md +++ b/go/ql/lib/change-notes/released/0.3.1.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.3.1 + +### Minor Analysis Improvements + * Added support for `BeegoInput.RequestBody` as a source of untrusted data. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 8025056129c..cd565f720c5 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.3.1-dev +version: 0.3.1 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 47dabdb2d2e..68880b18281 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.1 + +No user-facing changes. + ## 0.3.0 ### Query Metadata Changes diff --git a/go/ql/src/change-notes/released/0.3.1.md b/go/ql/src/change-notes/released/0.3.1.md new file mode 100644 index 00000000000..9fd4efd6c80 --- /dev/null +++ b/go/ql/src/change-notes/released/0.3.1.md @@ -0,0 +1,3 @@ +## 0.3.1 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index f454b5ce9d9..4a85f9fe6f3 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.3.1-dev +version: 0.3.1 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 0f9512eabda..2724a6d3cef 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* Added external flow sources for the intents received in exported Android services. + ## 0.4.0 ### Breaking Changes diff --git a/java/ql/lib/change-notes/2022-09-23-android-service-sources.md b/java/ql/lib/change-notes/released/0.4.1.md similarity index 66% rename from java/ql/lib/change-notes/2022-09-23-android-service-sources.md rename to java/ql/lib/change-notes/released/0.4.1.md index 812ff07422d..866a6cf524b 100644 --- a/java/ql/lib/change-notes/2022-09-23-android-service-sources.md +++ b/java/ql/lib/change-notes/released/0.4.1.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.4.1 + +### Minor Analysis Improvements + * Added external flow sources for the intents received in exported Android services. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index df1ad196123..3d5ea96dcc0 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.4.1-dev +version: 0.4.1 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 4f6633176f4..055d1327b06 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.4.1 + +### New Queries + +* Added a new query, `java/android/webview-debugging-enabled`, to detect instances of WebView debugging being enabled in production builds. + +### Minor Analysis Improvements + +* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. +* `PathSanitizer.qll` has been promoted from experimental to the main query pack. This sanitizer was originally [submitted as part of an experimental query by @luchua-bc](https://github.com/github/codeql/pull/7286). +* The queries `java/path-injection`, `java/path-injection-local` and `java/zipslip` now use the sanitizers provided by `PathSanitizer.qll`. + ## 0.4.0 ### New Queries diff --git a/java/ql/src/change-notes/2022-08-25-path-sanitizer.md b/java/ql/src/change-notes/2022-08-25-path-sanitizer.md deleted file mode 100644 index a883561d59c..00000000000 --- a/java/ql/src/change-notes/2022-08-25-path-sanitizer.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: minorAnalysis ---- - -* `PathSanitizer.qll` has been promoted from experimental to the main query pack. This sanitizer was originally [submitted as part of an experimental query by @luchua-bc](https://github.com/github/codeql/pull/7286). -* The queries `java/path-injection`, `java/path-injection-local` and `java/zipslip` now use the sanitizers provided by `PathSanitizer.qll`. \ No newline at end of file diff --git a/java/ql/src/change-notes/2022-08-31-webview-dubugging.md b/java/ql/src/change-notes/2022-08-31-webview-dubugging.md deleted file mode 100644 index 8e6295efeb3..00000000000 --- a/java/ql/src/change-notes/2022-08-31-webview-dubugging.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: newQuery ---- -* Added a new query, `java/android/webview-debugging-enabled`, to detect instances of WebView debugging being enabled in production builds. \ No newline at end of file diff --git a/java/ql/src/change-notes/2022-09-23-alert-messages.md b/java/ql/src/change-notes/2022-09-23-alert-messages.md deleted file mode 100644 index de46b7752eb..00000000000 --- a/java/ql/src/change-notes/2022-09-23-alert-messages.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. \ No newline at end of file diff --git a/java/ql/src/change-notes/released/0.4.1.md b/java/ql/src/change-notes/released/0.4.1.md new file mode 100644 index 00000000000..0ac482407a7 --- /dev/null +++ b/java/ql/src/change-notes/released/0.4.1.md @@ -0,0 +1,11 @@ +## 0.4.1 + +### New Queries + +* Added a new query, `java/android/webview-debugging-enabled`, to detect instances of WebView debugging being enabled in production builds. + +### Minor Analysis Improvements + +* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. +* `PathSanitizer.qll` has been promoted from experimental to the main query pack. This sanitizer was originally [submitted as part of an experimental query by @luchua-bc](https://github.com/github/codeql/pull/7286). +* The queries `java/path-injection`, `java/path-injection-local` and `java/zipslip` now use the sanitizers provided by `PathSanitizer.qll`. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 5f93a953ea6..1377facc607 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.4.1-dev +version: 0.4.1 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index d85a14dca02..de3424c2f4d 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.3.1 + +### Minor Analysis Improvements + +- Several of the SQL and NoSQL library models have improved, leading to more results for the `js/sql-injection` query, + and in some cases the `js/missing-rate-limiting` query. + ## 0.3.0 ### Breaking Changes diff --git a/javascript/ql/lib/change-notes/2022-09-06-type-defs-squashed.md b/javascript/ql/lib/change-notes/released/0.3.1.md similarity index 80% rename from javascript/ql/lib/change-notes/2022-09-06-type-defs-squashed.md rename to javascript/ql/lib/change-notes/released/0.3.1.md index 9e628b394dc..81c8ef9fcff 100644 --- a/javascript/ql/lib/change-notes/2022-09-06-type-defs-squashed.md +++ b/javascript/ql/lib/change-notes/released/0.3.1.md @@ -1,6 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.3.1 + +### Minor Analysis Improvements - Several of the SQL and NoSQL library models have improved, leading to more results for the `js/sql-injection` query, and in some cases the `js/missing-rate-limiting` query. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 0cf4b33407a..5fe7be54a20 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.3.1-dev +version: 0.3.1 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index a5e41a1e50a..b166176b56f 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.1 + +No user-facing changes. + ## 0.4.0 ### Minor Analysis Improvements diff --git a/javascript/ql/src/change-notes/released/0.4.1.md b/javascript/ql/src/change-notes/released/0.4.1.md new file mode 100644 index 00000000000..0d865d0571e --- /dev/null +++ b/javascript/ql/src/change-notes/released/0.4.1.md @@ -0,0 +1,3 @@ +## 0.4.1 + +No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 44ac00e5caf..9a7548cadb1 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.4.1-dev +version: 0.4.1 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 6bd73620860..c93557f5801 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.1 + +No user-facing changes. + ## 0.3.0 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/0.3.1.md b/misc/suite-helpers/change-notes/released/0.3.1.md new file mode 100644 index 00000000000..9fd4efd6c80 --- /dev/null +++ b/misc/suite-helpers/change-notes/released/0.3.1.md @@ -0,0 +1,3 @@ +## 0.3.1 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index aa0a2693b1d..911d334cc09 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.3.1-dev +version: 0.3.1 groups: shared diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 962c7b5d023..10707d9d391 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.6.1 + +### Minor Analysis Improvements + +* Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for reponse objects). +* Added modeling of creating Flask responses with `flask.jsonify`. + ## 0.6.0 ### Deprecated APIs diff --git a/python/ql/lib/change-notes/2022-09-22-flask-jsonify.md b/python/ql/lib/change-notes/2022-09-22-flask-jsonify.md deleted file mode 100644 index cac16e270f4..00000000000 --- a/python/ql/lib/change-notes/2022-09-22-flask-jsonify.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added modeling of creating Flask responses with `flask.jsonify`. diff --git a/python/ql/lib/change-notes/2022-09-28-api-subscript.md b/python/ql/lib/change-notes/released/0.6.1.md similarity index 69% rename from python/ql/lib/change-notes/2022-09-28-api-subscript.md rename to python/ql/lib/change-notes/released/0.6.1.md index f14b59d643b..e4ca9748e5f 100644 --- a/python/ql/lib/change-notes/2022-09-28-api-subscript.md +++ b/python/ql/lib/change-notes/released/0.6.1.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.6.1 + +### Minor Analysis Improvements + * Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for reponse objects). +* Added modeling of creating Flask responses with `flask.jsonify`. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index a3f820f884d..80fb0899f64 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.0 +lastReleaseVersion: 0.6.1 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 6121fdace8c..2104997ba95 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.6.1-dev +version: 0.6.1 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index b26aede7b0b..aaf184f4e7c 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.1 + +No user-facing changes. + ## 0.5.0 ### Query Metadata Changes diff --git a/python/ql/src/change-notes/released/0.5.1.md b/python/ql/src/change-notes/released/0.5.1.md new file mode 100644 index 00000000000..0275d38f63c --- /dev/null +++ b/python/ql/src/change-notes/released/0.5.1.md @@ -0,0 +1,3 @@ +## 0.5.1 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index 30e271c5361..0bf7024c337 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.0 +lastReleaseVersion: 0.5.1 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 6e3e2010677..4f57ea416ec 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.5.1-dev +version: 0.5.1 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 1a96d857e7f..677403b9a16 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,26 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* The following classes have been moved from `codeql.ruby.frameworks.ActionController` to `codeql.ruby.frameworks.Rails`: + * `ParamsCall`, now accessed as `Rails::ParamsCall`. + * `CookieCall`, now accessed as `Rails::CookieCall`. +* The following classes have been moved from `codeql.ruby.frameworks.ActionView` to `codeql.ruby.frameworks.Rails`: + * `HtmlSafeCall`, now accessed as `Rails::HtmlSafeCall`. + * `HtmlEscapeCall`, now accessed as `Rails::HtmlEscapeCall`. + * `RenderCall`, now accessed as `Rails::RenderCall`. + * `RenderToCall`, now accessed as `Rails::RenderToCall`. +* Subclasses of `ActionController::Metal` are now recognised as controllers. +* `ActionController::DataStreaming::send_file` is now recognized as a + `FileSystemAccess`. +* Various XSS sinks in the ActionView library are now recognized. +* Calls to `ActiveRecord::Base.create` are now recognized as model + instantiations. +* Various code executions, command executions and HTTP requests in the + ActiveStorage library are now recognized. +* `MethodBase` now has two new predicates related to visibility: `isPublic` and + `isProtected`. These hold, respectively, if the method is public or protected. + ## 0.4.0 ### Breaking Changes diff --git a/ruby/ql/lib/change-notes/2022-08-16-protected-methods.md b/ruby/ql/lib/change-notes/2022-08-16-protected-methods.md deleted file mode 100644 index 7647517c06c..00000000000 --- a/ruby/ql/lib/change-notes/2022-08-16-protected-methods.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* `MethodBase` now has two new predicates related to visibility: `isPublic` and - `isProtected`. These hold, respectively, if the method is public or protected. diff --git a/ruby/ql/lib/change-notes/2022-08-30-activestorage.md b/ruby/ql/lib/change-notes/2022-08-30-activestorage.md deleted file mode 100644 index b5ab9e34479..00000000000 --- a/ruby/ql/lib/change-notes/2022-08-30-activestorage.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: minorAnalysis ---- -* Various code executions, command executions and HTTP requests in the - ActiveStorage library are now recognized. - diff --git a/ruby/ql/lib/change-notes/2022-09-27-actionview.md b/ruby/ql/lib/change-notes/2022-09-27-actionview.md deleted file mode 100644 index d8f392971ad..00000000000 --- a/ruby/ql/lib/change-notes/2022-09-27-actionview.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Various XSS sinks in the ActionView library are now recognized. diff --git a/ruby/ql/lib/change-notes/2022-09-27-activerecord-create.md b/ruby/ql/lib/change-notes/2022-09-27-activerecord-create.md deleted file mode 100644 index b16da83f611..00000000000 --- a/ruby/ql/lib/change-notes/2022-09-27-activerecord-create.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* Calls to `ActiveRecord::Base.create` are now recognized as model - instantiations. diff --git a/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-metal.md b/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-metal.md deleted file mode 100644 index 4d4e2fef174..00000000000 --- a/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-metal.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Subclasses of `ActionController::Metal` are now recognised as controllers. diff --git a/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-sendfile.md b/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-sendfile.md deleted file mode 100644 index 93bf546f4a5..00000000000 --- a/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-sendfile.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: minorAnalysis ---- -* `ActionController::DataStreaming::send_file` is now recognized as a - `FileSystemAccess`. - diff --git a/ruby/ql/lib/change-notes/2022-10-04-actionview-controller-renames.md b/ruby/ql/lib/change-notes/2022-10-04-actionview-controller-renames.md deleted file mode 100644 index f269442dcf4..00000000000 --- a/ruby/ql/lib/change-notes/2022-10-04-actionview-controller-renames.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -category: minorAnalysis ---- -* The following classes have been moved from `codeql.ruby.frameworks.ActionController` to `codeql.ruby.frameworks.Rails`: - * `ParamsCall`, now accessed as `Rails::ParamsCall`. - * `CookieCall`, now accessed as `Rails::CookieCall`. -* The following classes have been moved from `codeql.ruby.frameworks.ActionView` to `codeql.ruby.frameworks.Rails`: - * `HtmlSafeCall`, now accessed as `Rails::HtmlSafeCall`. - * `HtmlEscapeCall`, now accessed as `Rails::HtmlEscapeCall`. - * `RenderCall`, now accessed as `Rails::RenderCall`. - * `RenderToCall`, now accessed as `Rails::RenderToCall`. diff --git a/ruby/ql/lib/change-notes/released/0.4.1.md b/ruby/ql/lib/change-notes/released/0.4.1.md new file mode 100644 index 00000000000..9c492f4ac7e --- /dev/null +++ b/ruby/ql/lib/change-notes/released/0.4.1.md @@ -0,0 +1,22 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* The following classes have been moved from `codeql.ruby.frameworks.ActionController` to `codeql.ruby.frameworks.Rails`: + * `ParamsCall`, now accessed as `Rails::ParamsCall`. + * `CookieCall`, now accessed as `Rails::CookieCall`. +* The following classes have been moved from `codeql.ruby.frameworks.ActionView` to `codeql.ruby.frameworks.Rails`: + * `HtmlSafeCall`, now accessed as `Rails::HtmlSafeCall`. + * `HtmlEscapeCall`, now accessed as `Rails::HtmlEscapeCall`. + * `RenderCall`, now accessed as `Rails::RenderCall`. + * `RenderToCall`, now accessed as `Rails::RenderToCall`. +* Subclasses of `ActionController::Metal` are now recognised as controllers. +* `ActionController::DataStreaming::send_file` is now recognized as a + `FileSystemAccess`. +* Various XSS sinks in the ActionView library are now recognized. +* Calls to `ActiveRecord::Base.create` are now recognized as model + instantiations. +* Various code executions, command executions and HTTP requests in the + ActiveStorage library are now recognized. +* `MethodBase` now has two new predicates related to visibility: `isPublic` and + `isProtected`. These hold, respectively, if the method is public or protected. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 97c480b8f6e..8010fd63a50 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.4.1-dev +version: 0.4.1 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index e45d4e8c250..6792b3e61c0 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* The `rb/xxe` query has been updated to add the following sinks for XML external entity expansion: + 1. Calls to parse XML using `LibXML` when its `default_substitute_entities` option is enabled. + 2. Uses of the Rails methods `ActiveSupport::XmlMini.parse`, `Hash.from_xml`, and `Hash.from_trusted_xml` when `ActiveSupport::XmlMini` is configured to use `LibXML` as its backend, and its `default_substitute_entities` option is enabled. + ## 0.4.0 ### New Queries diff --git a/ruby/ql/src/change-notes/2022-09-27-libxml-xxe.md b/ruby/ql/src/change-notes/released/0.4.1.md similarity index 80% rename from ruby/ql/src/change-notes/2022-09-27-libxml-xxe.md rename to ruby/ql/src/change-notes/released/0.4.1.md index a3084c62f2a..a3ee4612257 100644 --- a/ruby/ql/src/change-notes/2022-09-27-libxml-xxe.md +++ b/ruby/ql/src/change-notes/released/0.4.1.md @@ -1,6 +1,7 @@ ---- -category: minorAnalysis ---- +## 0.4.1 + +### Minor Analysis Improvements + * The `rb/xxe` query has been updated to add the following sinks for XML external entity expansion: 1. Calls to parse XML using `LibXML` when its `default_substitute_entities` option is enabled. - 2. Uses of the Rails methods `ActiveSupport::XmlMini.parse`, `Hash.from_xml`, and `Hash.from_trusted_xml` when `ActiveSupport::XmlMini` is configured to use `LibXML` as its backend, and its `default_substitute_entities` option is enabled. \ No newline at end of file + 2. Uses of the Rails methods `ActiveSupport::XmlMini.parse`, `Hash.from_xml`, and `Hash.from_trusted_xml` when `ActiveSupport::XmlMini` is configured to use `LibXML` as its backend, and its `default_substitute_entities` option is enabled. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 66f006ac2d5..344a7b03f93 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.4.1-dev +version: 0.4.1 groups: - ruby - queries diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index 2c547c365ec..9f2cb351ed0 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2 + +No user-facing changes. + ## 0.0.1 * Initial release. Extracted common SSA code into a library pack to share code between languages. diff --git a/shared/ssa/change-notes/released/0.0.2.md b/shared/ssa/change-notes/released/0.0.2.md new file mode 100644 index 00000000000..5ab250998ed --- /dev/null +++ b/shared/ssa/change-notes/released/0.0.2.md @@ -0,0 +1,3 @@ +## 0.0.2 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index c6933410b71..55dc06fbd76 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.1 +lastReleaseVersion: 0.0.2 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index ef21714c8b8..54bf861fa2e 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/ssa -version: 0.0.2-dev +version: 0.0.2 groups: shared library: true diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 95a5c570ac0..82994494b53 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2 + +No user-facing changes. + ## 0.0.1 * Initial release. Share the database of common typographical errors between languages. diff --git a/shared/typos/change-notes/released/0.0.2.md b/shared/typos/change-notes/released/0.0.2.md new file mode 100644 index 00000000000..5ab250998ed --- /dev/null +++ b/shared/typos/change-notes/released/0.0.2.md @@ -0,0 +1,3 @@ +## 0.0.2 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index c6933410b71..55dc06fbd76 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.1 +lastReleaseVersion: 0.0.2 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 587537220ec..3b52e2e07fb 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/typos -version: 0.0.2-dev +version: 0.0.2 groups: shared library: true From e9a304bad03176d2b62ed77e6292d5f146509dc3 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Fri, 7 Oct 2022 09:12:36 +0200 Subject: [PATCH 45/82] Kotlin: Add test for exposed internal representation --- .../ExposeRepresentation/ExposeRepresentation.expected | 1 + .../ExposeRepresentation/ExposeRepresentation.qlref | 1 + .../kotlin/query-tests/ExposeRepresentation/ExposesRep.kt | 3 +++ java/ql/test/kotlin/query-tests/ExposeRepresentation/User.kt | 5 +++++ 4 files changed, 10 insertions(+) create mode 100644 java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.expected create mode 100644 java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.qlref create mode 100644 java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposesRep.kt create mode 100644 java/ql/test/kotlin/query-tests/ExposeRepresentation/User.kt diff --git a/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.expected b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.expected new file mode 100644 index 00000000000..64b3f15ca4e --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.expected @@ -0,0 +1 @@ +| ExposesRep.kt:2:5:2:49 | getStrings | getStrings exposes the internal representation stored in field strings. The value may be modified $@. | User.kt:3:12:3:18 | User.kt:3:12:3:18 | after this call to getStrings | diff --git a/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.qlref b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.qlref new file mode 100644 index 00000000000..6452bb942d2 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.qlref @@ -0,0 +1 @@ +Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql diff --git a/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposesRep.kt b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposesRep.kt new file mode 100644 index 00000000000..04d8f8f588d --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposesRep.kt @@ -0,0 +1,3 @@ +class ExposesRep { + val strings: Array = arrayOfNulls(1) +} diff --git a/java/ql/test/kotlin/query-tests/ExposeRepresentation/User.kt b/java/ql/test/kotlin/query-tests/ExposeRepresentation/User.kt new file mode 100644 index 00000000000..aac812be0d0 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ExposeRepresentation/User.kt @@ -0,0 +1,5 @@ +class User { + fun test1(er: ExposesRep) { + er.strings[0] = "Hello world" + } +} From cd64faf635b207d84f5d680bf6f1aa85ead0a4f3 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Fri, 7 Oct 2022 09:13:10 +0200 Subject: [PATCH 46/82] Kotlin: ignore properties in `java/internal-representation-exposure` check --- .../Implementation Hiding/ExposeRepresentation.ql | 8 ++++++-- .../ExposeRepresentation/ExposeRepresentation.expected | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql b/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql index 8fe3d4e6ba6..9f24744fa0c 100644 --- a/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql +++ b/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql @@ -120,8 +120,12 @@ predicate exposesByStore(Callable c, Field f, Expr why, string whyText) { from Callable c, Field f, Expr why, string whyText where - exposesByReturn(c, f, why, whyText) or - exposesByStore(c, f, why, whyText) + ( + exposesByReturn(c, f, why, whyText) or + exposesByStore(c, f, why, whyText) + ) and + // Kotlin properties expose internal representation, but it's not accidental, so ignore them + not exists(Property p | p.getBackingField() = f) select c, c.getName() + " exposes the internal representation stored in field " + f.getName() + ". The value may be modified $@.", why.getLocation(), whyText diff --git a/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.expected b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.expected index 64b3f15ca4e..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.expected +++ b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.expected @@ -1 +0,0 @@ -| ExposesRep.kt:2:5:2:49 | getStrings | getStrings exposes the internal representation stored in field strings. The value may be modified $@. | User.kt:3:12:3:18 | User.kt:3:12:3:18 | after this call to getStrings | From f7f12076df9f3d88ebcc8b1a8c9014b67100546d Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Fri, 7 Oct 2022 09:22:06 +0200 Subject: [PATCH 47/82] Kotlin: Add test case for `::class` type check in `equals` --- .../MissingInstanceofInEquals.expected | 1 + .../kotlin/query-tests/MissingInstanceofInEquals/Test.kt | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/MissingInstanceofInEquals.expected b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/MissingInstanceofInEquals.expected index e69de29bb2d..304a0f245be 100644 --- a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/MissingInstanceofInEquals.expected +++ b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/MissingInstanceofInEquals.expected @@ -0,0 +1 @@ +| Test.kt:10:14:12:5 | equals | This 'equals()' method does not check argument type. | diff --git a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt index 7e8fa2619e2..f6252b5d3f2 100644 --- a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt +++ b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt @@ -5,3 +5,9 @@ data class E(val x: Int) { return (other as? E)?.x == this.x } } + +data class F(val x: Int) { + override fun equals(other: Any?): Boolean { + return other != null && other::class == this::class + } +} From 51f9314a50fbf081a8521ddc08a9cc48ae7b8a44 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Fri, 7 Oct 2022 09:22:57 +0200 Subject: [PATCH 48/82] Kotlin: Consider `::class` type check in `equals` --- java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql | 2 ++ .../MissingInstanceofInEquals.expected | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql index 999edaa0b38..1f05298878a 100644 --- a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql +++ b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql @@ -30,6 +30,8 @@ predicate hasTypeTest(Variable v) { or any(SafeCastExpr sce).getExpr() = v.getAnAccess() or + any(ClassExpr c).getExpr() = v.getAnAccess() + or exists(MethodAccess ma | ma.getMethod().getName() = "getClass" and ma.getQualifier() = v.getAnAccess() diff --git a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/MissingInstanceofInEquals.expected b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/MissingInstanceofInEquals.expected index 304a0f245be..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/MissingInstanceofInEquals.expected +++ b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/MissingInstanceofInEquals.expected @@ -1 +0,0 @@ -| Test.kt:10:14:12:5 | equals | This 'equals()' method does not check argument type. | From f51c13f0c160e00b9b56999abfb5d077f96ea22b Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Fri, 7 Oct 2022 09:32:00 +0200 Subject: [PATCH 49/82] Kotlin: Recognize generated files --- java/ql/lib/semmle/code/java/GeneratedFiles.qll | 11 +++++++++-- .../library-tests/GeneratedFiles/Generated.expected | 2 ++ .../kotlin/library-tests/GeneratedFiles/Generated.kt | 3 +++ .../kotlin/library-tests/GeneratedFiles/Generated.ql | 4 ++++ .../library-tests/GeneratedFiles/NonGenerated.kt | 3 +++ .../GeneratedFiles/generated/source/NonGenerated.kt | 1 + .../GeneratedFiles/generated/source/kapt/Generated.kt | 1 + 7 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.expected create mode 100644 java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.kt create mode 100644 java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.ql create mode 100644 java/ql/test/kotlin/library-tests/GeneratedFiles/NonGenerated.kt create mode 100644 java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/NonGenerated.kt create mode 100644 java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/kapt/Generated.kt diff --git a/java/ql/lib/semmle/code/java/GeneratedFiles.qll b/java/ql/lib/semmle/code/java/GeneratedFiles.qll index a7d1ae628f0..cfd72e02938 100644 --- a/java/ql/lib/semmle/code/java/GeneratedFiles.qll +++ b/java/ql/lib/semmle/code/java/GeneratedFiles.qll @@ -51,9 +51,9 @@ library class MarkerCommentGeneratedFile extends GeneratedFile { /** * A marker comment that indicates that it is in a generated file. */ -private class GeneratedFileMarker extends Top instanceof JavadocElement { +private class GeneratedFileMarker extends Top { GeneratedFileMarker() { - exists(string msg | msg = this.getText() | + exists(string msg | msg = this.(JavadocElement).getText() or msg = this.(KtComment).getText() | msg.regexpMatch("(?i).*\\bGenerated By\\b.*\\bDo not edit\\b.*") or msg.regexpMatch("(?i).*\\bThis (file|class|interface|art[ei]fact) (was|is|(has been)) (?:auto[ -]?)?gener(e?)ated.*") or msg.regexpMatch("(?i).*\\bAny modifications to this file will be lost\\b.*") or @@ -65,3 +65,10 @@ private class GeneratedFileMarker extends Top instanceof JavadocElement { ) } } + +/** + * A file detected as generated by the Kotlin Annotation Processing Tool (kapt). Detection is based on file path. + */ +private class KaptFile extends GeneratedFile { + KaptFile() { this.getRelativePath().matches("%/generated/source/kapt%") } +} diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.expected b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.expected new file mode 100644 index 00000000000..0a5b4c6ff29 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.expected @@ -0,0 +1,2 @@ +| Generated.kt:0:0:0:0 | Generated | +| generated/source/kapt/Generated.kt:0:0:0:0 | Generated | diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.kt b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.kt new file mode 100644 index 00000000000..4aa496a1b7d --- /dev/null +++ b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.kt @@ -0,0 +1,3 @@ +// This file was auto generated by me + +class B \ No newline at end of file diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.ql b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.ql new file mode 100644 index 00000000000..131acde1993 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.ql @@ -0,0 +1,4 @@ +import java + +from GeneratedFile f +select f diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/NonGenerated.kt b/java/ql/test/kotlin/library-tests/GeneratedFiles/NonGenerated.kt new file mode 100644 index 00000000000..4fd8af3f7a3 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/GeneratedFiles/NonGenerated.kt @@ -0,0 +1,3 @@ +// This file was not generated + +class A \ No newline at end of file diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/NonGenerated.kt b/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/NonGenerated.kt new file mode 100644 index 00000000000..a7f289eeb2f --- /dev/null +++ b/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/NonGenerated.kt @@ -0,0 +1 @@ +class D \ No newline at end of file diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/kapt/Generated.kt b/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/kapt/Generated.kt new file mode 100644 index 00000000000..9dccdd5e595 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/kapt/Generated.kt @@ -0,0 +1 @@ +class C \ No newline at end of file From 69fc59930fa25ac322d094da6bd34b8c85fbf6d8 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 7 Oct 2022 10:55:30 +0200 Subject: [PATCH 50/82] Ruby: Add ql doc to `lookupSingletonMethod` --- .../ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index 355b235e926..f988ea43779 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -736,6 +736,10 @@ private predicate singletonMethodOnModule(MethodBase method, string name, Module ) } +/** + * Holds if `method` is a singleton method named `name`, defined on module + * `m`, or any transitive base class of `m`. + */ pragma[nomagic] private MethodBase lookupSingletonMethod(Module m, string name) { singletonMethodOnModule(result, name, m) From a30b7120a706df9ffbb9a1549d5d89df8fc15a74 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 7 Oct 2022 11:17:39 +0200 Subject: [PATCH 51/82] fix some more style-guide violations in the alert-messages --- .../src/experimental/CWE-099/TaintedWebClient.ql | 4 ++-- ...ated-security-validations-always-return-true.ql | 5 +++-- .../backdoor/ProcessNameToHashTaintFlow.ql | 4 ++-- ...ecurity-validations-always-return-true.expected | 14 +++++++------- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql b/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql index 513c658cf92..8cee95a3d54 100644 --- a/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql +++ b/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql @@ -19,5 +19,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "$@ flows to here and is used in a method of WebClient.", - source.getNode(), "User-provided value" +select sink.getNode(), source, sink, "A method of WebClient depepends on a $@.", source.getNode(), + "user-provided value" diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql index 57561944718..753dfb82999 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql @@ -17,5 +17,6 @@ import JsonWebTokenHandlerLib from TokenValidationParametersProperty p, CallableAlwaysReturnsTrueHigherPrecision e where e = p.getAnAssignedValue() -select e, "JsonWebTokenHandler security-sensitive property $@ is being delegated to $@.", p, - p.getQualifiedName().toString(), e, "a callable that always returns \"true\"" +select e, + "JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns \"true\".", + p, p.getQualifiedName().toString() diff --git a/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql b/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql index 14d0cc02e44..5bb8a1dc6e9 100644 --- a/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql +++ b/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql @@ -50,5 +50,5 @@ predicate isSuspiciousPropertyName(PropertyRead pr) { from DataFlow::PathNode src, DataFlow::PathNode sink, DataFlowFromMethodToHash conf where conf.hasFlow(src.getNode(), sink.getNode()) select src.getNode(), src, sink, - "The hash is calculated on the process name $@, may be related to a backdoor. Please review the code for possible malicious intent.", - sink.getNode(), "here" + "The hash is calculated on $@, may be related to a backdoor. Please review the code for possible malicious intent.", + sink.getNode(), "this process name" diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected index dc224c9586e..a76e9660cec 100644 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected @@ -1,7 +1,7 @@ -| delegation-test.cs:101:63:101:186 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:54:34:54:50 | LifetimeValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.LifetimeValidator | delegation-test.cs:101:63:101:186 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:102:63:102:178 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:102:63:102:178 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:115:63:115:190 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:115:63:115:190 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:116:63:116:180 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:116:63:116:180 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:117:63:117:217 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:117:63:117:217 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:118:63:118:248 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:118:63:118:248 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:119:63:119:177 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:119:63:119:177 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:101:63:101:186 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:54:34:54:50 | LifetimeValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.LifetimeValidator | +| delegation-test.cs:102:63:102:178 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | +| delegation-test.cs:115:63:115:190 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | +| delegation-test.cs:116:63:116:180 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | +| delegation-test.cs:117:63:117:217 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | +| delegation-test.cs:118:63:118:248 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | +| delegation-test.cs:119:63:119:177 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | From 66c97055029b86e2ad8d1a7bc69f559e3bf27bb8 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 7 Oct 2022 11:19:46 +0200 Subject: [PATCH 52/82] fix some more style-guide violations in the alert-messages --- .../LocalVariableHidesGlobalVariable.ql | 2 +- cpp/ql/src/Likely Bugs/ShortLoopVarName.ql | 4 +- .../CWE/CWE-190/ArithmeticUncontrolled.ql | 2 +- .../LocalVariableHidesGlobalVariable.expected | 2 +- .../LocalVariableHidesGlobalVariable.expected | 10 ++-- .../ShortLoopVarName.expected | 8 +-- .../SAMATE/ArithmeticUncontrolled.expected | 48 ++++++++-------- .../ArithmeticUncontrolled.expected | 56 +++++++++---------- 8 files changed, 66 insertions(+), 66 deletions(-) diff --git a/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql b/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql index 53c96c4beb7..ef9135f1c0a 100644 --- a/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql +++ b/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql @@ -35,4 +35,4 @@ from LocalVariableOrParameter lv, GlobalVariable gv where lv.getName() = gv.getName() and lv.getFile() = gv.getFile() -select lv, lv.type() + gv.getName() + " hides $@ with the same name.", gv, "a global variable" +select lv, lv.type() + gv.getName() + " hides a $@ with the same name.", gv, "global variable" diff --git a/cpp/ql/src/Likely Bugs/ShortLoopVarName.ql b/cpp/ql/src/Likely Bugs/ShortLoopVarName.ql index 87dee3c8e30..298e4c1051a 100644 --- a/cpp/ql/src/Likely Bugs/ShortLoopVarName.ql +++ b/cpp/ql/src/Likely Bugs/ShortLoopVarName.ql @@ -48,5 +48,5 @@ where not coordinatePair(iterationVar, innerVar) select iterationVar, "Iteration variable " + iterationVar.getName() + - " for $@ should have a descriptive name, since there is $@.", outer, "this loop", inner, - "a nested loop" + " for $@ should have a descriptive name, since there is a $@.", outer, "this loop", inner, + "nested loop" diff --git a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql index 76ee3b60e13..964b2ff33d8 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql @@ -135,5 +135,5 @@ where sink.getNode().asExpr() = va and missingGuard(va, effect) select sink.getNode(), source, sink, - "Arithmetic expression depends on an $@, potentially causing an " + effect + ".", + "This arithmetic expression depends on an $@, potentially causing an " + effect + ".", getExpr(source.getNode()), "uncontrolled value" diff --git a/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.expected b/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.expected index 4aaecc3b3bd..531452ba1b4 100644 --- a/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.expected +++ b/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.expected @@ -1 +1 @@ -| UnintendedDeclaration.cpp:65:14:65:20 | definition of myMutex | Local variable myMutex hides $@ with the same name. | UnintendedDeclaration.cpp:40:7:40:13 | myMutex | a global variable | +| UnintendedDeclaration.cpp:65:14:65:20 | definition of myMutex | Local variable myMutex hides a $@ with the same name. | UnintendedDeclaration.cpp:40:7:40:13 | myMutex | global variable | diff --git a/cpp/ql/test/query-tests/Best Practices/Hiding/LocalVariableHidesGlobalVariable/LocalVariableHidesGlobalVariable.expected b/cpp/ql/test/query-tests/Best Practices/Hiding/LocalVariableHidesGlobalVariable/LocalVariableHidesGlobalVariable.expected index 1ad05dacf8b..d79adba14e4 100644 --- a/cpp/ql/test/query-tests/Best Practices/Hiding/LocalVariableHidesGlobalVariable/LocalVariableHidesGlobalVariable.expected +++ b/cpp/ql/test/query-tests/Best Practices/Hiding/LocalVariableHidesGlobalVariable/LocalVariableHidesGlobalVariable.expected @@ -1,5 +1,5 @@ -| Hiding.c:22:25:22:26 | definition of gi | Local variable gi hides $@ with the same name. | Hiding.c:2:5:2:6 | gi | a global variable | -| Hiding.c:23:25:23:26 | definition of gj | Local variable gj hides $@ with the same name. | Hiding.c:3:12:3:13 | gj | a global variable | -| Hiding.c:24:25:24:26 | definition of gk | Local variable gk hides $@ with the same name. | Hiding.c:4:12:4:13 | gk | a global variable | -| Hiding.c:37:20:37:21 | definition of g3 | Parameter g3 hides $@ with the same name. | Hiding.c:33:13:33:14 | g3 | a global variable | -| Hiding.c:40:20:40:21 | definition of g5 | Parameter g5 hides $@ with the same name. | Hiding.c:33:21:33:22 | g5 | a global variable | +| Hiding.c:22:25:22:26 | definition of gi | Local variable gi hides a $@ with the same name. | Hiding.c:2:5:2:6 | gi | global variable | +| Hiding.c:23:25:23:26 | definition of gj | Local variable gj hides a $@ with the same name. | Hiding.c:3:12:3:13 | gj | global variable | +| Hiding.c:24:25:24:26 | definition of gk | Local variable gk hides a $@ with the same name. | Hiding.c:4:12:4:13 | gk | global variable | +| Hiding.c:37:20:37:21 | definition of g3 | Parameter g3 hides a $@ with the same name. | Hiding.c:33:13:33:14 | g3 | global variable | +| Hiding.c:40:20:40:21 | definition of g5 | Parameter g5 hides a $@ with the same name. | Hiding.c:33:21:33:22 | g5 | global variable | diff --git a/cpp/ql/test/query-tests/Likely Bugs/ShortLoopVarName/ShortLoopVarName.expected b/cpp/ql/test/query-tests/Likely Bugs/ShortLoopVarName/ShortLoopVarName.expected index 16c5690bf75..22b1f8f4456 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/ShortLoopVarName/ShortLoopVarName.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/ShortLoopVarName/ShortLoopVarName.expected @@ -1,4 +1,4 @@ -| ShortLoopVarName.cpp:6:6:6:6 | i | Iteration variable i for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:12:2:18:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:14:3:17:3 | for(...;...;...) ... | a nested loop | -| ShortLoopVarName.cpp:30:13:30:13 | a | Iteration variable a for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:30:2:38:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:34:3:37:3 | for(...;...;...) ... | a nested loop | -| ShortLoopVarName.cpp:73:11:73:11 | y | Iteration variable y for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:73:2:80:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:75:3:79:3 | for(...;...;...) ... | a nested loop | -| ShortLoopVarName.cpp:96:12:96:12 | i | Iteration variable i for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:96:3:102:3 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:98:4:101:4 | for(...;...;...) ... | a nested loop | +| ShortLoopVarName.cpp:6:6:6:6 | i | Iteration variable i for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:12:2:18:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:14:3:17:3 | for(...;...;...) ... | nested loop | +| ShortLoopVarName.cpp:30:13:30:13 | a | Iteration variable a for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:30:2:38:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:34:3:37:3 | for(...;...;...) ... | nested loop | +| ShortLoopVarName.cpp:73:11:73:11 | y | Iteration variable y for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:73:2:80:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:75:3:79:3 | for(...;...;...) ... | nested loop | +| ShortLoopVarName.cpp:96:12:96:12 | i | Iteration variable i for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:96:3:102:3 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:98:4:101:4 | for(...;...;...) ... | nested loop | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.expected index b672d501c5e..3834d769463 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.expected @@ -52,27 +52,27 @@ nodes | examples.cpp:38:9:38:12 | data | semmle.label | data | subpaths #select -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected index efec436a131..011f8f73819 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected @@ -92,31 +92,31 @@ nodes | test.cpp:219:8:219:8 | x | semmle.label | x | subpaths #select -| test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | uncontrolled value | -| test.c:35:5:35:5 | r | test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:34:13:34:18 | call to rand | uncontrolled value | -| test.c:45:5:45:5 | r | test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:44:13:44:16 | call to rand | uncontrolled value | -| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value | -| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value | -| test.c:83:9:83:9 | r | test.c:81:14:81:17 | call to rand | test.c:83:9:83:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:14:81:17 | call to rand | uncontrolled value | -| test.c:83:9:83:9 | r | test.c:81:23:81:26 | call to rand | test.c:83:9:83:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:23:81:26 | call to rand | uncontrolled value | -| test.c:127:9:127:9 | r | test.c:125:13:125:16 | call to rand | test.c:127:9:127:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:125:13:125:16 | call to rand | uncontrolled value | -| test.c:133:5:133:5 | r | test.c:131:13:131:16 | call to rand | test.c:133:5:133:5 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:131:13:131:16 | call to rand | uncontrolled value | -| test.c:139:10:139:10 | r | test.c:137:13:137:16 | call to rand | test.c:139:10:139:10 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:137:13:137:16 | call to rand | uncontrolled value | -| test.c:157:9:157:9 | r | test.c:155:22:155:25 | call to rand | test.c:157:9:157:9 | r | Arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value | -| test.c:157:9:157:9 | r | test.c:155:22:155:27 | (unsigned int)... | test.c:157:9:157:9 | r | Arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value | -| test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | uncontrolled value | -| test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | uncontrolled value | -| test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | uncontrolled value | -| test.cpp:90:10:90:10 | x | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:86:10:86:13 | call to rand | uncontrolled value | -| test.cpp:102:10:102:10 | x | test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:98:10:98:13 | call to rand | uncontrolled value | -| test.cpp:146:9:146:9 | y | test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:137:10:137:13 | call to rand | uncontrolled value | -| test.cpp:154:10:154:10 | b | test.cpp:151:10:151:13 | call to rand | test.cpp:154:10:154:10 | b | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:151:10:151:13 | call to rand | uncontrolled value | -| test.cpp:171:11:171:16 | (int)... | test.cpp:169:11:169:14 | call to rand | test.cpp:171:11:171:16 | (int)... | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value | -| test.cpp:171:16:171:16 | y | test.cpp:169:11:169:14 | call to rand | test.cpp:171:16:171:16 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value | -| test.cpp:196:7:196:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:196:7:196:7 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | -| test.cpp:198:7:198:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:198:7:198:7 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | -| test.cpp:199:7:199:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:199:7:199:7 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | -| test.cpp:204:7:204:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:204:7:204:7 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | -| test.cpp:205:7:205:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:205:7:205:7 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | -| test.cpp:208:7:208:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:208:7:208:7 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | -| test.cpp:219:8:219:8 | x | test.cpp:215:11:215:14 | call to rand | test.cpp:219:8:219:8 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:215:11:215:14 | call to rand | uncontrolled value | +| test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | uncontrolled value | +| test.c:35:5:35:5 | r | test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:34:13:34:18 | call to rand | uncontrolled value | +| test.c:45:5:45:5 | r | test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:44:13:44:16 | call to rand | uncontrolled value | +| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value | +| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value | +| test.c:83:9:83:9 | r | test.c:81:14:81:17 | call to rand | test.c:83:9:83:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:14:81:17 | call to rand | uncontrolled value | +| test.c:83:9:83:9 | r | test.c:81:23:81:26 | call to rand | test.c:83:9:83:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:23:81:26 | call to rand | uncontrolled value | +| test.c:127:9:127:9 | r | test.c:125:13:125:16 | call to rand | test.c:127:9:127:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:125:13:125:16 | call to rand | uncontrolled value | +| test.c:133:5:133:5 | r | test.c:131:13:131:16 | call to rand | test.c:133:5:133:5 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:131:13:131:16 | call to rand | uncontrolled value | +| test.c:139:10:139:10 | r | test.c:137:13:137:16 | call to rand | test.c:139:10:139:10 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:137:13:137:16 | call to rand | uncontrolled value | +| test.c:157:9:157:9 | r | test.c:155:22:155:25 | call to rand | test.c:157:9:157:9 | r | This arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value | +| test.c:157:9:157:9 | r | test.c:155:22:155:27 | (unsigned int)... | test.c:157:9:157:9 | r | This arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value | +| test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | uncontrolled value | +| test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | uncontrolled value | +| test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | uncontrolled value | +| test.cpp:90:10:90:10 | x | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:86:10:86:13 | call to rand | uncontrolled value | +| test.cpp:102:10:102:10 | x | test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:98:10:98:13 | call to rand | uncontrolled value | +| test.cpp:146:9:146:9 | y | test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:137:10:137:13 | call to rand | uncontrolled value | +| test.cpp:154:10:154:10 | b | test.cpp:151:10:151:13 | call to rand | test.cpp:154:10:154:10 | b | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:151:10:151:13 | call to rand | uncontrolled value | +| test.cpp:171:11:171:16 | (int)... | test.cpp:169:11:169:14 | call to rand | test.cpp:171:11:171:16 | (int)... | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value | +| test.cpp:171:16:171:16 | y | test.cpp:169:11:169:14 | call to rand | test.cpp:171:16:171:16 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value | +| test.cpp:196:7:196:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:196:7:196:7 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | +| test.cpp:198:7:198:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:198:7:198:7 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | +| test.cpp:199:7:199:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:199:7:199:7 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | +| test.cpp:204:7:204:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:204:7:204:7 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | +| test.cpp:205:7:205:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:205:7:205:7 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | +| test.cpp:208:7:208:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:208:7:208:7 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | +| test.cpp:219:8:219:8 | x | test.cpp:215:11:215:14 | call to rand | test.cpp:219:8:219:8 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:215:11:215:14 | call to rand | uncontrolled value | From d5c45056bd945835a10328d19aeb2785cc7ea3b0 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 7 Oct 2022 11:21:01 +0200 Subject: [PATCH 53/82] fix some more style-guide violations in the alert-messages --- .../InsecureRandomnessCustomizations.qll | 4 +-- .../InconsistentCode/WrappedErrorAlwaysNil.ql | 2 +- .../CWE-020/SuspiciousCharacterInRegexp.ql | 2 +- go/ql/src/Security/CWE-117/LogInjection.ql | 2 +- .../Security/CWE-338/InsecureRandomness.ql | 6 ++-- .../src/experimental/CWE-369/DivideByZero.ql | 3 +- .../CWE-400/DatabaseCallInLoop.ql | 2 +- go/ql/src/experimental/CWE-918/SSRF.ql | 2 +- .../IntegerOverflow/IntegerOverflow.ql | 2 +- .../CWE-369/DivideByZero.expected | 12 +++---- .../CWE-400/DatabaseCallInLoop.expected | 6 ++-- go/ql/test/experimental/CWE-918/SSRF.expected | 34 +++++++++---------- .../WrappedErrorAlwaysNil.expected | 8 ++--- .../SuspiciousCharacterInRegexp.expected | 22 ++++++------ .../InsecureRandomness.expected | 10 +++--- 15 files changed, 58 insertions(+), 59 deletions(-) diff --git a/go/ql/lib/semmle/go/security/InsecureRandomnessCustomizations.qll b/go/ql/lib/semmle/go/security/InsecureRandomnessCustomizations.qll index 2cbb350461b..3bc6b5f5eec 100644 --- a/go/ql/lib/semmle/go/security/InsecureRandomnessCustomizations.qll +++ b/go/ql/lib/semmle/go/security/InsecureRandomnessCustomizations.qll @@ -64,7 +64,7 @@ module InsecureRandomness { ) } - override string getKind() { result = "this cryptographic algorithm" } + override string getKind() { result = "This cryptographic algorithm" } } /** @@ -75,7 +75,7 @@ module InsecureRandomness { this.getRoot().(FuncDef).getName().regexpMatch("(?i).*(gen(erate)?|salt|make|mk)Password.*") } - override string getKind() { result = "a password-related function" } + override string getKind() { result = "A password-related function" } } /** Gets a package that implements hash algorithms. */ diff --git a/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql b/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql index c846ef16303..93889b0a23e 100644 --- a/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql +++ b/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql @@ -61,4 +61,4 @@ where // } n = DataFlow::BarrierGuard::getABarrierNode() ) -select n, "The first argument to 'errors.Wrap' is always nil" +select n, "The first argument to 'errors.Wrap' is always nil." diff --git a/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql b/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql index 71ae1ac183a..5c1b4528302 100644 --- a/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql +++ b/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql @@ -48,5 +48,5 @@ class Config extends DataFlow::Configuration { from Config c, DataFlow::PathNode source, DataFlow::PathNode sink, string report where c.hasFlowPath(source, sink) and c.isSource(source.getNode(), report) -select source, source, sink, "$@ that is $@ contains " + report, source, "A string literal", sink, +select source, source, sink, "This string literal that is $@ contains " + report, sink, "used as a regular expression" diff --git a/go/ql/src/Security/CWE-117/LogInjection.ql b/go/ql/src/Security/CWE-117/LogInjection.ql index 070788af884..dbf0c767bb3 100644 --- a/go/ql/src/Security/CWE-117/LogInjection.ql +++ b/go/ql/src/Security/CWE-117/LogInjection.ql @@ -17,5 +17,5 @@ import DataFlow::PathGraph from LogInjection::Configuration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "Log entry depends on a $@.", source.getNode(), +select sink.getNode(), source, sink, "This log entry depends on a $@.", source.getNode(), "user-provided value" diff --git a/go/ql/src/Security/CWE-338/InsecureRandomness.ql b/go/ql/src/Security/CWE-338/InsecureRandomness.ql index 37ec1c21655..e87bbbae37b 100644 --- a/go/ql/src/Security/CWE-338/InsecureRandomness.ql +++ b/go/ql/src/Security/CWE-338/InsecureRandomness.ql @@ -19,7 +19,7 @@ where cfg.hasFlowPath(source, sink) and cfg.isSink(sink.getNode(), kind) and ( - kind != "a password-related function" + kind != "A password-related function" or sink = min(DataFlow::PathNode sink2, int line | @@ -31,5 +31,5 @@ where ) ) select sink.getNode(), source, sink, - "$@ generated with a cryptographically weak RNG is used in $@.", source.getNode(), - "A random number", sink.getNode(), kind + kind + " depends on a $@ generated with a cryptographically weak RNG.", source.getNode(), + "random number" diff --git a/go/ql/src/experimental/CWE-369/DivideByZero.ql b/go/ql/src/experimental/CWE-369/DivideByZero.ql index 8aa12f7f66e..b2e61bef37d 100644 --- a/go/ql/src/experimental/CWE-369/DivideByZero.ql +++ b/go/ql/src/experimental/CWE-369/DivideByZero.ql @@ -54,5 +54,4 @@ class DivideByZeroCheckConfig extends TaintTracking::Configuration { from DataFlow::PathNode source, DataFlow::PathNode sink, DivideByZeroCheckConfig cfg where cfg.hasFlowPath(source, sink) -select sink, source, sink, "Variable $@ might be zero leading to a division-by-zero panic.", sink, - sink.getNode().toString() +select sink, source, sink, "This variable might be zero leading to a division-by-zero panic." diff --git a/go/ql/src/experimental/CWE-400/DatabaseCallInLoop.ql b/go/ql/src/experimental/CWE-400/DatabaseCallInLoop.ql index 253d598835d..66fb90664ea 100644 --- a/go/ql/src/experimental/CWE-400/DatabaseCallInLoop.ql +++ b/go/ql/src/experimental/CWE-400/DatabaseCallInLoop.ql @@ -66,4 +66,4 @@ query predicate edges(CallGraphNode pred, CallGraphNode succ) { from LoopStmt loop, DatabaseAccess dbAccess where edges*(loop, dbAccess.asExpr()) -select dbAccess, loop, dbAccess, "$@ is called in $@", dbAccess, dbAccess.toString(), loop, "a loop" +select dbAccess, loop, dbAccess, "This calls " + dbAccess.toString() + " in a $@.", loop, "loop" diff --git a/go/ql/src/experimental/CWE-918/SSRF.ql b/go/ql/src/experimental/CWE-918/SSRF.ql index 41c41bb18de..4c14969c35f 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.ql +++ b/go/ql/src/experimental/CWE-918/SSRF.ql @@ -19,4 +19,4 @@ from where cfg.hasFlowPath(source, sink) and request = sink.getNode().(ServerSideRequestForgery::Sink).getARequest() -select request, source, sink, "The URL of this request depends on a user-provided value" +select request, source, sink, "The URL of this request depends on a user-provided value." diff --git a/go/ql/src/experimental/IntegerOverflow/IntegerOverflow.ql b/go/ql/src/experimental/IntegerOverflow/IntegerOverflow.ql index 3a3c6b1d745..ca17228816c 100644 --- a/go/ql/src/experimental/IntegerOverflow/IntegerOverflow.ql +++ b/go/ql/src/experimental/IntegerOverflow/IntegerOverflow.ql @@ -11,4 +11,4 @@ import RangeAnalysis from Expr expr where exprMayOverflow(expr) or exprMayUnderflow(expr) -select expr, "this expression may cause an integer overflow" +select expr, "This expression may cause an integer overflow." diff --git a/go/ql/test/experimental/CWE-369/DivideByZero.expected b/go/ql/test/experimental/CWE-369/DivideByZero.expected index 35a3e399cb7..e80e3295c22 100644 --- a/go/ql/test/experimental/CWE-369/DivideByZero.expected +++ b/go/ql/test/experimental/CWE-369/DivideByZero.expected @@ -24,9 +24,9 @@ nodes | DivideByZero.go:57:17:57:21 | value | semmle.label | value | subpaths #select -| DivideByZero.go:12:16:12:20 | value | DivideByZero.go:10:12:10:16 | selection of URL : pointer type | DivideByZero.go:12:16:12:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:12:16:12:20 | value | value | -| DivideByZero.go:19:16:19:20 | value | DivideByZero.go:17:12:17:16 | selection of URL : pointer type | DivideByZero.go:19:16:19:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:19:16:19:20 | value | value | -| DivideByZero.go:26:16:26:20 | value | DivideByZero.go:24:12:24:16 | selection of URL : pointer type | DivideByZero.go:26:16:26:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:26:16:26:20 | value | value | -| DivideByZero.go:33:16:33:20 | value | DivideByZero.go:31:12:31:16 | selection of URL : pointer type | DivideByZero.go:33:16:33:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:33:16:33:20 | value | value | -| DivideByZero.go:40:16:40:20 | value | DivideByZero.go:38:12:38:16 | selection of URL : pointer type | DivideByZero.go:40:16:40:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:40:16:40:20 | value | value | -| DivideByZero.go:57:17:57:21 | value | DivideByZero.go:54:12:54:16 | selection of URL : pointer type | DivideByZero.go:57:17:57:21 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:57:17:57:21 | value | value | +| DivideByZero.go:12:16:12:20 | value | DivideByZero.go:10:12:10:16 | selection of URL : pointer type | DivideByZero.go:12:16:12:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:19:16:19:20 | value | DivideByZero.go:17:12:17:16 | selection of URL : pointer type | DivideByZero.go:19:16:19:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:26:16:26:20 | value | DivideByZero.go:24:12:24:16 | selection of URL : pointer type | DivideByZero.go:26:16:26:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:33:16:33:20 | value | DivideByZero.go:31:12:31:16 | selection of URL : pointer type | DivideByZero.go:33:16:33:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:40:16:40:20 | value | DivideByZero.go:38:12:38:16 | selection of URL : pointer type | DivideByZero.go:40:16:40:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:57:17:57:21 | value | DivideByZero.go:54:12:54:16 | selection of URL : pointer type | DivideByZero.go:57:17:57:21 | value | This variable might be zero leading to a division-by-zero panic. | diff --git a/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected b/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected index bb197203f22..074dfaa134f 100644 --- a/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected +++ b/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected @@ -8,6 +8,6 @@ edges | test.go:24:2:26:2 | for statement | test.go:25:3:25:17 | call to runRunQuery | | test.go:25:3:25:17 | call to runRunQuery | test.go:14:1:16:1 | function declaration | #select -| DatabaseCallInLoop.go:9:3:9:41 | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First | $@ is called in $@ | DatabaseCallInLoop.go:9:3:9:41 | call to First | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | a loop | -| test.go:11:2:11:13 | call to Take | test.go:20:2:22:2 | for statement | test.go:11:2:11:13 | call to Take | $@ is called in $@ | test.go:11:2:11:13 | call to Take | call to Take | test.go:20:2:22:2 | for statement | a loop | -| test.go:11:2:11:13 | call to Take | test.go:24:2:26:2 | for statement | test.go:11:2:11:13 | call to Take | $@ is called in $@ | test.go:11:2:11:13 | call to Take | call to Take | test.go:24:2:26:2 | for statement | a loop | +| DatabaseCallInLoop.go:9:3:9:41 | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First | This calls call to First in a $@. | DatabaseCallInLoop.go:7:2:11:2 | range statement | loop | +| test.go:11:2:11:13 | call to Take | test.go:20:2:22:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:20:2:22:2 | for statement | loop | +| test.go:11:2:11:13 | call to Take | test.go:24:2:26:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:24:2:26:2 | for statement | loop | diff --git a/go/ql/test/experimental/CWE-918/SSRF.expected b/go/ql/test/experimental/CWE-918/SSRF.expected index a0b9993a4ca..5fdd1775d3d 100644 --- a/go/ql/test/experimental/CWE-918/SSRF.expected +++ b/go/ql/test/experimental/CWE-918/SSRF.expected @@ -55,20 +55,20 @@ nodes | new-tests.go:96:11:96:46 | ...+... | semmle.label | ...+... | subpaths #select -| builtin.go:22:12:22:63 | call to Get | builtin.go:19:12:19:34 | call to FormValue : string | builtin.go:22:21:22:62 | ...+... | The URL of this request depends on a user-provided value | -| builtin.go:88:12:88:53 | call to Dial | builtin.go:83:21:83:31 | call to Referer : string | builtin.go:88:27:88:40 | untrustedInput | The URL of this request depends on a user-provided value | -| builtin.go:102:13:102:40 | call to DialConfig | builtin.go:97:21:97:31 | call to Referer : string | builtin.go:101:36:101:49 | untrustedInput | The URL of this request depends on a user-provided value | -| builtin.go:114:3:114:39 | call to Dial | builtin.go:111:21:111:31 | call to Referer : string | builtin.go:114:15:114:28 | untrustedInput | The URL of this request depends on a user-provided value | -| builtin.go:132:3:132:62 | call to DialContext | builtin.go:129:21:129:31 | call to Referer : string | builtin.go:132:38:132:51 | untrustedInput | The URL of this request depends on a user-provided value | -| new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:47:2:47:47 | call to Get | new-tests.go:39:18:39:30 | call to Param : string | new-tests.go:47:11:47:46 | ...+... | The URL of this request depends on a user-provided value | -| new-tests.go:50:2:50:47 | call to Get | new-tests.go:49:18:49:30 | call to Query : string | new-tests.go:50:11:50:46 | ...+... | The URL of this request depends on a user-provided value | -| new-tests.go:68:2:68:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:68:11:68:57 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:69:2:69:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:69:11:69:57 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:74:3:74:59 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:74:12:74:58 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:79:2:79:47 | call to Get | new-tests.go:78:18:78:24 | selection of URL : pointer type | new-tests.go:79:11:79:46 | ...+... | The URL of this request depends on a user-provided value | -| new-tests.go:82:2:82:47 | call to Get | new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:82:11:82:46 | ...+... | The URL of this request depends on a user-provided value | -| new-tests.go:88:2:88:47 | call to Get | new-tests.go:86:10:86:20 | call to Vars : map type | new-tests.go:88:11:88:46 | ...+... | The URL of this request depends on a user-provided value | -| new-tests.go:96:2:96:47 | call to Get | new-tests.go:95:18:95:45 | call to URLParam : string | new-tests.go:96:11:96:46 | ...+... | The URL of this request depends on a user-provided value | +| builtin.go:22:12:22:63 | call to Get | builtin.go:19:12:19:34 | call to FormValue : string | builtin.go:22:21:22:62 | ...+... | The URL of this request depends on a user-provided value. | +| builtin.go:88:12:88:53 | call to Dial | builtin.go:83:21:83:31 | call to Referer : string | builtin.go:88:27:88:40 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:102:13:102:40 | call to DialConfig | builtin.go:97:21:97:31 | call to Referer : string | builtin.go:101:36:101:49 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:114:3:114:39 | call to Dial | builtin.go:111:21:111:31 | call to Referer : string | builtin.go:114:15:114:28 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:132:3:132:62 | call to DialContext | builtin.go:129:21:129:31 | call to Referer : string | builtin.go:132:38:132:51 | untrustedInput | The URL of this request depends on a user-provided value. | +| new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:47:2:47:47 | call to Get | new-tests.go:39:18:39:30 | call to Param : string | new-tests.go:47:11:47:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:50:2:50:47 | call to Get | new-tests.go:49:18:49:30 | call to Query : string | new-tests.go:50:11:50:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:68:2:68:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:68:11:68:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:69:2:69:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:69:11:69:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:74:3:74:59 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:74:12:74:58 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:79:2:79:47 | call to Get | new-tests.go:78:18:78:24 | selection of URL : pointer type | new-tests.go:79:11:79:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:82:2:82:47 | call to Get | new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:82:11:82:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:88:2:88:47 | call to Get | new-tests.go:86:10:86:20 | call to Vars : map type | new-tests.go:88:11:88:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:96:2:96:47 | call to Get | new-tests.go:95:18:95:45 | call to URLParam : string | new-tests.go:96:11:96:46 | ...+... | The URL of this request depends on a user-provided value. | diff --git a/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.expected b/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.expected index 4ac2411d7ca..43853d29664 100644 --- a/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.expected +++ b/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.expected @@ -1,4 +1,4 @@ -| WrappedErrorAlwaysNil.go:31:22:31:24 | err | The first argument to 'errors.Wrap' is always nil | -| WrappedErrorAlwaysNil.go:41:14:41:16 | nil | The first argument to 'errors.Wrap' is always nil | -| WrappedErrorAlwaysNil.go:45:14:45:16 | err | The first argument to 'errors.Wrap' is always nil | -| WrappedErrorAlwaysNil.go:49:14:49:21 | localErr | The first argument to 'errors.Wrap' is always nil | +| WrappedErrorAlwaysNil.go:31:22:31:24 | err | The first argument to 'errors.Wrap' is always nil. | +| WrappedErrorAlwaysNil.go:41:14:41:16 | nil | The first argument to 'errors.Wrap' is always nil. | +| WrappedErrorAlwaysNil.go:45:14:45:16 | err | The first argument to 'errors.Wrap' is always nil. | +| WrappedErrorAlwaysNil.go:49:14:49:21 | localErr | The first argument to 'errors.Wrap' is always nil. | diff --git a/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.expected b/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.expected index 130894d0639..cea5780a6c5 100644 --- a/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.expected +++ b/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.expected @@ -13,14 +13,14 @@ nodes | test.go:23:21:23:36 | "hello\\\\\\bworld" | semmle.label | "hello\\\\\\bworld" | subpaths #select -| SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | $@ that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | A string literal | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | used as a regular expression | -| test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:7:21:7:24 | "\\a" | A string literal | test.go:7:21:7:24 | "\\a" | used as a regular expression | -| test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:9:21:9:26 | "\\\\\\a" | A string literal | test.go:9:21:9:26 | "\\\\\\a" | used as a regular expression | -| test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:10:21:10:27 | "x\\\\\\a" | A string literal | test.go:10:21:10:27 | "x\\\\\\a" | used as a regular expression | -| test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:12:21:12:28 | "\\\\\\\\\\a" | A string literal | test.go:12:21:12:28 | "\\\\\\\\\\a" | used as a regular expression | -| test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | A string literal | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | used as a regular expression | -| test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | A string literal | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | used as a regular expression | -| test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:20:21:20:34 | "hello\\aworld" | A string literal | test.go:20:21:20:34 | "hello\\aworld" | used as a regular expression | -| test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:21:21:21:36 | "hello\\\\\\aworld" | A string literal | test.go:21:21:21:36 | "hello\\\\\\aworld" | used as a regular expression | -| test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | $@ that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:22:21:22:34 | "hello\\bworld" | A string literal | test.go:22:21:22:34 | "hello\\bworld" | used as a regular expression | -| test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | $@ that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:23:21:23:36 | "hello\\\\\\bworld" | A string literal | test.go:23:21:23:36 | "hello\\\\\\bworld" | used as a regular expression | +| SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | This string literal that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | used as a regular expression | +| test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:7:21:7:24 | "\\a" | used as a regular expression | +| test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:9:21:9:26 | "\\\\\\a" | used as a regular expression | +| test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:10:21:10:27 | "x\\\\\\a" | used as a regular expression | +| test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:12:21:12:28 | "\\\\\\\\\\a" | used as a regular expression | +| test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | used as a regular expression | +| test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | used as a regular expression | +| test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:20:21:20:34 | "hello\\aworld" | used as a regular expression | +| test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:21:21:21:36 | "hello\\\\\\aworld" | used as a regular expression | +| test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | This string literal that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:22:21:22:34 | "hello\\bworld" | used as a regular expression | +| test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | This string literal that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:23:21:23:36 | "hello\\\\\\bworld" | used as a regular expression | diff --git a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected index be68561ca27..2ba310c6ee1 100644 --- a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected +++ b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected @@ -20,8 +20,8 @@ nodes | sample.go:47:17:47:39 | call to Intn | semmle.label | call to Intn | subpaths #select -| InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | $@ generated with a cryptographically weak RNG is used in $@. | InsecureRandomness.go:12:18:12:40 | call to Intn | A random number | InsecureRandomness.go:12:18:12:40 | call to Intn | a password-related function | -| sample.go:26:25:26:30 | call to Guid | sample.go:15:49:15:61 | call to Uint32 : uint32 | sample.go:26:25:26:30 | call to Guid | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:15:49:15:61 | call to Uint32 | A random number | sample.go:26:25:26:30 | call to Guid | this cryptographic algorithm | -| sample.go:37:25:37:29 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:25:37:29 | nonce | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:34:12:34:40 | call to New | A random number | sample.go:37:25:37:29 | nonce | this cryptographic algorithm | -| sample.go:37:32:37:36 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:32:37:36 | nonce | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:34:12:34:40 | call to New | A random number | sample.go:37:32:37:36 | nonce | this cryptographic algorithm | -| sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:43:17:43:39 | call to Intn | A random number | sample.go:43:17:43:39 | call to Intn | a password-related function | +| InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | A password-related function depends on a $@ generated with a cryptographically weak RNG. | InsecureRandomness.go:12:18:12:40 | call to Intn | random number | +| sample.go:26:25:26:30 | call to Guid | sample.go:15:49:15:61 | call to Uint32 : uint32 | sample.go:26:25:26:30 | call to Guid | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:15:49:15:61 | call to Uint32 | random number | +| sample.go:37:25:37:29 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:25:37:29 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number | +| sample.go:37:32:37:36 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:32:37:36 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number | +| sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | A password-related function depends on a $@ generated with a cryptographically weak RNG. | sample.go:43:17:43:39 | call to Intn | random number | From 9f6240b38c56e7914119431de10905adb098db1e Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Fri, 7 Oct 2022 11:22:12 +0200 Subject: [PATCH 54/82] Kotlin: Add test for missing `override` modifier on SAM methods --- .../library-tests/exprs/funcExprs.expected | 169 +++++++++++++++++- .../kotlin/library-tests/exprs/funcExprs.ql | 7 +- 2 files changed, 174 insertions(+), 2 deletions(-) diff --git a/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected b/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected index 8b4da235ba0..997f0b05599 100644 --- a/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected +++ b/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected @@ -42,7 +42,7 @@ memberRefExprs | kFunctionInvoke.kt:8:44:8:47 | ...::... | kFunctionInvoke.kt:8:44:8:47 | invoke | invoke(java.lang.String) | kFunctionInvoke.kt:8:44:8:47 | new Function1(...) { ... } | | samConversion.kt:5:27:5:31 | ...::... | samConversion.kt:5:27:5:31 | invoke | invoke(int,int) | samConversion.kt:5:27:5:31 | new Function2(...) { ... } | | samConversion.kt:41:13:41:16 | ...::... | samConversion.kt:41:13:41:16 | invoke | invoke(java.lang.Object[]) | samConversion.kt:41:13:41:16 | new FunctionN(...) { ... } | -modifiers +lambda_modifiers | delegatedProperties.kt:6:32:9:9 | ...->... | delegatedProperties.kt:6:32:9:9 | invoke | override, public | | funcExprs.kt:22:26:22:33 | ...->... | funcExprs.kt:22:26:22:33 | invoke | override, public | | funcExprs.kt:23:26:23:33 | ...->... | funcExprs.kt:23:26:23:33 | invoke | override, public | @@ -74,6 +74,173 @@ modifiers | samConversion.kt:43:31:45:68 | ...->... | samConversion.kt:43:31:45:68 | invoke | public | | samConversion.kt:46:32:46:44 | ...->... | samConversion.kt:46:32:46:44 | invoke | override, public | | samConversion.kt:58:30:58:45 | ...->... | samConversion.kt:58:30:58:45 | invoke | override, public, suspend | +anon_class_member_modifiers +| delegatedProperties.kt:6:24:9:9 | new KProperty0(...) { ... } | delegatedProperties.kt:6:24:9:9 | get | override, public | +| delegatedProperties.kt:6:24:9:9 | new KProperty0(...) { ... } | delegatedProperties.kt:6:24:9:9 | invoke | override, public | +| delegatedProperties.kt:6:32:9:9 | new Function0(...) { ... } | delegatedProperties.kt:6:32:9:9 | invoke | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | get | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | get | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | invoke | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | invoke | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | set | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | set | override, public | +| delegatedProperties.kt:23:26:23:31 | new KProperty0(...) { ... } | delegatedProperties.kt:23:26:23:31 | get | override, public | +| delegatedProperties.kt:23:26:23:31 | new KProperty0(...) { ... } | delegatedProperties.kt:23:26:23:31 | invoke | override, public | +| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:26:13:26:28 | getCurValue | public | +| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:26:13:26:28 | setCurValue | public | +| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:27:22:27:88 | getValue | override, public | +| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:28:22:30:13 | setValue | override, public | +| delegatedProperties.kt:33:27:33:47 | new KProperty0(...) { ... } | delegatedProperties.kt:33:27:33:47 | get | override, public | +| delegatedProperties.kt:33:27:33:47 | new KProperty0(...) { ... } | delegatedProperties.kt:33:27:33:47 | invoke | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | get | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | get | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | invoke | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | invoke | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | set | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | set | override, public | +| delegatedProperties.kt:39:31:39:51 | new KProperty0(...) { ... } | delegatedProperties.kt:39:31:39:51 | get | override, public | +| delegatedProperties.kt:39:31:39:51 | new KProperty0(...) { ... } | delegatedProperties.kt:39:31:39:51 | get | override, public | +| delegatedProperties.kt:39:31:39:51 | new KProperty0(...) { ... } | delegatedProperties.kt:39:31:39:51 | invoke | override, public | +| delegatedProperties.kt:39:31:39:51 | new KProperty0(...) { ... } | delegatedProperties.kt:39:31:39:51 | invoke | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | get | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | get | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | invoke | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | invoke | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | set | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | set | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | get | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | get | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | invoke | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | invoke | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | set | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | set | override, public | +| delegatedProperties.kt:66:36:66:50 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:66:36:66:50 | get | override, public | +| delegatedProperties.kt:66:36:66:50 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:66:36:66:50 | invoke | override, public | +| delegatedProperties.kt:66:36:66:50 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:66:36:66:50 | set | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | get | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | get | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | invoke | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | invoke | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | set | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | set | override, public | +| delegatedProperties.kt:67:36:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:36:67:53 | get | override, public | +| delegatedProperties.kt:67:36:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:36:67:53 | invoke | override, public | +| delegatedProperties.kt:67:36:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:36:67:53 | set | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | get | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | get | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | invoke | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | invoke | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | set | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | set | override, public | +| delegatedProperties.kt:69:39:69:56 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:69:39:69:56 | get | override, public | +| delegatedProperties.kt:69:39:69:56 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:69:39:69:56 | invoke | override, public | +| delegatedProperties.kt:69:39:69:56 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:69:39:69:56 | set | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | get | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | get | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | invoke | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | invoke | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | set | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | set | override, public | +| delegatedProperties.kt:70:39:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:39:70:59 | get | override, public | +| delegatedProperties.kt:70:39:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:39:70:59 | invoke | override, public | +| delegatedProperties.kt:70:39:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:39:70:59 | set | override, public | +| delegatedProperties.kt:72:36:72:56 | new KProperty1(...) { ... } | delegatedProperties.kt:72:36:72:56 | get | override, public | +| delegatedProperties.kt:72:36:72:56 | new KProperty1(...) { ... } | delegatedProperties.kt:72:36:72:56 | invoke | override, public | +| delegatedProperties.kt:72:39:72:56 | new KProperty0(...) { ... } | delegatedProperties.kt:72:39:72:56 | get | override, public | +| delegatedProperties.kt:72:39:72:56 | new KProperty0(...) { ... } | delegatedProperties.kt:72:39:72:56 | invoke | override, public | +| delegatedProperties.kt:73:36:73:56 | new KProperty1(...) { ... } | delegatedProperties.kt:73:36:73:56 | get | override, public | +| delegatedProperties.kt:73:36:73:56 | new KProperty1(...) { ... } | delegatedProperties.kt:73:36:73:56 | invoke | override, public | +| delegatedProperties.kt:73:39:73:56 | new KProperty1(...) { ... } | delegatedProperties.kt:73:39:73:56 | get | override, public | +| delegatedProperties.kt:73:39:73:56 | new KProperty1(...) { ... } | delegatedProperties.kt:73:39:73:56 | invoke | override, public | +| delegatedProperties.kt:75:39:75:78 | new KProperty1(...) { ... } | delegatedProperties.kt:75:39:75:78 | get | override, public | +| delegatedProperties.kt:75:39:75:78 | new KProperty1(...) { ... } | delegatedProperties.kt:75:39:75:78 | invoke | override, public | +| delegatedProperties.kt:75:42:75:78 | new KProperty0(...) { ... } | delegatedProperties.kt:75:42:75:78 | get | override, public | +| delegatedProperties.kt:75:42:75:78 | new KProperty0(...) { ... } | delegatedProperties.kt:75:42:75:78 | invoke | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | get | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | get | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | invoke | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | invoke | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | set | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | set | override, public | +| delegatedProperties.kt:77:37:77:49 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:77:37:77:49 | get | override, public | +| delegatedProperties.kt:77:37:77:49 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:77:37:77:49 | invoke | override, public | +| delegatedProperties.kt:77:37:77:49 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:77:37:77:49 | set | override, public | +| delegatedProperties.kt:79:18:79:38 | new KProperty1(...) { ... } | delegatedProperties.kt:79:18:79:38 | get | override, public | +| delegatedProperties.kt:79:18:79:38 | new KProperty1(...) { ... } | delegatedProperties.kt:79:18:79:38 | invoke | override, public | +| delegatedProperties.kt:79:21:79:38 | new KProperty0(...) { ... } | delegatedProperties.kt:79:21:79:38 | get | override, public | +| delegatedProperties.kt:79:21:79:38 | new KProperty0(...) { ... } | delegatedProperties.kt:79:21:79:38 | invoke | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | get | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | get | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | invoke | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | invoke | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | set | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | set | override, public | +| delegatedProperties.kt:82:40:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:40:82:54 | get | override, public | +| delegatedProperties.kt:82:40:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:40:82:54 | invoke | override, public | +| delegatedProperties.kt:82:40:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:40:82:54 | set | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | get | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | get | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | invoke | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | invoke | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | set | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | set | override, public | +| delegatedProperties.kt:87:34:87:46 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:87:34:87:46 | get | override, public | +| delegatedProperties.kt:87:34:87:46 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:87:34:87:46 | invoke | override, public | +| delegatedProperties.kt:87:34:87:46 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:87:34:87:46 | set | override, public | +| exprs.kt:189:16:191:9 | new Interface1(...) { ... } | exprs.kt:190:13:190:49 | getA3 | public | +| funcExprs.kt:22:26:22:33 | new Function0(...) { ... } | funcExprs.kt:22:26:22:33 | invoke | override, public | +| funcExprs.kt:23:26:23:33 | new Function0(...) { ... } | funcExprs.kt:23:26:23:33 | invoke | override, public | +| funcExprs.kt:24:26:24:33 | new Function0(...) { ... } | funcExprs.kt:24:26:24:33 | invoke | override, public | +| funcExprs.kt:25:29:25:38 | new Function1(...) { ... } | funcExprs.kt:25:29:25:38 | invoke | override, public | +| funcExprs.kt:26:29:26:34 | new Function1(...) { ... } | funcExprs.kt:26:29:26:34 | invoke | override, public | +| funcExprs.kt:27:29:27:42 | new Function1(...) { ... } | funcExprs.kt:27:29:27:42 | invoke | override, public | +| funcExprs.kt:29:29:29:37 | new Function1(...) { ... } | funcExprs.kt:29:29:29:37 | invoke | override, public | +| funcExprs.kt:30:28:30:50 | new Function2(...) { ... } | funcExprs.kt:30:28:30:50 | invoke | override, public | +| funcExprs.kt:31:28:31:40 | new Function2(...) { ... } | funcExprs.kt:31:28:31:40 | invoke | override, public | +| funcExprs.kt:32:28:32:44 | new Function2(...) { ... } | funcExprs.kt:32:28:32:44 | invoke | override, public | +| funcExprs.kt:33:28:33:51 | new Function1>(...) { ... } | funcExprs.kt:33:28:33:51 | invoke | override, public | +| funcExprs.kt:33:37:33:47 | new Function1(...) { ... } | funcExprs.kt:33:37:33:47 | invoke | override, public | +| funcExprs.kt:35:29:35:112 | new Function22(...) { ... } | funcExprs.kt:35:29:35:112 | invoke | override, public | +| funcExprs.kt:36:29:36:117 | new FunctionN(...) { ... } | funcExprs.kt:36:29:36:117 | invoke | override, public | +| funcExprs.kt:36:29:36:117 | new FunctionN(...) { ... } | funcExprs.kt:36:29:36:117 | invoke | public | +| funcExprs.kt:38:26:38:38 | new Function0(...) { ... } | funcExprs.kt:38:26:38:38 | invoke | override, public | +| funcExprs.kt:39:26:39:36 | new Function0(...) { ... } | funcExprs.kt:39:26:39:36 | invoke | override, public | +| funcExprs.kt:40:29:40:41 | new Function1(...) { ... } | funcExprs.kt:40:29:40:41 | invoke | override, public | +| funcExprs.kt:41:29:41:39 | new Function2(...) { ... } | funcExprs.kt:41:29:41:39 | invoke | override, public | +| funcExprs.kt:42:29:42:33 | new Function1(...) { ... } | funcExprs.kt:42:29:42:33 | invoke | override, public | +| funcExprs.kt:43:28:43:34 | new Function2(...) { ... } | funcExprs.kt:43:28:43:34 | invoke | override, public | +| funcExprs.kt:44:29:44:42 | new Function22(...) { ... } | funcExprs.kt:44:29:44:42 | invoke | override, public | +| funcExprs.kt:45:29:45:42 | new FunctionN(...) { ... } | funcExprs.kt:45:29:45:42 | invoke | override, public | +| funcExprs.kt:46:30:46:41 | new FunctionN(...) { ... } | funcExprs.kt:46:30:46:41 | invoke | override, public | +| funcExprs.kt:49:26:49:32 | new Function0(...) { ... } | funcExprs.kt:49:26:49:32 | invoke | override, public | +| funcExprs.kt:51:8:51:16 | new Function0(...) { ... } | funcExprs.kt:51:8:51:16 | invoke | override, public | +| funcExprs.kt:75:12:75:22 | new Function1>,String>(...) { ... } | funcExprs.kt:75:12:75:22 | invoke | override, public | +| funcExprs.kt:83:31:83:51 | new Function1(...) { ... } | funcExprs.kt:83:31:83:51 | invoke | override, public | +| funcExprs.kt:86:39:86:59 | new Function1(...) { ... } | funcExprs.kt:86:39:86:59 | invoke | override, public, suspend | +| funcExprs.kt:90:15:90:69 | new FunctionN(...) { ... } | funcExprs.kt:90:15:90:69 | invoke | override, public | +| funcExprs.kt:90:15:90:69 | new FunctionN(...) { ... } | funcExprs.kt:90:15:90:69 | invoke | public | +| funcExprs.kt:94:15:94:67 | new Function22(...) { ... } | funcExprs.kt:94:15:94:67 | invoke | override, public, suspend | +| kFunctionInvoke.kt:8:44:8:47 | new Function1(...) { ... } | kFunctionInvoke.kt:8:44:8:47 | invoke | override, public | +| samConversion.kt:2:18:2:45 | new IntPredicate(...) { ... } | samConversion.kt:2:18:2:45 | accept | public | +| samConversion.kt:2:31:2:45 | new Function1(...) { ... } | samConversion.kt:2:31:2:45 | invoke | override, public | +| samConversion.kt:4:14:4:42 | new InterfaceFn1(...) { ... } | samConversion.kt:4:14:4:42 | fn1 | public | +| samConversion.kt:4:27:4:42 | new Function2(...) { ... } | samConversion.kt:4:27:4:42 | invoke | override, public | +| samConversion.kt:5:14:5:32 | new InterfaceFn1(...) { ... } | samConversion.kt:5:14:5:32 | fn1 | public | +| samConversion.kt:5:27:5:31 | new Function2(...) { ... } | samConversion.kt:5:27:5:31 | invoke | override, public | +| samConversion.kt:7:13:7:46 | new InterfaceFnExt1(...) { ... } | samConversion.kt:7:13:7:46 | ext | public | +| samConversion.kt:7:29:7:46 | new Function2(...) { ... } | samConversion.kt:7:29:7:46 | invoke | override, public | +| samConversion.kt:9:13:13:6 | new IntPredicate(...) { ... } | samConversion.kt:9:13:13:6 | accept | public | +| samConversion.kt:9:33:11:5 | new Function1(...) { ... } | samConversion.kt:9:33:11:5 | invoke | override, public | +| samConversion.kt:11:12:13:5 | new Function1(...) { ... } | samConversion.kt:11:12:13:5 | invoke | override, public | +| samConversion.kt:41:13:41:16 | new FunctionN(...) { ... } | samConversion.kt:41:13:41:16 | invoke | override, public | +| samConversion.kt:42:13:42:32 | new BigArityPredicate(...) { ... } | samConversion.kt:42:13:42:32 | accept | public | +| samConversion.kt:43:13:45:68 | new BigArityPredicate(...) { ... } | samConversion.kt:43:13:45:68 | accept | public | +| samConversion.kt:43:31:45:68 | new FunctionN(...) { ... } | samConversion.kt:43:31:45:68 | invoke | override, public | +| samConversion.kt:43:31:45:68 | new FunctionN(...) { ... } | samConversion.kt:43:31:45:68 | invoke | public | +| samConversion.kt:46:13:46:44 | new SomePredicate(...) { ... } | samConversion.kt:46:13:46:44 | fn | public | +| samConversion.kt:46:32:46:44 | new Function1(...) { ... } | samConversion.kt:46:32:46:44 | invoke | override, public | +| samConversion.kt:58:14:58:45 | new InterfaceFn1Sus(...) { ... } | samConversion.kt:58:14:58:45 | fn1 | public, suspend | +| samConversion.kt:58:30:58:45 | new Function2(...) { ... } | samConversion.kt:58:30:58:45 | invoke | override, public, suspend | nonOverrideInvoke | funcExprs.kt:36:29:36:117 | ...->... | funcExprs.kt:36:29:36:117 | invoke | 23 | | funcExprs.kt:90:15:90:69 | ...->... | funcExprs.kt:90:15:90:69 | invoke | 23 | diff --git a/java/ql/test/kotlin/library-tests/exprs/funcExprs.ql b/java/ql/test/kotlin/library-tests/exprs/funcExprs.ql index fa2b5fda2a2..f6e233336f3 100644 --- a/java/ql/test/kotlin/library-tests/exprs/funcExprs.ql +++ b/java/ql/test/kotlin/library-tests/exprs/funcExprs.ql @@ -19,11 +19,16 @@ query predicate memberRefExprs(MemberRefExpr e, Method m, string signature, Anon e.getAnonymousClass() = an } -query predicate modifiers(LambdaExpr le, Method m, string modifiers) { +query predicate lambda_modifiers(LambdaExpr le, Method m, string modifiers) { le.getAnonymousClass().getAMethod() = m and modifiers = concat(string s | m.hasModifier(s) | s, ", ") } +query predicate anon_class_member_modifiers(AnonymousClass ac, Method m, string modifiers) { + ac.getAMethod() = m and + modifiers = concat(string s | m.hasModifier(s) | s, ", ") +} + query predicate nonOverrideInvoke(LambdaExpr le, Method m, int pCount) { le.getAnonymousClass().getAMethod() = m and not m.hasModifier("override") and From 26c4216fef92b3375e1a85a10aa4f31f0113bac7 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Fri, 7 Oct 2022 11:23:10 +0200 Subject: [PATCH 55/82] Kotlin: Extract `override` modifier on SAM methods --- .../src/main/kotlin/KotlinFileExtractor.kt | 3 ++- .../library-tests/exprs/funcExprs.expected | 18 +++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index b7aff59b599..a83dafa1df6 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -4731,7 +4731,7 @@ open class KotlinFileExtractor( class extends Object implements IntPredicate { Function1 ; public (Function1 ) { this. = ; } - public Boolean accept(Integer i) { return .invoke(i); } + public override Boolean accept(Integer i) { return .invoke(i); } } IntPredicate x = (IntPredicate)new (...); @@ -4811,6 +4811,7 @@ open class KotlinFileExtractor( // the real underlying R Function.apply(T t). forceExtractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, typeSub, classTypeArgs, overriddenAttributes = OverriddenFunctionAttributes(id = ids.function, sourceLoc = tw.getLocation(e))) + addModifiers(ids.function, "override") if (st.isSuspendFunctionOrKFunction()) { addModifiers(ids.function, "suspend") } diff --git a/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected b/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected index 997f0b05599..7e636762d16 100644 --- a/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected +++ b/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected @@ -221,25 +221,25 @@ anon_class_member_modifiers | funcExprs.kt:90:15:90:69 | new FunctionN(...) { ... } | funcExprs.kt:90:15:90:69 | invoke | public | | funcExprs.kt:94:15:94:67 | new Function22(...) { ... } | funcExprs.kt:94:15:94:67 | invoke | override, public, suspend | | kFunctionInvoke.kt:8:44:8:47 | new Function1(...) { ... } | kFunctionInvoke.kt:8:44:8:47 | invoke | override, public | -| samConversion.kt:2:18:2:45 | new IntPredicate(...) { ... } | samConversion.kt:2:18:2:45 | accept | public | +| samConversion.kt:2:18:2:45 | new IntPredicate(...) { ... } | samConversion.kt:2:18:2:45 | accept | override, public | | samConversion.kt:2:31:2:45 | new Function1(...) { ... } | samConversion.kt:2:31:2:45 | invoke | override, public | -| samConversion.kt:4:14:4:42 | new InterfaceFn1(...) { ... } | samConversion.kt:4:14:4:42 | fn1 | public | +| samConversion.kt:4:14:4:42 | new InterfaceFn1(...) { ... } | samConversion.kt:4:14:4:42 | fn1 | override, public | | samConversion.kt:4:27:4:42 | new Function2(...) { ... } | samConversion.kt:4:27:4:42 | invoke | override, public | -| samConversion.kt:5:14:5:32 | new InterfaceFn1(...) { ... } | samConversion.kt:5:14:5:32 | fn1 | public | +| samConversion.kt:5:14:5:32 | new InterfaceFn1(...) { ... } | samConversion.kt:5:14:5:32 | fn1 | override, public | | samConversion.kt:5:27:5:31 | new Function2(...) { ... } | samConversion.kt:5:27:5:31 | invoke | override, public | -| samConversion.kt:7:13:7:46 | new InterfaceFnExt1(...) { ... } | samConversion.kt:7:13:7:46 | ext | public | +| samConversion.kt:7:13:7:46 | new InterfaceFnExt1(...) { ... } | samConversion.kt:7:13:7:46 | ext | override, public | | samConversion.kt:7:29:7:46 | new Function2(...) { ... } | samConversion.kt:7:29:7:46 | invoke | override, public | -| samConversion.kt:9:13:13:6 | new IntPredicate(...) { ... } | samConversion.kt:9:13:13:6 | accept | public | +| samConversion.kt:9:13:13:6 | new IntPredicate(...) { ... } | samConversion.kt:9:13:13:6 | accept | override, public | | samConversion.kt:9:33:11:5 | new Function1(...) { ... } | samConversion.kt:9:33:11:5 | invoke | override, public | | samConversion.kt:11:12:13:5 | new Function1(...) { ... } | samConversion.kt:11:12:13:5 | invoke | override, public | | samConversion.kt:41:13:41:16 | new FunctionN(...) { ... } | samConversion.kt:41:13:41:16 | invoke | override, public | -| samConversion.kt:42:13:42:32 | new BigArityPredicate(...) { ... } | samConversion.kt:42:13:42:32 | accept | public | -| samConversion.kt:43:13:45:68 | new BigArityPredicate(...) { ... } | samConversion.kt:43:13:45:68 | accept | public | +| samConversion.kt:42:13:42:32 | new BigArityPredicate(...) { ... } | samConversion.kt:42:13:42:32 | accept | override, public | +| samConversion.kt:43:13:45:68 | new BigArityPredicate(...) { ... } | samConversion.kt:43:13:45:68 | accept | override, public | | samConversion.kt:43:31:45:68 | new FunctionN(...) { ... } | samConversion.kt:43:31:45:68 | invoke | override, public | | samConversion.kt:43:31:45:68 | new FunctionN(...) { ... } | samConversion.kt:43:31:45:68 | invoke | public | -| samConversion.kt:46:13:46:44 | new SomePredicate(...) { ... } | samConversion.kt:46:13:46:44 | fn | public | +| samConversion.kt:46:13:46:44 | new SomePredicate(...) { ... } | samConversion.kt:46:13:46:44 | fn | override, public | | samConversion.kt:46:32:46:44 | new Function1(...) { ... } | samConversion.kt:46:32:46:44 | invoke | override, public | -| samConversion.kt:58:14:58:45 | new InterfaceFn1Sus(...) { ... } | samConversion.kt:58:14:58:45 | fn1 | public, suspend | +| samConversion.kt:58:14:58:45 | new InterfaceFn1Sus(...) { ... } | samConversion.kt:58:14:58:45 | fn1 | override, public, suspend | | samConversion.kt:58:30:58:45 | new Function2(...) { ... } | samConversion.kt:58:30:58:45 | invoke | override, public, suspend | nonOverrideInvoke | funcExprs.kt:36:29:36:117 | ...->... | funcExprs.kt:36:29:36:117 | invoke | 23 | From bb6e5756898acca2b6fedcd7f5323a49d2d3fc4b Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 6 Oct 2022 15:59:33 +0100 Subject: [PATCH 56/82] Kotlin: allow building a single embeddable plugin version --- java/kotlin-extractor/build.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index a4da1a2ea23..d714c799eed 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -25,6 +25,8 @@ def parse_args(): dest='many', help='Build for a single version/kind') parser.add_argument('--single-version', help='Build for a specific version/kind') + parser.add_argument('--single-version-embeddable', action='store_true', + help='When building a single version, build an embeddable extractor (default is standalone)') return parser.parse_args() @@ -233,12 +235,13 @@ def compile_standalone(version): 'build_standalone_' + version, version) +compile_single_version = compile_embeddable if args.single_version_embeddable == True else compile_standalone if args.single_version: - compile_standalone(args.single_version) + compile_single_version(args.single_version) elif args.many: for version in kotlin_plugin_versions.many_versions: compile_standalone(version) compile_embeddable(version) else: - compile_standalone(kotlin_plugin_versions.get_single_version()) + compile_single_version(kotlin_plugin_versions.get_single_version()) From 5d9c68c962e586f7de0620df4d12379d4224a848 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 7 Oct 2022 13:21:24 +0200 Subject: [PATCH 57/82] remove the taint-steps meta query --- ruby/ql/src/queries/meta/TaintSteps.ql | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 ruby/ql/src/queries/meta/TaintSteps.ql diff --git a/ruby/ql/src/queries/meta/TaintSteps.ql b/ruby/ql/src/queries/meta/TaintSteps.ql deleted file mode 100644 index c86a6ba1d3a..00000000000 --- a/ruby/ql/src/queries/meta/TaintSteps.ql +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @name Taint steps - * @description All taint steps. - * @kind problem - * @problem.severity recommendation - * @id rb/meta/taint-steps - * @tags meta - * @precision very-low - */ - -import ruby -import internal.TaintMetrics -import codeql.ruby.dataflow.internal.TaintTrackingPublic - -predicate relevantStep(DataFlow::Node pred, DataFlow::Node succ) { localTaintStep(pred, succ) } - -from File file, int numSteps -where - numSteps = - strictcount(DataFlow::Node pred, DataFlow::Node succ | - relevantStep(pred, succ) and pred.getLocation().getFile() = file - ) -select file, "File has " + numSteps + " taint steps." From 2df1d63d1c9c0f3310d91ac54c453feaeed3eaa2 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 7 Oct 2022 12:23:08 +0100 Subject: [PATCH 58/82] Extract the corresponding classes of enum entries, where they exist. --- .../src/main/kotlin/KotlinFileExtractor.kt | 10 ++++-- .../library-tests/methods/clinit.expected | 1 + .../kotlin/library-tests/methods/enumClass.kt | 12 +++++++ .../library-tests/methods/exprs.expected | 31 +++++++++++++++++++ .../library-tests/methods/methods.expected | 9 ++++++ .../library-tests/methods/parameters.expected | 5 +++ 6 files changed, 65 insertions(+), 3 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index fc28db0a3b0..9ff04cf6ade 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -155,7 +155,7 @@ open class KotlinFileExtractor( is IrEnumEntry -> { val parentId = useDeclarationParent(declaration.parent, false)?.cast() if (parentId != null) { - extractEnumEntry(declaration, parentId, extractFunctionBodies) + extractEnumEntry(declaration, parentId, extractPrivateMembers, extractFunctionBodies) } Unit } @@ -1254,7 +1254,7 @@ open class KotlinFileExtractor( } } - private fun extractEnumEntry(ee: IrEnumEntry, parentId: Label, extractTypeAccess: Boolean) { + private fun extractEnumEntry(ee: IrEnumEntry, parentId: Label, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) { with("enum entry", ee) { DeclarationStackAdjuster(ee).use { val id = useEnumEntry(ee) @@ -1265,7 +1265,7 @@ open class KotlinFileExtractor( tw.writeHasLocation(id, locId) tw.writeIsEnumConst(id) - if (extractTypeAccess) { + if (extractFunctionBodies) { val fieldDeclarationId = tw.getFreshIdLabel() tw.writeFielddecls(fieldDeclarationId, parentId) tw.writeFieldDeclaredIn(id, fieldDeclarationId, 0) @@ -1273,6 +1273,10 @@ open class KotlinFileExtractor( extractTypeAccess(type, locId, fieldDeclarationId, 0) } + + ee.correspondingClass?.let { + extractDeclaration(it, extractPrivateMembers, extractFunctionBodies) + } } } } diff --git a/java/ql/test/kotlin/library-tests/methods/clinit.expected b/java/ql/test/kotlin/library-tests/methods/clinit.expected index ea5b5392d82..3bf5f170f08 100644 --- a/java/ql/test/kotlin/library-tests/methods/clinit.expected +++ b/java/ql/test/kotlin/library-tests/methods/clinit.expected @@ -1,2 +1,3 @@ | clinit.kt:0:0:0:0 | | file://:0:0:0:0 | void | | enumClass.kt:0:0:0:0 | | file://:0:0:0:0 | void | +| enumClass.kt:0:0:0:0 | | file://:0:0:0:0 | void | diff --git a/java/ql/test/kotlin/library-tests/methods/enumClass.kt b/java/ql/test/kotlin/library-tests/methods/enumClass.kt index 89568c0d5f4..9f3acad608a 100644 --- a/java/ql/test/kotlin/library-tests/methods/enumClass.kt +++ b/java/ql/test/kotlin/library-tests/methods/enumClass.kt @@ -2,3 +2,15 @@ enum class EnumClass(val v: Int) { enum1(1), enum2(1) } + +enum class EnumWithFunctions { + + VAL { + override fun f(i: Int) = i + override fun g(i: Int) = this.f(i) + i + }; + + abstract fun f(i: Int): Int + abstract fun g(i: Int): Int + +} diff --git a/java/ql/test/kotlin/library-tests/methods/exprs.expected b/java/ql/test/kotlin/library-tests/methods/exprs.expected index 77033a11bbe..bf15f66b6ef 100644 --- a/java/ql/test/kotlin/library-tests/methods/exprs.expected +++ b/java/ql/test/kotlin/library-tests/methods/exprs.expected @@ -226,6 +226,10 @@ | enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | | enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | | enumClass.kt:0:0:0:0 | EnumClass[] | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumWithFunctions | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumWithFunctions | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumWithFunctions[] | TypeAccess | +| enumClass.kt:0:0:0:0 | String | TypeAccess | | enumClass.kt:0:0:0:0 | String | TypeAccess | | enumClass.kt:1:1:4:1 | Enum | TypeAccess | | enumClass.kt:1:1:4:1 | EnumClass | TypeAccess | @@ -252,6 +256,33 @@ | enumClass.kt:3:5:3:12 | EnumClass.enum2 | VarAccess | | enumClass.kt:3:5:3:12 | new EnumClass(...) | ClassInstanceExpr | | enumClass.kt:3:11:3:11 | 1 | IntegerLiteral | +| enumClass.kt:6:1:16:1 | Enum | TypeAccess | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | TypeAccess | +| enumClass.kt:6:1:16:1 | new Enum(...) | ClassInstanceExpr | +| enumClass.kt:8:3:11:4 | ...=... | KtInitializerAssignExpr | +| enumClass.kt:8:3:11:4 | | ImplicitCoercionToUnitExpr | +| enumClass.kt:8:3:11:4 | EnumWithFunctions | TypeAccess | +| enumClass.kt:8:3:11:4 | EnumWithFunctions | TypeAccess | +| enumClass.kt:8:3:11:4 | EnumWithFunctions | TypeAccess | +| enumClass.kt:8:3:11:4 | EnumWithFunctions.VAL | VarAccess | +| enumClass.kt:8:3:11:4 | Unit | TypeAccess | +| enumClass.kt:8:3:11:4 | VAL | TypeAccess | +| enumClass.kt:8:3:11:4 | new EnumWithFunctions(...) | ClassInstanceExpr | +| enumClass.kt:8:3:11:4 | new VAL(...) | ClassInstanceExpr | +| enumClass.kt:9:14:9:30 | int | TypeAccess | +| enumClass.kt:9:20:9:25 | int | TypeAccess | +| enumClass.kt:9:30:9:30 | i | VarAccess | +| enumClass.kt:10:14:10:42 | int | TypeAccess | +| enumClass.kt:10:20:10:25 | int | TypeAccess | +| enumClass.kt:10:30:10:33 | this | ThisAccess | +| enumClass.kt:10:30:10:42 | ... + ... | AddExpr | +| enumClass.kt:10:35:10:38 | f(...) | MethodAccess | +| enumClass.kt:10:37:10:37 | i | VarAccess | +| enumClass.kt:10:42:10:42 | i | VarAccess | +| enumClass.kt:13:12:13:29 | int | TypeAccess | +| enumClass.kt:13:18:13:23 | int | TypeAccess | +| enumClass.kt:14:12:14:29 | int | TypeAccess | +| enumClass.kt:14:18:14:23 | int | TypeAccess | | methods2.kt:4:1:5:1 | Unit | TypeAccess | | methods2.kt:4:26:4:31 | int | TypeAccess | | methods2.kt:4:34:4:39 | int | TypeAccess | diff --git a/java/ql/test/kotlin/library-tests/methods/methods.expected b/java/ql/test/kotlin/library-tests/methods/methods.expected index 69c8e1ab214..8ee20aac587 100644 --- a/java/ql/test/kotlin/library-tests/methods/methods.expected +++ b/java/ql/test/kotlin/library-tests/methods/methods.expected @@ -29,6 +29,13 @@ methods | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | public, static | Compiler generated | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | values | values() | public, static | Compiler generated | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:22:1:31 | getV | getV() | public | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | | () | | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | public, static | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | values | values() | public, static | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:13:12:13:29 | f | f(int) | public | | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:14:12:14:29 | g | g(int) | public | | +| enumClass.kt:8:3:11:4 | VAL | enumClass.kt:9:14:9:30 | f | f(int) | override, public | | +| enumClass.kt:8:3:11:4 | VAL | enumClass.kt:10:14:10:42 | g | g(int) | override, public | | | methods2.kt:0:0:0:0 | Methods2Kt | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | fooBarTopLevelMethod(int,int) | public, static | | | methods2.kt:7:1:10:1 | Class2 | methods2.kt:8:5:9:5 | fooBarClassMethod | fooBarClassMethod(int,int) | public | | | methods3.kt:0:0:0:0 | Methods3Kt | methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | fooBarTopLevelMethodExt(int,int) | public, static | | @@ -56,6 +63,8 @@ constructors | delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | | | | delegates.kt:8:66:11:5 | new Function3,String,String,Unit>(...) { ... } | delegates.kt:8:66:11:5 | | | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:6:4:1 | EnumClass | EnumClass(int) | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:6:6:16:1 | EnumWithFunctions | EnumWithFunctions() | +| enumClass.kt:8:3:11:4 | VAL | enumClass.kt:8:3:11:4 | VAL | VAL() | | methods2.kt:7:1:10:1 | Class2 | methods2.kt:7:1:10:1 | Class2 | Class2() | | methods3.kt:5:1:7:1 | Class3 | methods3.kt:5:1:7:1 | Class3 | Class3() | | methods4.kt:3:1:11:1 | NestedTest | methods4.kt:3:1:11:1 | NestedTest | NestedTest() | diff --git a/java/ql/test/kotlin/library-tests/methods/parameters.expected b/java/ql/test/kotlin/library-tests/methods/parameters.expected index 7e76cdcb55b..4475aeba459 100644 --- a/java/ql/test/kotlin/library-tests/methods/parameters.expected +++ b/java/ql/test/kotlin/library-tests/methods/parameters.expected @@ -23,6 +23,11 @@ | delegates.kt:8:66:11:5 | invoke | delegates.kt:9:15:9:17 | old | 1 | | delegates.kt:8:66:11:5 | invoke | delegates.kt:9:20:9:22 | new | 2 | | enumClass.kt:0:0:0:0 | valueOf | enumClass.kt:0:0:0:0 | value | 0 | +| enumClass.kt:0:0:0:0 | valueOf | enumClass.kt:0:0:0:0 | value | 0 | +| enumClass.kt:9:14:9:30 | f | enumClass.kt:9:20:9:25 | i | 0 | +| enumClass.kt:10:14:10:42 | g | enumClass.kt:10:20:10:25 | i | 0 | +| enumClass.kt:13:12:13:29 | f | enumClass.kt:13:18:13:23 | i | 0 | +| enumClass.kt:14:12:14:29 | g | enumClass.kt:14:18:14:23 | i | 0 | | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | methods2.kt:4:26:4:31 | x | 0 | | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | methods2.kt:4:34:4:39 | y | 1 | | methods2.kt:8:5:9:5 | fooBarClassMethod | methods2.kt:8:27:8:32 | x | 0 | From 99b7c77abc0b85354d7a6675cd8d2bc0c27ecbf2 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 7 Oct 2022 13:44:36 +0200 Subject: [PATCH 59/82] add change-note --- go/ql/src/change-notes/2022-10-07-alert-messages.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/src/change-notes/2022-10-07-alert-messages.md diff --git a/go/ql/src/change-notes/2022-10-07-alert-messages.md b/go/ql/src/change-notes/2022-10-07-alert-messages.md new file mode 100644 index 00000000000..de46b7752eb --- /dev/null +++ b/go/ql/src/change-notes/2022-10-07-alert-messages.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. \ No newline at end of file From a6674a5313a6e2bd5127535266d1a9154f91efd7 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Fri, 7 Oct 2022 12:49:08 +0100 Subject: [PATCH 60/82] Ruby: fix uses of deprecated class name --- ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll | 2 +- .../frameworks/action_controller/params-flow.ql | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll index 839e197307c..8556c167b5d 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll @@ -392,7 +392,7 @@ private module ParamsSummaries { */ private class ParamsInstance extends DataFlow::Node { ParamsInstance() { - this.asExpr().getExpr() instanceof ParamsCall + this.asExpr().getExpr() instanceof Rails::ParamsCall or this = any(DataFlow::CallNode call | diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.ql b/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.ql index 3121b1e71ef..412ba5534b8 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.ql +++ b/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.ql @@ -5,10 +5,12 @@ import ruby import TestUtilities.InlineFlowTest import PathGraph -import codeql.ruby.frameworks.ActionController +import codeql.ruby.frameworks.Rails class ParamsTaintFlowConf extends DefaultTaintFlowConf { - override predicate isSource(DataFlow::Node n) { n.asExpr().getExpr() instanceof ParamsCall } + override predicate isSource(DataFlow::Node n) { + n.asExpr().getExpr() instanceof Rails::ParamsCall + } } from DataFlow::PathNode source, DataFlow::PathNode sink, ParamsTaintFlowConf conf From 115d4de0e0c6ac0e6cbf69043b52b171cb2fe9a5 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 7 Oct 2022 13:50:27 +0100 Subject: [PATCH 61/82] Kotlin: keep method overloads together --- .../src/main/kotlin/KotlinFileExtractor.kt | 99 +++++++++---------- 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index fc28db0a3b0..09e15bb4f67 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -1769,56 +1769,6 @@ open class KotlinFileExtractor( extractCallValueArguments(id, valueArgsWithDummies + extraArgs, enclosingStmt, enclosingCallable, nextIdx) } - fun extractRawMethodAccess( - syntacticCallTarget: IrFunction, - callsite: IrCall, - enclosingCallable: Label, - callsiteParent: Label, - childIdx: Int, - enclosingStmt: Label, - valueArguments: List, - dispatchReceiver: IrExpression?, - extensionReceiver: IrExpression?, - typeArguments: List = listOf(), - extractClassTypeArguments: Boolean = false, - superQualifierSymbol: IrClassSymbol? = null) { - - val locId = tw.getLocation(callsite) - - if (valueArguments.any { it == null }) { - extractsDefaultsCall( - syntacticCallTarget, - locId, - callsite, - enclosingCallable, - callsiteParent, - childIdx, - enclosingStmt, - valueArguments, - dispatchReceiver, - extensionReceiver - ) - } else { - extractRawMethodAccess( - syntacticCallTarget, - locId, - callsite.type, - enclosingCallable, - callsiteParent, - childIdx, - enclosingStmt, - valueArguments.size, - { argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) }, - dispatchReceiver?.type, - dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } }, - extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } }, - typeArguments, - extractClassTypeArguments, - superQualifierSymbol - ) - } - } - private fun getFunctionInvokeMethod(typeArgs: List): IrFunction? { // For `kotlin.FunctionX` and `kotlin.reflect.KFunctionX` interfaces, we're making sure that we // extract the call to the `invoke` method that does exist, `kotlin.jvm.functions.FunctionX::invoke`. @@ -1877,6 +1827,55 @@ open class KotlinFileExtractor( } } + fun extractRawMethodAccess( + syntacticCallTarget: IrFunction, + callsite: IrCall, + enclosingCallable: Label, + callsiteParent: Label, + childIdx: Int, + enclosingStmt: Label, + valueArguments: List, + dispatchReceiver: IrExpression?, + extensionReceiver: IrExpression?, + typeArguments: List = listOf(), + extractClassTypeArguments: Boolean = false, + superQualifierSymbol: IrClassSymbol? = null) { + + val locId = tw.getLocation(callsite) + + if (valueArguments.any { it == null }) { + extractsDefaultsCall( + syntacticCallTarget, + locId, + callsite, + enclosingCallable, + callsiteParent, + childIdx, + enclosingStmt, + valueArguments, + dispatchReceiver, + extensionReceiver + ) + } else { + extractRawMethodAccess( + syntacticCallTarget, + locId, + callsite.type, + enclosingCallable, + callsiteParent, + childIdx, + enclosingStmt, + valueArguments.size, + { argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) }, + dispatchReceiver?.type, + dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } }, + extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } }, + typeArguments, + extractClassTypeArguments, + superQualifierSymbol + ) + } + } fun extractRawMethodAccess( syntacticCallTarget: IrFunction, From b8ef9e0ddc271fc6713da74ae6f1c6387e5c9a9b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 7 Oct 2022 15:59:45 +0000 Subject: [PATCH 62/82] Post-release preparation for codeql-cli-2.11.1 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 2746ed855a3..fade2cc7c96 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.4.1 +version: 0.4.2-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 5bb1b4e6c67..169ac0a41ee 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.4.1 +version: 0.4.2-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 2bf4479335c..96ed3493829 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.3.1 +version: 1.3.2-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index d2bd8afddf1..888b9099b3d 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.3.1 +version: 1.3.2-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 5d5e75ad307..8b00f8845c2 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.4.1 +version: 0.4.2-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 2a80e25d0b6..682028cf7cc 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.4.1 +version: 0.4.2-dev groups: - csharp - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index cd565f720c5..3b38291ebb5 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.3.1 +version: 0.3.2-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 4a85f9fe6f3..574b63f69c1 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.3.1 +version: 0.3.2-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 3d5ea96dcc0..fc774265862 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.4.1 +version: 0.4.2-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 1377facc607..d74415382a4 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.4.1 +version: 0.4.2-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 5fe7be54a20..d5442a13f13 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.3.1 +version: 0.3.2-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 9a7548cadb1..c3157ce5043 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.4.1 +version: 0.4.2-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 911d334cc09..0c38110c86a 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.3.1 +version: 0.3.2-dev groups: shared diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 2104997ba95..aea8a2fe067 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.6.1 +version: 0.6.2-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 4f57ea416ec..31b6ab69f2e 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.5.1 +version: 0.5.2-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 8010fd63a50..1ed112d89d4 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.4.1 +version: 0.4.2-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 344a7b03f93..43e9df97f13 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.4.1 +version: 0.4.2-dev groups: - ruby - queries diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 54bf861fa2e..3fc606ae5ed 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/ssa -version: 0.0.2 +version: 0.0.3-dev groups: shared library: true diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 3b52e2e07fb..a8adea7ab70 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/typos -version: 0.0.2 +version: 0.0.3-dev groups: shared library: true From bef40119476bd035415fa56d12baa5b6ee08bca7 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 7 Oct 2022 17:31:38 +0100 Subject: [PATCH 63/82] Kotlin: fix type variable erasure inside default function values Previously because extractClassInstance didn't use the declaration stack, we wouldn't notice that it was legal to refer to its type variable in the context of extracting a specialised method <-> method source-decl edge. This led to erasing the types of the source-decl, so that e.g. Map.put(...) would have signature (Object, Object) not (K, V) as it should. --- .../src/main/kotlin/KotlinFileExtractor.kt | 16 +++++- .../src/main/kotlin/KotlinUsesExtractor.kt | 13 +---- .../parameter-defaults/PrintAst.expected | 56 +++++++++++++++++++ .../parameter-defaults/erasure.ql | 10 +++- .../library-tests/parameter-defaults/test.kt | 12 ++++ 5 files changed, 94 insertions(+), 13 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index fc28db0a3b0..e859a24141c 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -254,9 +254,23 @@ open class KotlinFileExtractor( } } + fun extractClassInstance(classLabel: Label, c: IrClass, argsIncludingOuterClasses: List?, shouldExtractOutline: Boolean, shouldExtractDetails: Boolean) { + DeclarationStackAdjuster(c).use { + if (shouldExtractOutline) { + extractClassWithoutMembers(c, argsIncludingOuterClasses) + } + + if (shouldExtractDetails) { + val supertypeMode = if (argsIncludingOuterClasses == null) ExtractSupertypesMode.Raw else ExtractSupertypesMode.Specialised(argsIncludingOuterClasses) + extractClassSupertypes(c, classLabel, supertypeMode, true) + extractNonPrivateMemberPrototypes(c, argsIncludingOuterClasses, classLabel) + } + } + } + // `argsIncludingOuterClasses` can be null to describe a raw generic type. // For non-generic types it will be zero-length list. - fun extractClassInstance(c: IrClass, argsIncludingOuterClasses: List?): Label { + private fun extractClassWithoutMembers(c: IrClass, argsIncludingOuterClasses: List?): Label { with("class instance", c) { if (argsIncludingOuterClasses?.isEmpty() == true) { logger.error("Instance without type arguments: " + c.name.asString()) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index da87bfe1169..1bd27278da0 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -411,16 +411,9 @@ open class KotlinUsesExtractor( if (replacedArgsIncludingOuterClasses == null || replacedArgsIncludingOuterClasses.isNotEmpty()) { // If this is a generic type instantiation or a raw type then it has no // source entity, so we need to extract it here - val extractorWithCSource by lazy { this.withFileOfClass(replacedClass) } - - if (!instanceSeenBefore) { - extractorWithCSource.extractClassInstance(replacedClass, replacedArgsIncludingOuterClasses) - } - - if (inReceiverContext && tw.lm.genericSpecialisationsExtracted.add(classLabelResult.classLabel)) { - val supertypeMode = if (replacedArgsIncludingOuterClasses == null) ExtractSupertypesMode.Raw else ExtractSupertypesMode.Specialised(replacedArgsIncludingOuterClasses) - extractorWithCSource.extractClassSupertypes(replacedClass, classLabel, supertypeMode, true) - extractorWithCSource.extractNonPrivateMemberPrototypes(replacedClass, replacedArgsIncludingOuterClasses, classLabel) + val shouldExtractClassDetails = inReceiverContext && tw.lm.genericSpecialisationsExtracted.add(classLabelResult.classLabel) + if (!instanceSeenBefore || shouldExtractClassDetails) { + this.withFileOfClass(replacedClass).extractClassInstance(classLabel, replacedClass, replacedArgsIncludingOuterClasses, !instanceSeenBefore, shouldExtractClassDetails) } } diff --git a/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected b/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected index ed590470d20..95198f2beaa 100644 --- a/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected @@ -1165,3 +1165,59 @@ test.kt: # 161| -1: [VarAccess] p0 # 161| 0: [VarAccess] p1 # 161| 1: [VarAccess] p2 +# 165| 15: [Class,GenericType,ParameterizedType] TestGenericUsedWithinDefaultValue +#-----| -2: (Generic Parameters) +# 165| 0: [TypeVariable] T +# 165| 1: [Constructor] TestGenericUsedWithinDefaultValue +# 165| 5: [BlockStmt] { ... } +# 165| 0: [SuperConstructorInvocationStmt] super(...) +# 165| 1: [BlockStmt] { ... } +# 171| 2: [Method] f +# 171| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 171| 0: [Parameter] x +# 171| 0: [TypeAccess] int +# 171| 1: [Parameter] y +# 171| 0: [TypeAccess] String +# 171| 5: [BlockStmt] { ... } +# 171| 3: [Method] f$default +# 171| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 171| 0: [Parameter] p0 +# 171| 0: [TypeAccess] TestGenericUsedWithinDefaultValue<> +# 171| 1: [Parameter] p1 +# 171| 0: [TypeAccess] int +# 171| 2: [Parameter] p2 +# 171| 0: [TypeAccess] String +# 171| 3: [Parameter] p3 +# 171| 0: [TypeAccess] int +# 171| 4: [Parameter] p4 +# 171| 0: [TypeAccess] Object +# 171| 5: [BlockStmt] { ... } +# 171| 0: [IfStmt] if (...) +# 171| 0: [EQExpr] ... == ... +# 171| 0: [AndBitwiseExpr] ... & ... +# 171| 0: [IntegerLiteral] 2 +# 171| 1: [VarAccess] p3 +# 171| 1: [IntegerLiteral] 0 +# 171| 1: [ExprStmt] ; +# 171| 0: [AssignExpr] ...=... +# 171| 0: [VarAccess] p2 +# 171| 1: [MethodAccess] ident(...) +# 171| -1: [ClassInstanceExpr] new TestGenericUsedWithinDefaultValue(...) +# 171| -3: [TypeAccess] TestGenericUsedWithinDefaultValue +# 171| 0: [TypeAccess] String +# 171| 0: [StringLiteral] Hello world +# 171| 1: [ReturnStmt] return ... +# 171| 0: [MethodAccess] f(...) +# 171| -1: [VarAccess] p0 +# 171| 0: [VarAccess] p1 +# 171| 1: [VarAccess] p2 +# 173| 4: [Method] ident +# 173| 3: [TypeAccess] T +#-----| 4: (Parameters) +# 173| 0: [Parameter] t +# 173| 0: [TypeAccess] T +# 173| 5: [BlockStmt] { ... } +# 173| 0: [ReturnStmt] return ... +# 173| 0: [VarAccess] t diff --git a/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql b/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql index b53a83e436c..9bb2ad44c15 100644 --- a/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql +++ b/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql @@ -1,9 +1,15 @@ import java +class InstantiatedType extends ParameterizedType { + InstantiatedType() { typeArgs(_, _, this) } +} + // This checks that all type parameter references are erased in the context of a $default function. predicate containsTypeVariables(Type t) { - t != t.getErasure() and - not t.getErasure().(GenericType).getRawType() = t + t instanceof TypeVariable or + containsTypeVariables(t.(InstantiatedType).getATypeArgument()) or + containsTypeVariables(t.(NestedType).getEnclosingType()) or + containsTypeVariables(t.(Wildcard).getATypeBound().getType()) } from Expr e diff --git a/java/ql/test/kotlin/library-tests/parameter-defaults/test.kt b/java/ql/test/kotlin/library-tests/parameter-defaults/test.kt index aa8684e8e70..25a29fb468f 100644 --- a/java/ql/test/kotlin/library-tests/parameter-defaults/test.kt +++ b/java/ql/test/kotlin/library-tests/parameter-defaults/test.kt @@ -161,3 +161,15 @@ class VisibilityTests { private fun i(x: Int, y: Int = 0) = x + y } + +class TestGenericUsedWithinDefaultValue { + + // This tests parameter erasure works properly: we should notice that here the type variable T + // isn't used in the specialisation TestGenericUsedWithinDefaultValue, but it can be + // cited in contexts like "the signature of the source declaration of 'TestGenericUsedWithinDefaultValue.f(String)' is 'f(T)'", + // not 'f(Object)' as we might mistakenly conclude if we're inappropriately erasing 'T'. + fun f(x: Int, y: String = TestGenericUsedWithinDefaultValue().ident("Hello world")) { } + + fun ident(t: T) = t + +} From 85f92ff80a5eaaef829956d7fcccdab4a72a2264 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 7 Oct 2022 17:49:03 +0100 Subject: [PATCH 64/82] Require --single-version with --single-version-embeddable --- java/kotlin-extractor/build.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index d714c799eed..8ea0162bf17 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -235,13 +235,19 @@ def compile_standalone(version): 'build_standalone_' + version, version) -compile_single_version = compile_embeddable if args.single_version_embeddable == True else compile_standalone + if args.single_version: - compile_single_version(args.single_version) + if args.single_version_embeddable == True: + compile_embeddable(args.single_version) + else: + compile_standalone(args.single_version) +elif args.single_version_embeddable != None: + print("--single-version-embeddable requires --single-version", file=sys.stderr) + sys.exit(1) elif args.many: for version in kotlin_plugin_versions.many_versions: compile_standalone(version) compile_embeddable(version) else: - compile_single_version(kotlin_plugin_versions.get_single_version()) + compile_standalone(kotlin_plugin_versions.get_single_version()) From 68967c40bcccfaac3a8170f3ca4371a780332bba Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 7 Oct 2022 17:49:51 +0100 Subject: [PATCH 65/82] Remove whitespace --- java/kotlin-extractor/build.py | 1 - 1 file changed, 1 deletion(-) diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index 8ea0162bf17..3aabeab2cec 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -236,7 +236,6 @@ def compile_standalone(version): version) - if args.single_version: if args.single_version_embeddable == True: compile_embeddable(args.single_version) From 9c0cdfde6b94a73eb1d8fbe23998f2e5e239095f Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 7 Oct 2022 18:02:32 +0100 Subject: [PATCH 66/82] Note store_true params default to False not None --- java/kotlin-extractor/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index 3aabeab2cec..9525522869b 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -241,7 +241,7 @@ if args.single_version: compile_embeddable(args.single_version) else: compile_standalone(args.single_version) -elif args.single_version_embeddable != None: +elif args.single_version_embeddable == True: print("--single-version-embeddable requires --single-version", file=sys.stderr) sys.exit(1) elif args.many: From 5dcb70e4821635ff743fb00e9a36a12e05a40a2f Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 7 Oct 2022 18:10:52 +0100 Subject: [PATCH 67/82] Make method private --- java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index e859a24141c..a6412efdc0e 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -356,7 +356,7 @@ open class KotlinFileExtractor( // `argsIncludingOuterClasses` can be null to describe a raw generic type. // For non-generic types it will be zero-length list. - fun extractNonPrivateMemberPrototypes(c: IrClass, argsIncludingOuterClasses: List?, id: Label) { + private fun extractNonPrivateMemberPrototypes(c: IrClass, argsIncludingOuterClasses: List?, id: Label) { with("member prototypes", c) { val typeParamSubstitution = when (argsIncludingOuterClasses) { From d707c526e5680913ec7180cd1a83c6edcfa91c36 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 9 Oct 2022 10:24:40 +0200 Subject: [PATCH 68/82] Ruby: Avoid computing full `fastTC` for `AstNode::getParent` DIL before ``` /* AST::AstNode */ AST#87953007::Cached::TAstNode result) = fastTC(Module#fe82a56b::parent#1#ff/2) . Module#fe82a56b::enclosingModule#1#ff(/* AST::AstNode */ AST#87953007::Cached::TAstNode node, /* Module::ModuleBase */ AST#87953007::Cached::TAstNode result) :- exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode call_result#2 | Module#2a43f566::ModuleBase#f(result), project#AST#a6718388::AstNode::getAChild#1#dispred(result, call_result#2), ( node = call_result#2; #Module#fe82a56b::parent#1Plus#ff(node, call_result#2) ) ) . ``` DIL after ``` incremental Module#fe82a56b::enclosingModule#1#ff(/* AST::AstNode */ AST#87953007::Cached::TAstNode node, /* Module::ModuleBase */ AST#87953007::Cached::TAstNode result) :- ( Module#2a43f566::ModuleBase#f(result), exists(cached dontcare string _ | AST#a6718388::AstNode::getAChild#1#dispred(result, _, node) ) ); exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode mid | Module#2a43f566::ModuleBase#f(result), rec Module#fe82a56b::enclosingModule#1#ff(mid, result), not(Module#2a43f566::ModuleBase#f(mid)), not(Method#8b49e67f::Block#f(mid)), exists(cached dontcare string _ | AST#a6718388::AstNode::getAChild#1#dispred(mid, _, node) ) ) | [base_case] Module#2a43f566::ModuleBase#f(result), project#AST#a6718388::AstNode::getAChild#1#dispred(result, node) | [delta_order] exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode mid | Module#2a43f566::ModuleBase#f(result), delta previous rec Module#fe82a56b::enclosingModule#1#ff(mid, result), not(Module#2a43f566::ModuleBase#f(mid)), not(Method#8b49e67f::Block#f(mid)), project#AST#a6718388::AstNode::getAChild#1#dispred(mid, node) ), not(previous rec Module#fe82a56b::enclosingModule#1#ff(node, result)) | [delta_order_up_to_500000] exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode mid | delta previous rec Module#fe82a56b::enclosingModule#1#ff(mid, result), Module#2a43f566::ModuleBase#f(result), not(Module#2a43f566::ModuleBase#f(mid)), not(Method#8b49e67f::Block#f(mid)), project#AST#a6718388::AstNode::getAChild#1#dispred(mid, node) ), not(previous rec Module#fe82a56b::enclosingModule#1#ff(node, result)) . ``` --- ruby/ql/lib/codeql/ruby/ast/internal/Module.qll | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll index 9a9626cf74f..67b53baa51c 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll @@ -486,12 +486,15 @@ private import ResolveImpl * methods evaluate the block in the context of some other module/class instead of * the enclosing one. */ -private ModuleBase enclosingModule(AstNode node) { result = parent*(node).getParent() } - -private AstNode parent(AstNode n) { - result = n.getParent() and - not result instanceof ModuleBase and - not result instanceof Block +private ModuleBase enclosingModule(AstNode node) { + result = node.getParent() + or + exists(AstNode mid | + result = enclosingModule(mid) and + mid = node.getParent() and + not mid instanceof ModuleBase and + not mid instanceof Block + ) } private Module getAncestors(Module m) { From 262a74d03d9efe64abf050cb7943ddd457ee6d63 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 9 Oct 2022 10:50:32 +0200 Subject: [PATCH 69/82] Ruby: Avoid computing full `fastTC` for `AstNode::getParent` DIL before ``` /* AST::AstNode */ AST#87953007::Cached::TAstNode result) = fastTC(AST#a6718388::AstNode::getAChild#0#dispred#ff/2) . Completion#445d5844::mayRaise#1#f(/* Call::Call */ unique AST#87953007::Cached::TAstNode c) :- exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode call_result#2 | exists(/* ControlFlowGraphImpl::Trees::BodyStmtTree */ AST#87953007::Cached::TAstNode bst | ( ( project#Expr#6fb2af19::BodyStmt::getRescue#1#dispred#fff(bst), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ); ( exists(/* Expr::StmtSequence */ dontcare AST#87953007::Cached::TAstNode _ | Expr#6fb2af19::BodyStmt::getEnsure#0#dispred#ff(bst, _) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst), project#ControlFlowGraphImpl#288ae92e::Trees::StmtSequenceTree::getBodyChild#2#dispred#ffff(bst, call_result#2) ), ( (c = call_result#2, Call#841c84e8::Call#f(c)); ( #AST#a6718388::AstNode::getAChild#0#dispredPlus#ff(call_result#2, c), Call#841c84e8::Call#f(c) ) ) ) . ``` DIL after ``` incremental Completion#445d5844::getARescuableBodyChild#0#f(/* AST::AstNode */ unique AST#87953007::Cached::TAstNode result) :- exists(/* ControlFlowGraphImpl::Trees::BodyStmtTree */ AST#87953007::Cached::TAstNode bst | ( ( exists(dontcare int _, /* Expr::RescueClause */ dontcare AST#87953007::Cached::TAstNode _1 | Expr#6fb2af19::BodyStmt::getRescue#1#dispred#fff(bst, _, _1) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ); ( exists(/* Expr::StmtSequence */ dontcare AST#87953007::Cached::TAstNode _ | Expr#6fb2af19::BodyStmt::getEnsure#0#dispred#ff(bst, _) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst), exists(boolean arg2, dontcare int _ | arg2 = true, ControlFlowGraphImpl#288ae92e::Trees::StmtSequenceTree::getBodyChild#2#dispred#ffff(bst, _, arg2, result) ) ); exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode call_result#5 | rec Completion#445d5844::getARescuableBodyChild#0#f(call_result#5), exists(cached dontcare string _ | AST#a6718388::AstNode::getAChild#1#dispred(call_result#5, _, result) ) ) | [base_case] exists(/* ControlFlowGraphImpl::Trees::BodyStmtTree */ AST#87953007::Cached::TAstNode bst | ( ( project#Expr#6fb2af19::BodyStmt::getRescue#1#dispred#fff(bst), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ); ( exists(/* Expr::StmtSequence */ dontcare AST#87953007::Cached::TAstNode _ | Expr#6fb2af19::BodyStmt::getEnsure#0#dispred#ff(bst, _) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst), project#ControlFlowGraphImpl#288ae92e::Trees::StmtSequenceTree::getBodyChild#2#dispred#ffff(bst, result) ) | [delta_order] exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode call_result#5 | delta previous rec Completion#445d5844::getARescuableBodyChild#0#f(call_result#5), project#AST#a6718388::AstNode::getAChild#1#dispred(call_result#5, result) ), not(previous rec Completion#445d5844::getARescuableBodyChild#0#f(result)) . ``` --- .../ruby/controlflow/internal/Completion.qll | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll index 7615357453d..fe4cca24d69 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll @@ -71,18 +71,22 @@ private predicate completionIsValidForStmt(AstNode n, Completion c) { c = TReturnCompletion() } +private AstNode getARescuableBodyChild() { + exists(Trees::BodyStmtTree bst | result = bst.getBodyChild(_, true) | + exists(bst.getARescue()) + or + exists(bst.getEnsure()) + ) + or + result = getARescuableBodyChild().getAChild() +} + /** * Holds if `c` happens in an exception-aware context, that is, it may be * `rescue`d or `ensure`d. In such cases, we assume that the target of `c` * may raise an exception (in addition to evaluating normally). */ -private predicate mayRaise(Call c) { - exists(Trees::BodyStmtTree bst | c = bst.getBodyChild(_, true).getAChild*() | - exists(bst.getARescue()) - or - exists(bst.getEnsure()) - ) -} +private predicate mayRaise(Call c) { c = getARescuableBodyChild() } /** A completion of a statement or an expression. */ abstract class Completion extends TCompletion { From d39b0fd3f42e9f0e5699ec19b2f67d775a0f804e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 9 Oct 2022 10:52:06 +0200 Subject: [PATCH 70/82] Ruby: Avoid computing full `fastTC` for `AstNode::getParent` DIL before ``` /* AST::AstNode */ AST#87953007::Cached::TAstNode result) = fastTC(AST#a6718388::AstNode::getAChild#0#dispred#ff/2) . Synthesis#d9ff06b1::isInDesugaredContext#1#f(/* AST::AstNode */ unique AST#87953007::Cached::TAstNode n) :- exists(int arg1, /* AST::AstNode */ dontcare AST#87953007::Cached::TAstNode _ | arg1 = -1, AST#87953007::Cached::getSynthChild#2(_, arg1, n) ); exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode call_result#2 | exists(int arg1, /* AST::AstNode */ dontcare AST#87953007::Cached::TAstNode _ | arg1 = -1, AST#87953007::Cached::getSynthChild#2(_, arg1, call_result#2) ), #AST#a6718388::AstNode::getAChild#0#dispredPlus#ff(call_result#2, n) ) . ``` DIL after ``` incremental Synthesis#d9ff06b1::isInDesugaredContext#1#f(/* AST::AstNode */ unique AST#87953007::Cached::TAstNode n) :- exists(int arg1, /* AST::AstNode */ dontcare AST#87953007::Cached::TAstNode _ | arg1 = -1, AST#87953007::Cached::getSynthChild#2(_, arg1, n) ); exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode any#expr##2 | rec Synthesis#d9ff06b1::isInDesugaredContext#1#f(any#expr##2), exists(cached dontcare string _ | AST#a6718388::AstNode::getAChild#1#dispred(any#expr##2, _, n) ) ) | [base_case] exists(int arg1, /* AST::AstNode */ dontcare AST#87953007::Cached::TAstNode _ | arg1 = -1, AST#87953007::Cached::getSynthChild#2(_, arg1, n) ) | [delta_order] exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode any#expr##2 | delta previous rec Synthesis#d9ff06b1::isInDesugaredContext#1#f(any#expr##2), project#AST#a6718388::AstNode::getAChild#1#dispred(any#expr##2, n) ), not(previous rec Synthesis#d9ff06b1::isInDesugaredContext#1#f(n)) . `` --- ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index 6eaafee71af..5b18756bd5b 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -132,7 +132,10 @@ int desugarLevel(AstNode n) { result = count(Desugared desugared | n = desugared * Holds if `n` appears in a context that is desugared. That is, a * transitive, reflexive parent of `n` is a desugared node. */ -predicate isInDesugaredContext(AstNode n) { n = any(AstNode sugar).getDesugared().getAChild*() } +predicate isInDesugaredContext(AstNode n) { + n = any(AstNode sugar).getDesugared() or + n = any(AstNode mid | isInDesugaredContext(mid)).getAChild() +} /** * Holds if `n` is a node that only exists as a result of desugaring some From 02192acd5fc1e6aac03b1c13ea83c827ca6ca7be Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 9 Oct 2022 10:53:23 +0200 Subject: [PATCH 71/82] Ruby: Avoid computing full `fastTC` for `AstNode::getParent` DIL before ``` /* AST::AstNode */ AST#87953007::Cached::TAstNode result) = fastTC(AST#a6718388::AstNode::getAChild#0#dispred#ff/2) . Synthesis#d9ff06b1::Desugared::getADescendant#0#dispred#ff(/* Synthesis::Desugared */ AST#87953007::Cached::TAstNode this, /* AST::AstNode */ AST#87953007::Cached::TAstNode result) :- ( exists(int arg1, /* AST::AstNode */ dontcare AST#87953007::Cached::TAstNode _ | arg1 = -1, AST#87953007::Cached::getSynthChild#2(_, arg1, this) ), result = this ); ( exists(int arg1, /* AST::AstNode */ dontcare AST#87953007::Cached::TAstNode _ | arg1 = -1, AST#87953007::Cached::getSynthChild#2(_, arg1, this) ), #AST#a6718388::AstNode::getAChild#0#dispredPlus#ff(this, result) ) . ``` DIL after ``` incremental Synthesis#d9ff06b1::Desugared::getADescendant#ff(/* Synthesis::Desugared */ AST#87953007::Cached::TAstNode this, /* AST::AstNode */ AST#87953007::Cached::TAstNode result) :- ( exists(int arg1, /* AST::AstNode */ dontcare AST#87953007::Cached::TAstNode _ | arg1 = -1, AST#87953007::Cached::getSynthChild#2(_, arg1, this) ), result = this ); exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode call_result#2 | exists(int arg1, /* AST::AstNode */ dontcare AST#87953007::Cached::TAstNode _ | arg1 = -1, AST#87953007::Cached::getSynthChild#2(_, arg1, this) ), rec Synthesis#d9ff06b1::Desugared::getADescendant#ff(this, call_result#2), exists(cached dontcare string _ | AST#a6718388::AstNode::getAChild#1#dispred(call_result#2, _, result) ) ) | [base_case] exists(int arg1, /* AST::AstNode */ dontcare AST#87953007::Cached::TAstNode _ | arg1 = -1, AST#87953007::Cached::getSynthChild#2(_, arg1, this) ), result = this | [delta_order] exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode call_result#2 | exists(int arg1, /* AST::AstNode */ dontcare AST#87953007::Cached::TAstNode _ | arg1 = -1, AST#87953007::Cached::getSynthChild#2(_, arg1, this) ), delta previous rec Synthesis#d9ff06b1::Desugared::getADescendant#ff(this, call_result#2), project#AST#a6718388::AstNode::getAChild#1#dispred(call_result#2, result) ), not( previous rec Synthesis#d9ff06b1::Desugared::getADescendant#ff(this, result) ) | [delta_order_up_to_500000] exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode call_result#2 | delta previous rec Synthesis#d9ff06b1::Desugared::getADescendant#ff(this, call_result#2), exists(int arg1, /* AST::AstNode */ dontcare AST#87953007::Cached::TAstNode _ | arg1 = -1, AST#87953007::Cached::getSynthChild#2(_, arg1, this) ), project#AST#a6718388::AstNode::getAChild#1#dispred(call_result#2, result) ), not( previous rec Synthesis#d9ff06b1::Desugared::getADescendant#ff(this, result) ) . ``` --- ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index 5b18756bd5b..1ab4435a85a 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -118,7 +118,11 @@ class Synthesis extends TSynthesis { private class Desugared extends AstNode { Desugared() { this = any(AstNode sugar).getDesugared() } - AstNode getADescendant() { result = this.getAChild*() } + AstNode getADescendant() { + result = this + or + result = this.getADescendant().getAChild() + } } /** From d1c8c40c1705baba33b85b50425f85078375960d Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 9 Oct 2022 19:46:48 +0200 Subject: [PATCH 72/82] Data flow: Avoid call to `pathSuccPlus` in `Configuration::hasFlowTo(Expr)` --- .../codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. From 296ec94a2a958fb9c223433c6e06a2420bd46de2 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 9 Oct 2022 19:47:48 +0200 Subject: [PATCH 73/82] Data flow: Sync files --- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll | 4 +++- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll | 4 +++- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll | 4 +++- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll | 4 +++- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll | 4 +++- .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll | 4 +++- .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll | 4 +++- .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll | 4 +++- .../semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll | 4 +++- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll | 4 +++- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll | 4 +++- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll | 4 +++- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll | 4 +++- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll | 4 +++- .../semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll | 4 +++- .../semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll | 4 +++- .../semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll | 4 +++- .../semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll | 4 +++- .../dataflow/internal/DataFlowImplForContentDataFlow.qll | 4 +++- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll | 4 +++- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll | 4 +++- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll | 4 +++- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll | 4 +++- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll | 4 +++- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll | 4 +++- .../dataflow/internal/DataFlowImplForOnActivityResult.qll | 4 +++- .../java/dataflow/internal/DataFlowImplForSerializability.qll | 4 +++- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll | 4 +++- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll | 4 +++- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll | 4 +++- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll | 4 +++- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll | 4 +++- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll | 4 +++- .../dataflow/internal/DataFlowImplForHttpClientLibraries.qll | 4 +++- .../codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll | 4 +++- swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll | 4 +++- 36 files changed, 108 insertions(+), 36 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. From 9f34bf80fd15ac682cef9aa16a1d7e45541c3b71 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 9 Oct 2022 19:59:05 +0200 Subject: [PATCH 74/82] Ruby: Cache use of `DataFlowImplForPathname` --- ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll index 0939e6c17c8..85db78252c8 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll @@ -27,6 +27,7 @@ module Pathname { * Every `PathnameInstance` is considered to be a `FileNameSource`. */ class PathnameInstance extends FileNameSource { + cached PathnameInstance() { any(PathnameConfiguration c).hasFlowTo(this) } } From efa6b3c0c656dd46c341ba8e56a11ff44bf7a99d Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 9 Oct 2022 19:59:56 +0200 Subject: [PATCH 75/82] Ruby: Cache uses of `DataFlowImplForHttpClientLibraries` --- ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll | 1 + ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll | 1 + ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll | 1 + ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll | 1 + ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll | 1 + ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll | 2 ++ ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll | 1 + ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll | 1 + 8 files changed, 9 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll index 4468f8ffa58..37b3cdbd576 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll @@ -70,6 +70,7 @@ class ExconHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode ) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll index ae4bb25c265..139a484f87a 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll @@ -71,6 +71,7 @@ class FaradayHttpRequest extends Http::Client::Request::Range, DataFlow::CallNod ) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll index 0d8e6cfa0fc..51537e25148 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll @@ -61,6 +61,7 @@ class HttpClientRequest extends Http::Client::Request::Range, DataFlow::CallNode .getArgument(0) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll index 08ab0f94141..e0b5de43351 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll @@ -53,6 +53,7 @@ class HttpartyRequest extends Http::Client::Request::Range, DataFlow::CallNode { result = this.getKeywordArgumentIncludeHashArgument(["verify", "verify_peer"]) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll index f12f6fa8e30..d6dbd581f86 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll @@ -80,6 +80,7 @@ class NetHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode { ) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll index f11a4b2908f..68ca62beaf8 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll @@ -42,6 +42,7 @@ class OpenUriRequest extends Http::Client::Request::Range, DataFlow::CallNode { result = this.getKeywordArgumentIncludeHashArgument("ssl_verify_mode") } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { @@ -91,6 +92,7 @@ class OpenUriKernelOpenRequest extends Http::Client::Request::Range, DataFlow::C ) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll index 4b9ddfaab41..7df9875b00c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll @@ -54,6 +54,7 @@ class RestClientHttpRequest extends Http::Client::Request::Range, DataFlow::Call ) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll index 163560e61f9..e41add437d3 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll @@ -34,6 +34,7 @@ class TyphoeusHttpRequest extends Http::Client::Request::Range, DataFlow::CallNo result = this.getKeywordArgumentIncludeHashArgument("ssl_verifypeer") } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { From 059864587e7ed39b1674062b1ce56dfd2bdc95e4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 10 Oct 2022 11:00:18 +0100 Subject: [PATCH 76/82] C++: Add 'mremap' to whitelist. --- cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql b/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql index a378d50b0df..9c456f71bbb 100644 --- a/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql +++ b/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql @@ -67,11 +67,7 @@ class VarargsFunction extends Function { not exists(FunctionCall fc, int index | this.nonTrailingVarArgValue(fc, index) = result) } - predicate isWhitelisted() { - this.hasGlobalName("open") or - this.hasGlobalName("fcntl") or - this.hasGlobalName("ptrace") - } + predicate isWhitelisted() { this.hasGlobalName(["open", "fcntl", "ptrace", "mremap"]) } } from VarargsFunction f, FunctionCall fc, string terminator, int cnt, int totalCount From 08d6b2f30ae8a8d5343c0e732db8d08e595ec1ea Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Mon, 10 Oct 2022 13:46:18 +0200 Subject: [PATCH 77/82] Python: Fix typo in qldoc --- python/ql/lib/semmle/python/Concepts.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/ql/lib/semmle/python/Concepts.qll b/python/ql/lib/semmle/python/Concepts.qll index b4f1c73e633..fe091f84e9c 100644 --- a/python/ql/lib/semmle/python/Concepts.qll +++ b/python/ql/lib/semmle/python/Concepts.qll @@ -344,7 +344,7 @@ module SqlConstruction { * A data-flow node that executes SQL statements. * * If the context of interest is such that merely constructing an SQL statement - * would be valuabe to report, then consider using `SqlConstruction`. + * would be valuable to report, then consider using `SqlConstruction`. * * Extend this class to refine existing API models. If you want to model new APIs, * extend `SqlExecution::Range` instead. @@ -360,7 +360,7 @@ module SqlExecution { * A data-flow node that executes SQL statements. * * If the context of interest is such that merely constructing an SQL statement - * would be valuabe to report, then consider using `SqlConstruction`. + * would be valuable to report, then consider using `SqlConstruction`. * * Extend this class to model new APIs. If you want to refine existing API models, * extend `SqlExecution` instead. @@ -465,7 +465,7 @@ module XML { * A data-flow node that executes a xpath expression. * * If the context of interest is such that merely constructing an XPath expression - * would be valuabe to report, then consider using `XPathConstruction`. + * would be valuable to report, then consider using `XPathConstruction`. * * Extend this class to refine existing API models. If you want to model new APIs, * extend `XPathExecution::Range` instead. @@ -487,7 +487,7 @@ module XML { * A data-flow node that executes a XPath expression. * * If the context of interest is such that merely constructing an XPath expression - * would be valuabe to report, then consider using `XPathConstruction`. + * would be valuable to report, then consider using `XPathConstruction`. * * Extend this class to model new APIs. If you want to refine existing API models, * extend `XPathExecution` instead. From 544e2e4107528ad57bf71cc64bc4b8bbaabd6332 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Mon, 10 Oct 2022 14:42:15 +0200 Subject: [PATCH 78/82] Remove path based generated file classification --- java/ql/lib/semmle/code/java/GeneratedFiles.qll | 7 ------- .../kotlin/library-tests/GeneratedFiles/Generated.expected | 1 - .../GeneratedFiles/generated/source/NonGenerated.kt | 1 - .../GeneratedFiles/generated/source/kapt/Generated.kt | 1 - 4 files changed, 10 deletions(-) delete mode 100644 java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/NonGenerated.kt delete mode 100644 java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/kapt/Generated.kt diff --git a/java/ql/lib/semmle/code/java/GeneratedFiles.qll b/java/ql/lib/semmle/code/java/GeneratedFiles.qll index cfd72e02938..79197653848 100644 --- a/java/ql/lib/semmle/code/java/GeneratedFiles.qll +++ b/java/ql/lib/semmle/code/java/GeneratedFiles.qll @@ -65,10 +65,3 @@ private class GeneratedFileMarker extends Top { ) } } - -/** - * A file detected as generated by the Kotlin Annotation Processing Tool (kapt). Detection is based on file path. - */ -private class KaptFile extends GeneratedFile { - KaptFile() { this.getRelativePath().matches("%/generated/source/kapt%") } -} diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.expected b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.expected index 0a5b4c6ff29..6b4abd0e1a4 100644 --- a/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.expected +++ b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.expected @@ -1,2 +1 @@ | Generated.kt:0:0:0:0 | Generated | -| generated/source/kapt/Generated.kt:0:0:0:0 | Generated | diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/NonGenerated.kt b/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/NonGenerated.kt deleted file mode 100644 index a7f289eeb2f..00000000000 --- a/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/NonGenerated.kt +++ /dev/null @@ -1 +0,0 @@ -class D \ No newline at end of file diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/kapt/Generated.kt b/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/kapt/Generated.kt deleted file mode 100644 index 9dccdd5e595..00000000000 --- a/java/ql/test/kotlin/library-tests/GeneratedFiles/generated/source/kapt/Generated.kt +++ /dev/null @@ -1 +0,0 @@ -class C \ No newline at end of file From f7203bfcb82b5cf3907c0deacbf094fa8b7e7008 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Mon, 10 Oct 2022 15:27:45 +0200 Subject: [PATCH 79/82] CI: fix qhelp preview The command to gather the changed files uses NULL character terminated "lines", therefore we should supply the `-z` flag to `basename` as well. Otherwise we end up calling `git grep -l "\n"` which would list all files containing a newline. --- .github/workflows/qhelp-pr-preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/qhelp-pr-preview.yml b/.github/workflows/qhelp-pr-preview.yml index 5cca4faf540..a44ef5ad48d 100644 --- a/.github/workflows/qhelp-pr-preview.yml +++ b/.github/workflows/qhelp-pr-preview.yml @@ -52,7 +52,7 @@ jobs: id: changes run: | (git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.qhelp$' | grep -z -v '.inc.qhelp'; - git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.inc.qhelp$' | xargs --null -rn1 basename | xargs --null -rn1 git grep -z -l) | + git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.inc.qhelp$' | xargs --null -rn1 basename -z | xargs --null -rn1 git grep -z -l) | grep -z '.qhelp$' | grep -z -v '^-' | sort -z -u > "${RUNNER_TEMP}/paths.txt" - name: QHelp preview From 67cef92f94bf3adf412b1ca41e5b72b63c0f8a9b Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 7 Oct 2022 12:38:46 +0200 Subject: [PATCH 80/82] JS: Rewrite to use DataFlow::Node API and restrict context --- .../javascript/dataflow/TaintTracking.qll | 44 +++++++------------ .../Security/CWE-079/DomBasedXss/Xss.expected | 7 --- .../XssWithAdditionalSources.expected | 7 --- 3 files changed, 17 insertions(+), 41 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index c3cc9869cc4..fc78c8a9ad1 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -711,41 +711,31 @@ module TaintTracking { } } + /** + * Gets a local source of any part of the input to the given stringification `call`. + */ + private DataFlow::Node getAJsonLocalInput(JsonStringifyCall call) { + result = call.getInput() + or + exists(DataFlow::SourceNode source | source = getAJsonLocalInput(call).getALocalSource() | + result = source.getAPropertyWrite().getRhs() + or + result = source.(DataFlow::ObjectLiteralNode).getASpreadProperty() + or + result = source.(DataFlow::ArrayCreationNode).getASpreadArgument() + ) + } + /** * A taint propagating data flow edge arising from JSON unparsing. */ private class JsonStringifyTaintStep extends SharedTaintStep { override predicate serializeStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(JsonStringifyCall call, DataFlow::Node arg | - arg = call.getArgument(0) and - this.findInObject(arg.asExpr(), pred.asExpr()) and + exists(JsonStringifyCall call | + pred = getAJsonLocalInput(call) and succ = call ) } - - // find target in root object recursively - private predicate findInObject(Expr root, Expr target) { - // base case - root = target - or - // when root is Object - exists(Property property | - root instanceof ObjectExpr and - property = root.(ObjectExpr).getAProperty() and - ( - this.findInObject(property.getNameExpr(), target) or - this.findInObject(property.getInit(), target) - ) - ) - or - // when root is Array - root instanceof ArrayExpr and - this.findInObject(root.(ArrayExpr).getAChildExpr(), target) - or - // when root is VarRef - root instanceof VarRef and - this.findInObject(root.(VarRef).getAVariable().getAnAssignedExpr(), target) - } } /** diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 6303a737716..4582ba675a4 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -1533,13 +1533,6 @@ edges | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index 82fb3119575..5c5232b11d2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -1583,13 +1583,6 @@ edges | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | -| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | From ecf7ed38e01483cacbc0d1928e55777e21fee76c Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 10 Oct 2022 11:55:54 +0200 Subject: [PATCH 81/82] JS: Performance tweak --- .../ql/lib/semmle/javascript/dataflow/TaintTracking.qll | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index fc78c8a9ad1..2e7a9dd4f34 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -714,10 +714,13 @@ module TaintTracking { /** * Gets a local source of any part of the input to the given stringification `call`. */ + pragma[nomagic] private DataFlow::Node getAJsonLocalInput(JsonStringifyCall call) { result = call.getInput() or - exists(DataFlow::SourceNode source | source = getAJsonLocalInput(call).getALocalSource() | + exists(DataFlow::SourceNode source | + source = pragma[only_bind_out](getAJsonLocalInput(call)).getALocalSource() + | result = source.getAPropertyWrite().getRhs() or result = source.(DataFlow::ObjectLiteralNode).getASpreadProperty() From b1a165ee980085910619ec62f878ed6ce3145e07 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 10 Oct 2022 15:12:23 +0200 Subject: [PATCH 82/82] JS: Edit change note --- .../src/change-notes/2022-10-04-json-stringify-improvement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/change-notes/2022-10-04-json-stringify-improvement.md b/javascript/ql/src/change-notes/2022-10-04-json-stringify-improvement.md index 5d488ff0a48..0480c231a16 100644 --- a/javascript/ql/src/change-notes/2022-10-04-json-stringify-improvement.md +++ b/javascript/ql/src/change-notes/2022-10-04-json-stringify-improvement.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* Improved taint tracking behavior when the `JSON.stringify` method called. Previously, `JsonStringifyTaintStep` detects only if the source is equal to an argument. Now, it can detect the case that the argument is object and source is located in its property. +* Improved taint tracking through `JSON.stringify` in cases where a tainted value is stored somewhere in the input object.