From 486a5ac96f1682c352ee033ab39312b9ebf721eb Mon Sep 17 00:00:00 2001
From: amammad
Date: Thu, 23 Feb 2023 21:23:05 +0100
Subject: [PATCH 01/21] v1
---
.../YAMLUnsafeYamlDeserialization.qhelp | 20 +++++
.../CWE-502/YAMLUnsafeYamlDeserialization.ql | 87 +++++++++++++++++++
.../CWE-502/YAMLUnsafeYamlDeserialization.rb | 20 +++++
.../YAMLUnsafeYamlDeserialization.expected | 70 +++++++++++++++
.../YAMLUnsafeYamlDeserialization.qlref | 1 +
.../CWE-502/YAMLUnsafeYamlDeserialization.rb | 20 +++++
6 files changed, 218 insertions(+)
create mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp
create mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
create mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb
create mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected
create mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref
create mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb
diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp
new file mode 100644
index 00000000000..821747e0b52
--- /dev/null
+++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp
@@ -0,0 +1,20 @@
+
+
+
+
+ Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application.
+ Unsafe deserializing the malicious serialized yaml document through the Psych (YAML) library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain.
+
+
+
+
+ After Psych(YAML) 4.0.0, the load method is same as safe_load method.
+ This vulnerability can be prevented by using YAML.load (same as YAML.safe_load), YAML.load_file (same as YAML.safe_load_file) instead of YAML.unsafe_* methods.
+ Be careful that YAML.load_stream don't use safe_load method, Also Be careful the to_ruby method of Psych get called on a trusted parsed (YAML.parse*) yaml document.
+
+
+
+ In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.
+
+
+
\ No newline at end of file
diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
new file mode 100644
index 00000000000..668dc822b15
--- /dev/null
+++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
@@ -0,0 +1,87 @@
+/**
+ * @name Deserialization of user-controlled data by YAML
+ * @description Deserializing user-controlled data may allow attackers to
+ * execute arbitrary code.
+ * @kind path-problem
+ * @problem.severity warning
+ * @security-severity 9.8
+ * @precision high
+ * @id rb/YAML-unsafe-deserialization
+ * @tags security
+ * experimental
+ * external/cwe/cwe-502
+ */
+
+import codeql.ruby.AST
+import codeql.ruby.ApiGraphs
+import codeql.ruby.DataFlow
+import codeql.ruby.dataflow.RemoteFlowSources
+import codeql.ruby.TaintTracking
+import DataFlow::PathGraph
+
+abstract class YAMLSink extends DataFlow::Node { }
+
+class YamlunsafeLoadArgument extends YAMLSink {
+ YamlunsafeLoadArgument() {
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"])
+ .getArgument(0)
+ or
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall(["unsafe_load", "load_stream"])
+ .getKeywordArgument("yaml")
+ or
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall("unsafe_load_file")
+ .getKeywordArgument("filename")
+ }
+}
+
+class Configuration extends TaintTracking::Configuration {
+ Configuration() { this = "UnsafeDeserialization" }
+
+ override predicate isSource(DataFlow::Node source) {
+ // for detecting The CVE we should uncomment following line instead of current RemoteFlowSource
+ source instanceof DataFlow::LocalSourceNode
+ // source instanceof RemoteFlowSource
+ }
+
+ override predicate isSink(DataFlow::Node sink) {
+ // for detecting The CVE we should uncomment following line
+ // sink.getLocation().getFile().toString().matches("%yaml_column%") and
+ sink instanceof YAMLSink or
+ sink =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall(["parse", "parse_stream", "parse_file"])
+ .getAMethodCall("to_ruby")
+ }
+
+ override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
+ exists(DataFlow::CallNode yaml_parser_methods |
+ yaml_parser_methods =
+ API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and
+ (
+ nodeFrom = yaml_parser_methods.getArgument(0) or
+ nodeFrom = yaml_parser_methods.getKeywordArgument("yaml")
+ ) and
+ nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
+ )
+ or
+ exists(DataFlow::CallNode yaml_parser_methods |
+ yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and
+ (
+ nodeFrom = yaml_parser_methods.getArgument(0) or
+ nodeFrom = yaml_parser_methods.getKeywordArgument("filename")
+ ) and
+ nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
+ )
+ }
+}
+
+from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
+where config.hasFlowPath(source, sink)
+select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(),
+ "potentially untrusted source"
diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb
new file mode 100644
index 00000000000..58ea8024350
--- /dev/null
+++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb
@@ -0,0 +1,20 @@
+require 'yaml'
+class UsersController < ActionController::Base
+ def example
+ # safe
+ Psych.load(params[:yaml_string])
+ Psych.load_file(params[:yaml_file])
+ Psych.parse_stream(params[:yaml_string])
+ Psych.parse(params[:yaml_string])
+ Psych.parse_file(params[:yaml_file])
+ # unsafe
+ Psych.unsafe_load(params[:yaml_string])
+ Psych.unsafe_load_file(params[:yaml_file])
+ Psych.load_stream(params[:yaml_string])
+ Psych.parse_stream(params[:yaml_string]).to_ruby
+ Psych.parse(params[:yaml_string]).to_ruby
+ Psych.parse_file(params[:yaml_file]).to_ruby
+
+ end
+end
+
diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected
new file mode 100644
index 00000000000..e274fb6f005
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected
@@ -0,0 +1,70 @@
+edges
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby |
+| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] |
+| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] |
+| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] |
+| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : |
+| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : |
+| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : |
+| file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] |
+| file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : |
+| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] |
+| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] |
+| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : |
+| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : |
+nodes
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | semmle.label | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | semmle.label | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | semmle.label | ...[...] : |
+| file://:0:0:0:0 | parameter self of [] : | semmle.label | parameter self of [] : |
+| file://:0:0:0:0 | parameter self of [](:yaml_file) : | semmle.label | parameter self of [](:yaml_file) : |
+| file://:0:0:0:0 | parameter self of [](:yaml_string) : | semmle.label | parameter self of [](:yaml_string) : |
+subpaths
+#select
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_file) | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_file) | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref
new file mode 100644
index 00000000000..7e9e87117f9
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref
@@ -0,0 +1 @@
+experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb
new file mode 100644
index 00000000000..58ea8024350
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb
@@ -0,0 +1,20 @@
+require 'yaml'
+class UsersController < ActionController::Base
+ def example
+ # safe
+ Psych.load(params[:yaml_string])
+ Psych.load_file(params[:yaml_file])
+ Psych.parse_stream(params[:yaml_string])
+ Psych.parse(params[:yaml_string])
+ Psych.parse_file(params[:yaml_file])
+ # unsafe
+ Psych.unsafe_load(params[:yaml_string])
+ Psych.unsafe_load_file(params[:yaml_file])
+ Psych.load_stream(params[:yaml_string])
+ Psych.parse_stream(params[:yaml_string]).to_ruby
+ Psych.parse(params[:yaml_string]).to_ruby
+ Psych.parse_file(params[:yaml_file]).to_ruby
+
+ end
+end
+
From e4b8a0e06dcfd027ea28bf73f0ab2c564d8c47e7 Mon Sep 17 00:00:00 2001
From: amammad
Date: Thu, 23 Feb 2023 21:45:33 +0100
Subject: [PATCH 02/21] v1.1
---
.../experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
index 668dc822b15..e8b3fb761f4 100644
--- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
+++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
@@ -18,6 +18,7 @@ import codeql.ruby.DataFlow
import codeql.ruby.dataflow.RemoteFlowSources
import codeql.ruby.TaintTracking
import DataFlow::PathGraph
+import codeql.ruby.security.UnsafeDeserializationCustomizations
abstract class YAMLSink extends DataFlow::Node { }
@@ -45,8 +46,8 @@ class Configuration extends TaintTracking::Configuration {
override predicate isSource(DataFlow::Node source) {
// for detecting The CVE we should uncomment following line instead of current RemoteFlowSource
- source instanceof DataFlow::LocalSourceNode
- // source instanceof RemoteFlowSource
+ // source instanceof DataFlow::LocalSourceNode
+ source instanceof UnsafeDeserialization::Source
}
override predicate isSink(DataFlow::Node sink) {
From d96153a05ef945a0768888096468662e7cb8656d Mon Sep 17 00:00:00 2001
From: amammad
Date: Fri, 24 Feb 2023 09:28:16 +0100
Subject: [PATCH 03/21] v1.2 change to PascalCase
---
.../experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
index e8b3fb761f4..7612c556d90 100644
--- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
+++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
@@ -20,10 +20,10 @@ import codeql.ruby.TaintTracking
import DataFlow::PathGraph
import codeql.ruby.security.UnsafeDeserializationCustomizations
-abstract class YAMLSink extends DataFlow::Node { }
+abstract class YamlSink extends DataFlow::Node { }
-class YamlunsafeLoadArgument extends YAMLSink {
- YamlunsafeLoadArgument() {
+class YamlUnsafeLoadArgument extends YamlSink {
+ YamlUnsafeLoadArgument() {
this =
API::getTopLevelMember(["YAML", "Psych"])
.getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"])
@@ -53,7 +53,7 @@ class Configuration extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) {
// for detecting The CVE we should uncomment following line
// sink.getLocation().getFile().toString().matches("%yaml_column%") and
- sink instanceof YAMLSink or
+ sink instanceof YamlSink or
sink =
API::getTopLevelMember(["YAML", "Psych"])
.getAMethodCall(["parse", "parse_stream", "parse_file"])
From 0e343e5a12b9dbb83dd0db30d79b6c42894a6ba9 Mon Sep 17 00:00:00 2001
From: amammad
Date: Fri, 24 Feb 2023 11:45:06 +0100
Subject: [PATCH 04/21] v1.3
---
.../CWE-502/YAMLUnsafeYamlDeserialization.ql | 20 +++---
.../CWE-502/YAMLUnsafeYamlDeserialization.rb | 4 +-
.../YAMLUnsafeYamlDeserialization.expected | 72 +++++--------------
.../CWE-502/YAMLUnsafeYamlDeserialization.rb | 4 +-
4 files changed, 34 insertions(+), 66 deletions(-)
diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
index 7612c556d90..a3f42a9c84e 100644
--- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
+++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
@@ -12,10 +12,8 @@
* external/cwe/cwe-502
*/
-import codeql.ruby.AST
import codeql.ruby.ApiGraphs
import codeql.ruby.DataFlow
-import codeql.ruby.dataflow.RemoteFlowSources
import codeql.ruby.TaintTracking
import DataFlow::PathGraph
import codeql.ruby.security.UnsafeDeserializationCustomizations
@@ -38,26 +36,28 @@ class YamlUnsafeLoadArgument extends YamlSink {
API::getTopLevelMember(["YAML", "Psych"])
.getAMethodCall("unsafe_load_file")
.getKeywordArgument("filename")
+ or
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall(["parse", "parse_stream", "parse_file"])
+ .getAMethodCall("to_ruby")
}
}
class Configuration extends TaintTracking::Configuration {
- Configuration() { this = "UnsafeDeserialization" }
+ Configuration() { this = "UnsafeYAMLDeserialization" }
override predicate isSource(DataFlow::Node source) {
- // for detecting The CVE we should uncomment following line instead of current RemoteFlowSource
+ // to detect CVE-2022-32224, we should uncomment following line instead of current UnsafeDeserialization::Source
// source instanceof DataFlow::LocalSourceNode
source instanceof UnsafeDeserialization::Source
}
override predicate isSink(DataFlow::Node sink) {
- // for detecting The CVE we should uncomment following line
+ // after changing the isSource for detecting CVE-2022-32224
+ // uncomment the following line only see the CVE sink not other files similar sinks
// sink.getLocation().getFile().toString().matches("%yaml_column%") and
- sink instanceof YamlSink or
- sink =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall(["parse", "parse_stream", "parse_file"])
- .getAMethodCall("to_ruby")
+ sink instanceof YamlSink
}
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb
index 58ea8024350..6e836a0a049 100644
--- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb
+++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb
@@ -11,10 +11,12 @@ class UsersController < ActionController::Base
Psych.unsafe_load(params[:yaml_string])
Psych.unsafe_load_file(params[:yaml_file])
Psych.load_stream(params[:yaml_string])
- Psych.parse_stream(params[:yaml_string]).to_ruby
+ parse_output = Psych.parse_stream(params[:yaml_string])
+ parse_output.to_ruby
Psych.parse(params[:yaml_string]).to_ruby
Psych.parse_file(params[:yaml_file]).to_ruby
end
end
+
diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected
index e274fb6f005..c01afdfbe69 100644
--- a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected
+++ b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected
@@ -2,24 +2,12 @@ edges
| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] |
| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] |
| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby |
-| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] |
-| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] |
-| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] |
-| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : |
-| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : |
-| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : |
-| file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] |
-| file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : |
-| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] |
-| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] |
-| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : |
-| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby |
nodes
| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : |
| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] |
@@ -27,44 +15,20 @@ nodes
| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] |
| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : |
| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | semmle.label | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | semmle.label | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | semmle.label | ...[...] : |
-| file://:0:0:0:0 | parameter self of [] : | semmle.label | parameter self of [] : |
-| file://:0:0:0:0 | parameter self of [](:yaml_file) : | semmle.label | parameter self of [](:yaml_file) : |
-| file://:0:0:0:0 | parameter self of [](:yaml_string) : | semmle.label | parameter self of [](:yaml_string) : |
+| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : |
subpaths
#select
| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source |
| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_file) | potentially untrusted source |
| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_file) | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb
index 58ea8024350..6e836a0a049 100644
--- a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb
+++ b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb
@@ -11,10 +11,12 @@ class UsersController < ActionController::Base
Psych.unsafe_load(params[:yaml_string])
Psych.unsafe_load_file(params[:yaml_file])
Psych.load_stream(params[:yaml_string])
- Psych.parse_stream(params[:yaml_string]).to_ruby
+ parse_output = Psych.parse_stream(params[:yaml_string])
+ parse_output.to_ruby
Psych.parse(params[:yaml_string]).to_ruby
Psych.parse_file(params[:yaml_file]).to_ruby
end
end
+
From 0521ffe175243a5bd9071c2f9bb231ced31d3ece Mon Sep 17 00:00:00 2001
From: amammad
Date: Fri, 24 Feb 2023 13:13:06 +0100
Subject: [PATCH 05/21] v1.4 correct dirs uppercase issue
---
.../YAMLUnsafeYamlDeserialization.qhelp | 20 +++++
.../cwe-502/YAMLUnsafeYamlDeserialization.ql | 88 +++++++++++++++++++
.../cwe-502/YAMLUnsafeYamlDeserialization.rb | 22 +++++
.../YAMLUnsafeYamlDeserialization.expected | 34 +++++++
.../YAMLUnsafeYamlDeserialization.qlref | 1 +
.../cwe-502/YAMLUnsafeYamlDeserialization.rb | 22 +++++
6 files changed, 187 insertions(+)
create mode 100644 ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp
create mode 100644 ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql
create mode 100644 ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb
create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected
create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref
create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp
new file mode 100644
index 00000000000..821747e0b52
--- /dev/null
+++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp
@@ -0,0 +1,20 @@
+
+
+
+
+ Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application.
+ Unsafe deserializing the malicious serialized yaml document through the Psych (YAML) library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain.
+
+
+
+
+ After Psych(YAML) 4.0.0, the load method is same as safe_load method.
+ This vulnerability can be prevented by using YAML.load (same as YAML.safe_load), YAML.load_file (same as YAML.safe_load_file) instead of YAML.unsafe_* methods.
+ Be careful that YAML.load_stream don't use safe_load method, Also Be careful the to_ruby method of Psych get called on a trusted parsed (YAML.parse*) yaml document.
+
+
+
+ In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.
+
+
+
\ No newline at end of file
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql
new file mode 100644
index 00000000000..a3f42a9c84e
--- /dev/null
+++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql
@@ -0,0 +1,88 @@
+/**
+ * @name Deserialization of user-controlled data by YAML
+ * @description Deserializing user-controlled data may allow attackers to
+ * execute arbitrary code.
+ * @kind path-problem
+ * @problem.severity warning
+ * @security-severity 9.8
+ * @precision high
+ * @id rb/YAML-unsafe-deserialization
+ * @tags security
+ * experimental
+ * external/cwe/cwe-502
+ */
+
+import codeql.ruby.ApiGraphs
+import codeql.ruby.DataFlow
+import codeql.ruby.TaintTracking
+import DataFlow::PathGraph
+import codeql.ruby.security.UnsafeDeserializationCustomizations
+
+abstract class YamlSink extends DataFlow::Node { }
+
+class YamlUnsafeLoadArgument extends YamlSink {
+ YamlUnsafeLoadArgument() {
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"])
+ .getArgument(0)
+ or
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall(["unsafe_load", "load_stream"])
+ .getKeywordArgument("yaml")
+ or
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall("unsafe_load_file")
+ .getKeywordArgument("filename")
+ or
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall(["parse", "parse_stream", "parse_file"])
+ .getAMethodCall("to_ruby")
+ }
+}
+
+class Configuration extends TaintTracking::Configuration {
+ Configuration() { this = "UnsafeYAMLDeserialization" }
+
+ override predicate isSource(DataFlow::Node source) {
+ // to detect CVE-2022-32224, we should uncomment following line instead of current UnsafeDeserialization::Source
+ // source instanceof DataFlow::LocalSourceNode
+ source instanceof UnsafeDeserialization::Source
+ }
+
+ override predicate isSink(DataFlow::Node sink) {
+ // after changing the isSource for detecting CVE-2022-32224
+ // uncomment the following line only see the CVE sink not other files similar sinks
+ // sink.getLocation().getFile().toString().matches("%yaml_column%") and
+ sink instanceof YamlSink
+ }
+
+ override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
+ exists(DataFlow::CallNode yaml_parser_methods |
+ yaml_parser_methods =
+ API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and
+ (
+ nodeFrom = yaml_parser_methods.getArgument(0) or
+ nodeFrom = yaml_parser_methods.getKeywordArgument("yaml")
+ ) and
+ nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
+ )
+ or
+ exists(DataFlow::CallNode yaml_parser_methods |
+ yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and
+ (
+ nodeFrom = yaml_parser_methods.getArgument(0) or
+ nodeFrom = yaml_parser_methods.getKeywordArgument("filename")
+ ) and
+ nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
+ )
+ }
+}
+
+from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
+where config.hasFlowPath(source, sink)
+select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(),
+ "potentially untrusted source"
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb
new file mode 100644
index 00000000000..6e836a0a049
--- /dev/null
+++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb
@@ -0,0 +1,22 @@
+require 'yaml'
+class UsersController < ActionController::Base
+ def example
+ # safe
+ Psych.load(params[:yaml_string])
+ Psych.load_file(params[:yaml_file])
+ Psych.parse_stream(params[:yaml_string])
+ Psych.parse(params[:yaml_string])
+ Psych.parse_file(params[:yaml_file])
+ # unsafe
+ Psych.unsafe_load(params[:yaml_string])
+ Psych.unsafe_load_file(params[:yaml_file])
+ Psych.load_stream(params[:yaml_string])
+ parse_output = Psych.parse_stream(params[:yaml_string])
+ parse_output.to_ruby
+ Psych.parse(params[:yaml_string]).to_ruby
+ Psych.parse_file(params[:yaml_file]).to_ruby
+
+ end
+end
+
+
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected
new file mode 100644
index 00000000000..c01afdfbe69
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected
@@ -0,0 +1,34 @@
+edges
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby |
+nodes
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : |
+| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : |
+subpaths
+#select
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref
new file mode 100644
index 00000000000..7e9e87117f9
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref
@@ -0,0 +1 @@
+experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb
new file mode 100644
index 00000000000..6e836a0a049
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb
@@ -0,0 +1,22 @@
+require 'yaml'
+class UsersController < ActionController::Base
+ def example
+ # safe
+ Psych.load(params[:yaml_string])
+ Psych.load_file(params[:yaml_file])
+ Psych.parse_stream(params[:yaml_string])
+ Psych.parse(params[:yaml_string])
+ Psych.parse_file(params[:yaml_file])
+ # unsafe
+ Psych.unsafe_load(params[:yaml_string])
+ Psych.unsafe_load_file(params[:yaml_file])
+ Psych.load_stream(params[:yaml_string])
+ parse_output = Psych.parse_stream(params[:yaml_string])
+ parse_output.to_ruby
+ Psych.parse(params[:yaml_string]).to_ruby
+ Psych.parse_file(params[:yaml_file]).to_ruby
+
+ end
+end
+
+
From 4360a56b45483b658e583f5a8684ce96b80d5b73 Mon Sep 17 00:00:00 2001
From: amammad
Date: Sat, 25 Feb 2023 20:49:48 +0100
Subject: [PATCH 06/21] v2 add plist.parse_xml as a dangerous sink and
enhancements on documents
---
.../YAMLUnsafeYamlDeserialization.qhelp | 20 -----
.../CWE-502/YAMLUnsafeYamlDeserialization.ql | 88 -------------------
.../CWE-502/YAMLUnsafeYamlDeserialization.rb | 22 -----
.../PlistUnsafeYamlDeserialization.qhelp | 25 ++++++
.../cwe-502/PlistUnsafeYamlDeserialization.ql | 68 ++++++++++++++
.../cwe-502/PlistUnsafeYamlDeserialization.rb | 13 +++
.../YAMLUnsafeYamlDeserialization.qhelp | 6 ++
.../cwe-502/YAMLUnsafeYamlDeserialization.ql | 14 +--
.../YAMLUnsafeYamlDeserialization.expected | 34 -------
.../YAMLUnsafeYamlDeserialization.qlref | 1 -
.../CWE-502/YAMLUnsafeYamlDeserialization.rb | 22 -----
.../PlistUnsafeYamlDeserialization.expected | 12 +++
.../PlistUnsafeYamlDeserialization.qlref | 1 +
.../cwe-502/PlistUnsafeYamlDeserialization.rb | 13 +++
.../YAMLUnsafeYamlDeserialization.expected | 12 +--
.../YAMLUnsafeYamlDeserialization.qlref | 2 +-
16 files changed, 152 insertions(+), 201 deletions(-)
delete mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp
delete mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
delete mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb
create mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp
create mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql
create mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb
create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected
create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref
create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb
diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp
deleted file mode 100644
index 821747e0b52..00000000000
--- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
- Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application.
- Unsafe deserializing the malicious serialized yaml document through the Psych (YAML) library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain.
-
-
-
-
- After Psych(YAML) 4.0.0, the load method is same as safe_load method.
- This vulnerability can be prevented by using YAML.load (same as YAML.safe_load), YAML.load_file (same as YAML.safe_load_file) instead of YAML.unsafe_* methods.
- Be careful that YAML.load_stream don't use safe_load method, Also Be careful the to_ruby method of Psych get called on a trusted parsed (YAML.parse*) yaml document.
-
-
-
- In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.
-
-
-
\ No newline at end of file
diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
deleted file mode 100644
index a3f42a9c84e..00000000000
--- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * @name Deserialization of user-controlled data by YAML
- * @description Deserializing user-controlled data may allow attackers to
- * execute arbitrary code.
- * @kind path-problem
- * @problem.severity warning
- * @security-severity 9.8
- * @precision high
- * @id rb/YAML-unsafe-deserialization
- * @tags security
- * experimental
- * external/cwe/cwe-502
- */
-
-import codeql.ruby.ApiGraphs
-import codeql.ruby.DataFlow
-import codeql.ruby.TaintTracking
-import DataFlow::PathGraph
-import codeql.ruby.security.UnsafeDeserializationCustomizations
-
-abstract class YamlSink extends DataFlow::Node { }
-
-class YamlUnsafeLoadArgument extends YamlSink {
- YamlUnsafeLoadArgument() {
- this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"])
- .getArgument(0)
- or
- this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall(["unsafe_load", "load_stream"])
- .getKeywordArgument("yaml")
- or
- this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall("unsafe_load_file")
- .getKeywordArgument("filename")
- or
- this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall(["parse", "parse_stream", "parse_file"])
- .getAMethodCall("to_ruby")
- }
-}
-
-class Configuration extends TaintTracking::Configuration {
- Configuration() { this = "UnsafeYAMLDeserialization" }
-
- override predicate isSource(DataFlow::Node source) {
- // to detect CVE-2022-32224, we should uncomment following line instead of current UnsafeDeserialization::Source
- // source instanceof DataFlow::LocalSourceNode
- source instanceof UnsafeDeserialization::Source
- }
-
- override predicate isSink(DataFlow::Node sink) {
- // after changing the isSource for detecting CVE-2022-32224
- // uncomment the following line only see the CVE sink not other files similar sinks
- // sink.getLocation().getFile().toString().matches("%yaml_column%") and
- sink instanceof YamlSink
- }
-
- override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
- exists(DataFlow::CallNode yaml_parser_methods |
- yaml_parser_methods =
- API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and
- (
- nodeFrom = yaml_parser_methods.getArgument(0) or
- nodeFrom = yaml_parser_methods.getKeywordArgument("yaml")
- ) and
- nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
- )
- or
- exists(DataFlow::CallNode yaml_parser_methods |
- yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and
- (
- nodeFrom = yaml_parser_methods.getArgument(0) or
- nodeFrom = yaml_parser_methods.getKeywordArgument("filename")
- ) and
- nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
- )
- }
-}
-
-from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
-where config.hasFlowPath(source, sink)
-select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(),
- "potentially untrusted source"
diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb
deleted file mode 100644
index 6e836a0a049..00000000000
--- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'yaml'
-class UsersController < ActionController::Base
- def example
- # safe
- Psych.load(params[:yaml_string])
- Psych.load_file(params[:yaml_file])
- Psych.parse_stream(params[:yaml_string])
- Psych.parse(params[:yaml_string])
- Psych.parse_file(params[:yaml_file])
- # unsafe
- Psych.unsafe_load(params[:yaml_string])
- Psych.unsafe_load_file(params[:yaml_file])
- Psych.load_stream(params[:yaml_string])
- parse_output = Psych.parse_stream(params[:yaml_string])
- parse_output.to_ruby
- Psych.parse(params[:yaml_string]).to_ruby
- Psych.parse_file(params[:yaml_file]).to_ruby
-
- end
-end
-
-
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp
new file mode 100644
index 00000000000..80ec6c51dc0
--- /dev/null
+++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp
@@ -0,0 +1,25 @@
+
+
+
+
+ Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application.
+ Unsafe deserializing the malicious serialized xml document through the Plist library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain.
+
+
+
+
+ This vulnerability can be prevented by using Plist.parse_xml.
+
+
+
+ In the example below, you can see safe and unsafe call of this dangerous method that can be abused by a remote user input. You can use "marshal: false" as an arugument for Plist.parse_xml to use it safe.
+
+
+
+
+
+ Security considerations from library documentation
+ patsplat/plist.
+
+
+
\ No newline at end of file
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql
new file mode 100644
index 00000000000..02d554cffb6
--- /dev/null
+++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql
@@ -0,0 +1,68 @@
+/**
+ * @name Unsafe Deserialization of user-controlled data by Plist
+ * @description Deserializing user-controlled data may allow attackers to
+ * execute arbitrary code.
+ * @kind path-problem
+ * @problem.severity warning
+ * @security-severity 9.8
+ * @precision high
+ * @id rb/Plist-unsafe-deserialization
+ * @tags security
+ * experimental
+ * external/cwe/cwe-502
+ */
+
+import codeql.ruby.ApiGraphs
+import codeql.ruby.DataFlow
+import codeql.ruby.TaintTracking
+import codeql.ruby.CFG
+import DataFlow::PathGraph
+import codeql.ruby.security.UnsafeDeserializationCustomizations
+
+abstract class PlistUnsafeSinks extends DataFlow::Node { }
+
+/**
+ * check whether an input argument has desired "key: value" input or not.
+ * borrowed from UnsafeDeserialization module with some changes
+ */
+predicate checkkeyBalue(CfgNodes::ExprNodes::PairCfgNode p, string key, string value) {
+ p.getKey().getConstantValue().isStringlikeValue(key) and
+ DataFlow::exprNode(p.getValue()).getALocalSource().getConstantValue().toString() = value
+}
+
+/**
+ * An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is
+ * the default), considered a sink for unsafe deserialization.
+ * borrowed from UnsafeDeserialization module with some changes
+ */
+class UnsafePlistParsexmlArgument extends PlistUnsafeSinks {
+ UnsafePlistParsexmlArgument() {
+ exists(DataFlow::CallNode plistParsexml |
+ plistParsexml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml")
+ |
+ this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and
+ // Exclude calls that explicitly pass a safe mode option.
+ checkkeyBalue(plistParsexml.getArgument(1).asExpr(), "marshal", "true")
+ or
+ this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and
+ plistParsexml.getNumberOfArguments() = 1
+ )
+ }
+}
+
+class Configuration extends TaintTracking::Configuration {
+ Configuration() { this = "PlistUnsafeDeserialization" }
+
+ override predicate isSource(DataFlow::Node source) {
+ // to detect CVE-2021-33575, we should uncomment following line instead of current UnsafeDeserialization::Source
+ // source instanceof DataFlow::LocalSourceNode
+ source instanceof UnsafeDeserialization::Source
+ }
+
+ override predicate isSink(DataFlow::Node sink) { sink instanceof PlistUnsafeSinks }
+}
+
+from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
+where config.hasFlowPath(source, sink)
+select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(),
+ "potentially untrusted source"
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb
new file mode 100644
index 00000000000..63f64b5cd22
--- /dev/null
+++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb
@@ -0,0 +1,13 @@
+require 'yaml'
+class UsersController < ActionController::Base
+ def example
+ # not safe
+ result = Plist.parse_xml(params[:yaml_string])
+ result = Plist.parse_xml(params[:yaml_string], marshal: true)
+
+ # safe
+ result = Plist.parse_xml(params[:yaml_string], marshal: false)
+ end
+end
+
+
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp
index 821747e0b52..c3a74527483 100644
--- a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp
+++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp
@@ -17,4 +17,10 @@
In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.
+
+
+ You can read that how unsafe yaml load methods can lead to code executions.
+ Universal Deserialisation Gadget for Ruby 2.x-3.x .
+
+
\ No newline at end of file
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql
index a3f42a9c84e..5cb720d19da 100644
--- a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql
+++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql
@@ -1,5 +1,5 @@
/**
- * @name Deserialization of user-controlled data by YAML
+ * @name Unsafe Deserialization of user-controlled data by YAML
* @description Deserializing user-controlled data may allow attackers to
* execute arbitrary code.
* @kind path-problem
@@ -18,10 +18,10 @@ import codeql.ruby.TaintTracking
import DataFlow::PathGraph
import codeql.ruby.security.UnsafeDeserializationCustomizations
-abstract class YamlSink extends DataFlow::Node { }
+abstract class YamlUnsafeSinks extends DataFlow::Node { }
-class YamlUnsafeLoadArgument extends YamlSink {
- YamlUnsafeLoadArgument() {
+class YamlUnsafeArgument extends YamlUnsafeSinks {
+ YamlUnsafeArgument() {
this =
API::getTopLevelMember(["YAML", "Psych"])
.getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"])
@@ -45,7 +45,7 @@ class YamlUnsafeLoadArgument extends YamlSink {
}
class Configuration extends TaintTracking::Configuration {
- Configuration() { this = "UnsafeYAMLDeserialization" }
+ Configuration() { this = "YamlUnsafeDeserialization" }
override predicate isSource(DataFlow::Node source) {
// to detect CVE-2022-32224, we should uncomment following line instead of current UnsafeDeserialization::Source
@@ -57,7 +57,7 @@ class Configuration extends TaintTracking::Configuration {
// after changing the isSource for detecting CVE-2022-32224
// uncomment the following line only see the CVE sink not other files similar sinks
// sink.getLocation().getFile().toString().matches("%yaml_column%") and
- sink instanceof YamlSink
+ sink instanceof YamlUnsafeSinks
}
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
@@ -84,5 +84,5 @@ class Configuration extends TaintTracking::Configuration {
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
-select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(),
+select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(),
"potentially untrusted source"
diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected
deleted file mode 100644
index c01afdfbe69..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected
+++ /dev/null
@@ -1,34 +0,0 @@
-edges
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby |
-nodes
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : |
-subpaths
-#select
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref
deleted file mode 100644
index 7e9e87117f9..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref
+++ /dev/null
@@ -1 +0,0 @@
-experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb
deleted file mode 100644
index 6e836a0a049..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'yaml'
-class UsersController < ActionController::Base
- def example
- # safe
- Psych.load(params[:yaml_string])
- Psych.load_file(params[:yaml_file])
- Psych.parse_stream(params[:yaml_string])
- Psych.parse(params[:yaml_string])
- Psych.parse_file(params[:yaml_file])
- # unsafe
- Psych.unsafe_load(params[:yaml_string])
- Psych.unsafe_load_file(params[:yaml_file])
- Psych.load_stream(params[:yaml_string])
- parse_output = Psych.parse_stream(params[:yaml_string])
- parse_output.to_ruby
- Psych.parse(params[:yaml_string]).to_ruby
- Psych.parse_file(params[:yaml_file]).to_ruby
-
- end
-end
-
-
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected
new file mode 100644
index 00000000000..f5da2a260c4
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected
@@ -0,0 +1,12 @@
+edges
+| PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] |
+| PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] |
+nodes
+| PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | semmle.label | call to params : |
+| PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | semmle.label | ...[...] |
+| PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | semmle.label | call to params : |
+| PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | semmle.label | ...[...] |
+subpaths
+#select
+| PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params | potentially untrusted source |
+| PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref
new file mode 100644
index 00000000000..74d9d37315a
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref
@@ -0,0 +1 @@
+experimental/cwe-502/PlistUnsafeYamlDeserialization.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb
new file mode 100644
index 00000000000..63f64b5cd22
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb
@@ -0,0 +1,13 @@
+require 'yaml'
+class UsersController < ActionController::Base
+ def example
+ # not safe
+ result = Plist.parse_xml(params[:yaml_string])
+ result = Plist.parse_xml(params[:yaml_string], marshal: true)
+
+ # safe
+ result = Plist.parse_xml(params[:yaml_string], marshal: false)
+ end
+end
+
+
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected
index c01afdfbe69..489602044a7 100644
--- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected
@@ -26,9 +26,9 @@ nodes
| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : |
subpaths
#select
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source |
+| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref
index 7e9e87117f9..87fe2520217 100644
--- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref
@@ -1 +1 @@
-experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql
\ No newline at end of file
+experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql
\ No newline at end of file
From b9296d3df88084252074f69bae97e986095b3b83 Mon Sep 17 00:00:00 2001
From: amammad
Date: Sat, 25 Feb 2023 23:08:31 +0100
Subject: [PATCH 07/21] v2.1 fix file names
---
...qhelp => PlistUnsafeDeserialization.qhelp} | 0
...ation.ql => PlistUnsafeDeserialization.ql} | 0
...ation.rb => PlistUnsafeDeserialization.rb} | 0
....qhelp => YAMLUnsafeDeserialization.qhelp} | 0
...zation.ql => YAMLUnsafeDeserialization.ql} | 0
...zation.rb => YAMLUnsafeDeserialization.rb} | 0
.../PlistUnsafeDeserialization.expected | 12 +++++++
.../cwe-502/PlistUnsafeDeserialization.qlref | 1 +
...ation.rb => PlistUnsafeDeserialization.rb} | 0
.../PlistUnsafeYamlDeserialization.expected | 12 -------
.../PlistUnsafeYamlDeserialization.qlref | 1 -
.../YAMLUnsafeDeserialization.expected | 34 +++++++++++++++++++
.../cwe-502/YAMLUnsafeDeserialization.qlref | 1 +
...zation.rb => YAMLUnsafeDeserialization.rb} | 0
.../YAMLUnsafeYamlDeserialization.expected | 34 -------------------
.../YAMLUnsafeYamlDeserialization.qlref | 1 -
16 files changed, 48 insertions(+), 48 deletions(-)
rename ruby/ql/src/experimental/cwe-502/{PlistUnsafeYamlDeserialization.qhelp => PlistUnsafeDeserialization.qhelp} (100%)
rename ruby/ql/src/experimental/cwe-502/{PlistUnsafeYamlDeserialization.ql => PlistUnsafeDeserialization.ql} (100%)
rename ruby/ql/src/experimental/cwe-502/{PlistUnsafeYamlDeserialization.rb => PlistUnsafeDeserialization.rb} (100%)
rename ruby/ql/src/experimental/cwe-502/{YAMLUnsafeYamlDeserialization.qhelp => YAMLUnsafeDeserialization.qhelp} (100%)
rename ruby/ql/src/experimental/cwe-502/{YAMLUnsafeYamlDeserialization.ql => YAMLUnsafeDeserialization.ql} (100%)
rename ruby/ql/src/experimental/cwe-502/{YAMLUnsafeYamlDeserialization.rb => YAMLUnsafeDeserialization.rb} (100%)
create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected
create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref
rename ruby/ql/test/query-tests/experimental/Security/cwe-502/{PlistUnsafeYamlDeserialization.rb => PlistUnsafeDeserialization.rb} (100%)
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref
create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected
create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref
rename ruby/ql/test/query-tests/experimental/Security/cwe-502/{YAMLUnsafeYamlDeserialization.rb => YAMLUnsafeDeserialization.rb} (100%)
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp
similarity index 100%
rename from ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp
rename to ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql
similarity index 100%
rename from ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql
rename to ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb
similarity index 100%
rename from ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb
rename to ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp
similarity index 100%
rename from ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp
rename to ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql
similarity index 100%
rename from ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql
rename to ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.rb
similarity index 100%
rename from ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb
rename to ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.rb
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected
new file mode 100644
index 00000000000..967ef978a3b
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected
@@ -0,0 +1,12 @@
+edges
+| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] |
+| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] |
+nodes
+| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | semmle.label | call to params : |
+| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | semmle.label | ...[...] |
+| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | semmle.label | call to params : |
+| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | semmle.label | ...[...] |
+subpaths
+#select
+| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | potentially untrusted source |
+| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref
new file mode 100644
index 00000000000..f7bfbada7b5
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref
@@ -0,0 +1 @@
+experimental/cwe-502/PlistUnsafeDeserialization.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.rb
similarity index 100%
rename from ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb
rename to ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.rb
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected
deleted file mode 100644
index f5da2a260c4..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected
+++ /dev/null
@@ -1,12 +0,0 @@
-edges
-| PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] |
-| PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] |
-nodes
-| PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | semmle.label | call to params : |
-| PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | semmle.label | ...[...] |
-| PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | semmle.label | call to params : |
-| PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | semmle.label | ...[...] |
-subpaths
-#select
-| PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params | potentially untrusted source |
-| PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref
deleted file mode 100644
index 74d9d37315a..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref
+++ /dev/null
@@ -1 +0,0 @@
-experimental/cwe-502/PlistUnsafeYamlDeserialization.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected
new file mode 100644
index 00000000000..9a9bd05e514
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected
@@ -0,0 +1,34 @@
+edges
+| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] |
+| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] |
+| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] |
+| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : |
+| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby |
+| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : |
+| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby |
+| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : |
+| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby |
+nodes
+| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : |
+| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : |
+| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : |
+| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : |
+subpaths
+#select
+| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source |
+| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source |
+| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source |
+| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source |
+| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source |
+| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref
new file mode 100644
index 00000000000..e06e0921159
--- /dev/null
+++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref
@@ -0,0 +1 @@
+experimental/cwe-502/YAMLUnsafeDeserialization.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb
similarity index 100%
rename from ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb
rename to ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected
deleted file mode 100644
index 489602044a7..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected
+++ /dev/null
@@ -1,34 +0,0 @@
-edges
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby |
-nodes
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] |
-| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : |
-| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : |
-subpaths
-#select
-| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source |
-| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref
deleted file mode 100644
index 87fe2520217..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref
+++ /dev/null
@@ -1 +0,0 @@
-experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql
\ No newline at end of file
From ad7e107ff57da219b2abc185fc8e80020b302082 Mon Sep 17 00:00:00 2001
From: amammad
Date: Wed, 1 Mar 2023 08:55:17 +0100
Subject: [PATCH 08/21] add the new YAML/PLIST sinks into the existing
rb/unsafe-deserialization query
---
.../UnsafeDeserializationCustomizations.qll | 59 ++++++++++++++++++-
.../security/UnsafeDeserializationQuery.qll | 22 +++++++
2 files changed, 79 insertions(+), 2 deletions(-)
diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
index 45e0888eacd..96f7e87d7a2 100644
--- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
+++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
@@ -75,13 +75,41 @@ module UnsafeDeserialization {
}
/**
- * An argument in a call to `YAML.load`, considered a sink
+ * An argument in a call to `YAML.unsafe_*` and `YAML.load_stream` , considered sinks
* for unsafe deserialization. The `YAML` module is an alias of `Psych` in
* recent versions of Ruby.
*/
class YamlLoadArgument extends Sink {
YamlLoadArgument() {
- this = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("load").getArgument(0)
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"])
+ .getArgument(0)
+ or
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall(["unsafe_load", "load_stream"])
+ .getKeywordArgument("yaml")
+ or
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall("unsafe_load_file")
+ .getKeywordArgument("filename")
+ }
+ }
+
+ /**
+ * An argument in a call to `YAML.parse*`, considered sinks
+ * for unsafe deserialization if there is a call to `to_ruby` on returned value of them,
+ * so this need some additional taint steps. The `YAML` module is an alias of `Psych` in
+ * recent versions of Ruby.
+ */
+ class YamlParseArgument extends Sink {
+ YamlParseArgument() {
+ this =
+ API::getTopLevelMember(["YAML", "Psych"])
+ .getAMethodCall(["parse", "parse_stream", "parse_file"])
+ .getAMethodCall("to_ruby")
}
}
@@ -208,4 +236,31 @@ module UnsafeDeserialization {
)
}
}
+
+ /**
+ * check whether an input argument has desired "key: value" input or not.
+ */
+ predicate checkkeyValue(CfgNodes::ExprNodes::PairCfgNode p, string key, string value) {
+ p.getKey().getConstantValue().isStringlikeValue(key) and
+ DataFlow::exprNode(p.getValue()).getALocalSource().getConstantValue().toString() = value
+ }
+
+ /**
+ * An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is
+ * the default), considered a sink for unsafe deserialization.
+ */
+ class UnsafePlistParsexmlArgument extends Sink {
+ UnsafePlistParsexmlArgument() {
+ exists(DataFlow::CallNode plistParsexml |
+ plistParsexml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml")
+ |
+ this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and
+ // Exclude calls that explicitly pass a safe mode option.
+ checkkeyValue(plistParsexml.getArgument(1).asExpr(), "marshal", "true")
+ or
+ this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and
+ plistParsexml.getNumberOfArguments() = 1
+ )
+ }
+ }
}
diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll
index dc6293dc10e..fed9160ccd9 100644
--- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll
+++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll
@@ -9,6 +9,7 @@
private import codeql.ruby.AST
private import codeql.ruby.DataFlow
private import codeql.ruby.TaintTracking
+private import codeql.ruby.ApiGraphs
import UnsafeDeserializationCustomizations
/**
@@ -23,6 +24,27 @@ class Configuration extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserialization::Sink }
+ override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
+ exists(DataFlow::CallNode yaml_parser_methods |
+ yaml_parser_methods =
+ API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and
+ (
+ nodeFrom = yaml_parser_methods.getArgument(0) or
+ nodeFrom = yaml_parser_methods.getKeywordArgument("yaml")
+ ) and
+ nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
+ )
+ or
+ exists(DataFlow::CallNode yaml_parser_methods |
+ yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and
+ (
+ nodeFrom = yaml_parser_methods.getArgument(0) or
+ nodeFrom = yaml_parser_methods.getKeywordArgument("filename")
+ ) and
+ nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
+ )
+ }
+
override predicate isSanitizer(DataFlow::Node node) {
super.isSanitizer(node) or
node instanceof UnsafeDeserialization::Sanitizer
From e76ed9454ab924a1b9a1f2a99711180938ade110 Mon Sep 17 00:00:00 2001
From: amammad
Date: Wed, 1 Mar 2023 10:45:45 +0100
Subject: [PATCH 09/21] v3 add global taint steps for to_ruby of YAML/Psych
---
ruby/ql/lib/codeql/ruby/Frameworks.qll | 1 +
ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll | 30 +++++++++++++++++++
.../security/UnsafeDeserializationQuery.qll | 21 -------------
3 files changed, 31 insertions(+), 21 deletions(-)
create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll
diff --git a/ruby/ql/lib/codeql/ruby/Frameworks.qll b/ruby/ql/lib/codeql/ruby/Frameworks.qll
index 29eacf22e33..e6f2d9681f3 100644
--- a/ruby/ql/lib/codeql/ruby/Frameworks.qll
+++ b/ruby/ql/lib/codeql/ruby/Frameworks.qll
@@ -33,3 +33,4 @@ private import codeql.ruby.frameworks.Sinatra
private import codeql.ruby.frameworks.Twirp
private import codeql.ruby.frameworks.Sqlite3
private import codeql.ruby.frameworks.Pg
+private import codeql.ruby.frameworks.Yaml
diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll
new file mode 100644
index 00000000000..d1fe6547e56
--- /dev/null
+++ b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll
@@ -0,0 +1,30 @@
+/**
+ * add additional steps for to_ruby method of YAML/Psych library
+ */
+
+private import codeql.ruby.dataflow.FlowSteps
+private import codeql.ruby.DataFlow
+private import codeql.ruby.ApiGraphs
+
+private class YamlParseStep extends AdditionalTaintStep {
+ override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
+ exists(DataFlow::CallNode yaml_parser_methods |
+ yaml_parser_methods =
+ API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and
+ (
+ pred = yaml_parser_methods.getArgument(0) or
+ pred = yaml_parser_methods.getKeywordArgument("yaml")
+ ) and
+ succ = yaml_parser_methods.getAMethodCall("to_ruby")
+ )
+ or
+ exists(DataFlow::CallNode yaml_parser_methods |
+ yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and
+ (
+ pred = yaml_parser_methods.getArgument(0) or
+ pred = yaml_parser_methods.getKeywordArgument("filename")
+ ) and
+ succ = yaml_parser_methods.getAMethodCall("to_ruby")
+ )
+ }
+}
diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll
index fed9160ccd9..c4c5a39e451 100644
--- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll
+++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll
@@ -24,27 +24,6 @@ class Configuration extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserialization::Sink }
- override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
- exists(DataFlow::CallNode yaml_parser_methods |
- yaml_parser_methods =
- API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and
- (
- nodeFrom = yaml_parser_methods.getArgument(0) or
- nodeFrom = yaml_parser_methods.getKeywordArgument("yaml")
- ) and
- nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
- )
- or
- exists(DataFlow::CallNode yaml_parser_methods |
- yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and
- (
- nodeFrom = yaml_parser_methods.getArgument(0) or
- nodeFrom = yaml_parser_methods.getKeywordArgument("filename")
- ) and
- nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
- )
- }
-
override predicate isSanitizer(DataFlow::Node node) {
super.isSanitizer(node) or
node instanceof UnsafeDeserialization::Sanitizer
From 335441ce041893314eb377e154f4d11876f3eb6f Mon Sep 17 00:00:00 2001
From: amammad
Date: Mon, 24 Apr 2023 10:43:09 +0200
Subject: [PATCH 10/21] v4: make variable names camelCase, some inhancement,
remove some duplicates
---
ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll | 41 ++++++++++------
.../UnsafeDeserializationCustomizations.qll | 48 ++++++++-----------
.../security/UnsafeDeserializationQuery.qll | 1 -
.../cwe-502/PlistUnsafeDeserialization.qhelp | 7 ++-
.../cwe-502/PlistUnsafeDeserialization.ql | 25 +++-------
.../cwe-502/PlistUnsafeDeserialization.rb | 6 ++-
.../cwe-502/UnsafeDeserialization.qhelp | 23 +++++++++
.../examples/PlistUnsafeDeserialization.rb | 17 +++++++
.../examples/YAMLUnsafeDeserialization.rb | 22 +++++++++
9 files changed, 123 insertions(+), 67 deletions(-)
create mode 100644 ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb
create mode 100644 ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb
diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll
index d1fe6547e56..81afdcbed7b 100644
--- a/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll
+++ b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll
@@ -1,30 +1,43 @@
/**
- * add additional steps for to_ruby method of YAML/Psych library
+ * Provides modeling for the `YAML` and `Psych` libraries.
*/
private import codeql.ruby.dataflow.FlowSteps
private import codeql.ruby.DataFlow
private import codeql.ruby.ApiGraphs
+/**
+ * A taint step related to the result of `YAML.parse` calls, or similar.
+ *In the following example, this step will propagate taint from
+ *`source` to `sink`:
+ *
+ *```rb
+ *x = source
+ *result = YAML.parse(x)
+ *sink result.to_ruby # Unsafe call
+ * ```
+ */
private class YamlParseStep extends AdditionalTaintStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
- exists(DataFlow::CallNode yaml_parser_methods |
- yaml_parser_methods =
- API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and
+ exists(DataFlow::CallNode yamlParserMethod |
+ yamlParserMethod = yamlNode().getAMethodCall(["parse", "parse_stream"]) and
(
- pred = yaml_parser_methods.getArgument(0) or
- pred = yaml_parser_methods.getKeywordArgument("yaml")
+ pred = yamlParserMethod.getArgument(0) or
+ pred = yamlParserMethod.getKeywordArgument("yaml")
) and
- succ = yaml_parser_methods.getAMethodCall("to_ruby")
- )
- or
- exists(DataFlow::CallNode yaml_parser_methods |
- yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and
+ succ = yamlParserMethod.getAMethodCall("to_ruby")
+ or
+ yamlParserMethod = yamlNode().getAMethodCall("parse_file") and
(
- pred = yaml_parser_methods.getArgument(0) or
- pred = yaml_parser_methods.getKeywordArgument("filename")
+ pred = yamlParserMethod.getArgument(0) or
+ pred = yamlParserMethod.getKeywordArgument("filename")
) and
- succ = yaml_parser_methods.getAMethodCall("to_ruby")
+ succ = yamlParserMethod.getAMethodCall("to_ruby")
)
}
}
+
+/**
+ * YAML/Psych Top level Class member
+ */
+private API::Node yamlNode() { result = API::getTopLevelMember(["YAML", "Psych"]) }
diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
index 96f7e87d7a2..fcaceed1b3a 100644
--- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
+++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
@@ -78,26 +78,27 @@ module UnsafeDeserialization {
* An argument in a call to `YAML.unsafe_*` and `YAML.load_stream` , considered sinks
* for unsafe deserialization. The `YAML` module is an alias of `Psych` in
* recent versions of Ruby.
+ * the `this = yamlNode().getAMethodCall("load").getArgument(0)` is safe
+ * in recent versions of YAML library, so it will be removed in future.
*/
class YamlLoadArgument extends Sink {
YamlLoadArgument() {
- this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"])
- .getArgument(0)
+ this = yamlNode().getAMethodCall("load").getArgument(0)
or
this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall(["unsafe_load", "load_stream"])
- .getKeywordArgument("yaml")
+ yamlNode().getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"]).getArgument(0)
or
- this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall("unsafe_load_file")
- .getKeywordArgument("filename")
+ this = yamlNode().getAMethodCall(["unsafe_load", "load_stream"]).getKeywordArgument("yaml")
+ or
+ this = yamlNode().getAMethodCall("unsafe_load_file").getKeywordArgument("filename")
}
}
+ /**
+ * YAML/Psych Top level Class member
+ */
+ private API::Node yamlNode() { result = API::getTopLevelMember(["YAML", "Psych"]) }
+
/**
* An argument in a call to `YAML.parse*`, considered sinks
* for unsafe deserialization if there is a call to `to_ruby` on returned value of them,
@@ -107,9 +108,7 @@ module UnsafeDeserialization {
class YamlParseArgument extends Sink {
YamlParseArgument() {
this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall(["parse", "parse_stream", "parse_file"])
- .getAMethodCall("to_ruby")
+ yamlNode().getAMethodCall(["parse", "parse_stream", "parse_file"]).getAMethodCall("to_ruby")
}
}
@@ -237,29 +236,20 @@ module UnsafeDeserialization {
}
}
- /**
- * check whether an input argument has desired "key: value" input or not.
- */
- predicate checkkeyValue(CfgNodes::ExprNodes::PairCfgNode p, string key, string value) {
- p.getKey().getConstantValue().isStringlikeValue(key) and
- DataFlow::exprNode(p.getValue()).getALocalSource().getConstantValue().toString() = value
- }
-
/**
* An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is
* the default), considered a sink for unsafe deserialization.
*/
class UnsafePlistParsexmlArgument extends Sink {
UnsafePlistParsexmlArgument() {
- exists(DataFlow::CallNode plistParsexml |
- plistParsexml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml")
+ exists(DataFlow::CallNode plistParseXml |
+ plistParseXml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml")
|
- this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and
- // Exclude calls that explicitly pass a safe mode option.
- checkkeyValue(plistParsexml.getArgument(1).asExpr(), "marshal", "true")
+ this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and
+ plistParseXml.getKeywordArgument("marshal").getConstantValue().isBoolean(true)
or
- this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and
- plistParsexml.getNumberOfArguments() = 1
+ this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and
+ plistParseXml.getNumberOfArguments() = 1
)
}
}
diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll
index c4c5a39e451..dc6293dc10e 100644
--- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll
+++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll
@@ -9,7 +9,6 @@
private import codeql.ruby.AST
private import codeql.ruby.DataFlow
private import codeql.ruby.TaintTracking
-private import codeql.ruby.ApiGraphs
import UnsafeDeserializationCustomizations
/**
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp
index 80ec6c51dc0..45c4220c1b4 100644
--- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp
+++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp
@@ -8,18 +8,17 @@
- This vulnerability can be prevented by using Plist.parse_xml.
+ This vulnerability in Plist can be prevented by calling Plist.parse_xml FileOrXmlString, marshal: false.
- In the example below, you can see safe and unsafe call of this dangerous method that can be abused by a remote user input. You can use "marshal: false" as an arugument for Plist.parse_xml to use it safe.
+
In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for Plist.parse_xml to use it safe.
- Security considerations from library documentation
- patsplat/plist.
+ Security considerations from library documentation: patsplat/plist Repository.
\ No newline at end of file
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql
index 02d554cffb6..4ba55824598 100644
--- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql
+++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql
@@ -6,7 +6,7 @@
* @problem.severity warning
* @security-severity 9.8
* @precision high
- * @id rb/Plist-unsafe-deserialization
+ * @id rb/plist-unsafe-deserialization
* @tags security
* experimental
* external/cwe/cwe-502
@@ -21,31 +21,20 @@ import codeql.ruby.security.UnsafeDeserializationCustomizations
abstract class PlistUnsafeSinks extends DataFlow::Node { }
-/**
- * check whether an input argument has desired "key: value" input or not.
- * borrowed from UnsafeDeserialization module with some changes
- */
-predicate checkkeyBalue(CfgNodes::ExprNodes::PairCfgNode p, string key, string value) {
- p.getKey().getConstantValue().isStringlikeValue(key) and
- DataFlow::exprNode(p.getValue()).getALocalSource().getConstantValue().toString() = value
-}
-
/**
* An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is
* the default), considered a sink for unsafe deserialization.
- * borrowed from UnsafeDeserialization module with some changes
*/
class UnsafePlistParsexmlArgument extends PlistUnsafeSinks {
UnsafePlistParsexmlArgument() {
- exists(DataFlow::CallNode plistParsexml |
- plistParsexml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml")
+ exists(DataFlow::CallNode plistParseXml |
+ plistParseXml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml")
|
- this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and
- // Exclude calls that explicitly pass a safe mode option.
- checkkeyBalue(plistParsexml.getArgument(1).asExpr(), "marshal", "true")
+ this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and
+ plistParseXml.getKeywordArgument("marshal").getConstantValue().isBoolean(true)
or
- this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and
- plistParsexml.getNumberOfArguments() = 1
+ this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and
+ plistParseXml.getNumberOfArguments() = 1
)
}
}
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb
index 63f64b5cd22..433873d6fa0 100644
--- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb
+++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb
@@ -1,12 +1,16 @@
-require 'yaml'
+require 'plist'
class UsersController < ActionController::Base
def example
# not safe
+ config = true
result = Plist.parse_xml(params[:yaml_string])
+ result = Plist.parse_xml(params[:yaml_string], marshal: config)
result = Plist.parse_xml(params[:yaml_string], marshal: true)
# safe
+ config = false
result = Plist.parse_xml(params[:yaml_string], marshal: false)
+ result = Plist.parse_xml(params[:yaml_string], marshal: config)
end
end
diff --git a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
index 406ba24935b..9ee9234770e 100644
--- a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
+++ b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
@@ -17,6 +17,17 @@ libraries that support it, such as the Ruby standard library's JSON
module, ensure that the parser is configured to disable
deserialization of arbitrary objects.
+
+
+YAML/Psych recommendation:
+After Psych(YAML) 4.0.0, the load method is same as safe_load method.
+This vulnerability can be prevented by using YAML.load (same as YAML.safe_load), YAML.load_file (same as YAML.safe_load_file) instead of YAML.unsafe_* methods.
+Be careful that YAML.load_stream don't use safe_load method, Also Be careful the to_ruby method of Psych get called on a trusted parsed (YAML.parse*) yaml document.
+
+
+
+This vulnerability in Plist can be prevented by calling Plist.parse_xml FileOrXmlString, marshal: false.
+
@@ -27,6 +38,14 @@ on data from an HTTP request. Since these methods are capable of deserializing
to arbitrary objects, this is inherently unsafe.
+
+In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.
+
+
+In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for Plist.parse_xml to use it safe.
+
+
+
Using JSON.parse and YAML.safe_load instead, as in the
following example, removes the vulnerability. Similarly, calling
@@ -55,6 +74,10 @@ Ruby documentation: security guidance on the YAML library.
+
+You can read that how unsafe yaml load methods can lead to code executions:
+Universal Deserialisation Gadget for Ruby 2.x-3.x .
+
diff --git a/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb b/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb
new file mode 100644
index 00000000000..433873d6fa0
--- /dev/null
+++ b/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb
@@ -0,0 +1,17 @@
+require 'plist'
+class UsersController < ActionController::Base
+ def example
+ # not safe
+ config = true
+ result = Plist.parse_xml(params[:yaml_string])
+ result = Plist.parse_xml(params[:yaml_string], marshal: config)
+ result = Plist.parse_xml(params[:yaml_string], marshal: true)
+
+ # safe
+ config = false
+ result = Plist.parse_xml(params[:yaml_string], marshal: false)
+ result = Plist.parse_xml(params[:yaml_string], marshal: config)
+ end
+end
+
+
diff --git a/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb b/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb
new file mode 100644
index 00000000000..6e836a0a049
--- /dev/null
+++ b/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb
@@ -0,0 +1,22 @@
+require 'yaml'
+class UsersController < ActionController::Base
+ def example
+ # safe
+ Psych.load(params[:yaml_string])
+ Psych.load_file(params[:yaml_file])
+ Psych.parse_stream(params[:yaml_string])
+ Psych.parse(params[:yaml_string])
+ Psych.parse_file(params[:yaml_file])
+ # unsafe
+ Psych.unsafe_load(params[:yaml_string])
+ Psych.unsafe_load_file(params[:yaml_file])
+ Psych.load_stream(params[:yaml_string])
+ parse_output = Psych.parse_stream(params[:yaml_string])
+ parse_output.to_ruby
+ Psych.parse(params[:yaml_string]).to_ruby
+ Psych.parse_file(params[:yaml_file]).to_ruby
+
+ end
+end
+
+
From 40e24b6b94508d98dde7090dcd439714775f8bd0 Mon Sep 17 00:00:00 2001
From: amammad
Date: Thu, 27 Apr 2023 06:35:34 +0200
Subject: [PATCH 11/21] v4.1 fix file names in qhelp
---
.../src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp | 2 +-
.../src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp | 2 +-
.../src/queries/security/cwe-502/UnsafeDeserialization.qhelp | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp
index 45c4220c1b4..9863402d583 100644
--- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp
+++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp
@@ -14,7 +14,7 @@
In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for Plist.parse_xml to use it safe.
-
+
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp
index c3a74527483..c644f495271 100644
--- a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp
+++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp
@@ -15,7 +15,7 @@
In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.
-
+
diff --git a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
index 9ee9234770e..1ebf32750a1 100644
--- a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
+++ b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
@@ -40,11 +40,11 @@ to arbitrary objects, this is inherently unsafe.
In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.
-
+
In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for Plist.parse_xml to use it safe.
-
+
Using JSON.parse and YAML.safe_load instead, as in the
From d727d573d5ce139e8356bfca8765fc4dbcc9caa4 Mon Sep 17 00:00:00 2001
From: amammad
Date: Thu, 27 Apr 2023 06:48:15 +0200
Subject: [PATCH 12/21] v4.2 write exact version of yaml.load default loader
change
---
.../ruby/security/UnsafeDeserializationCustomizations.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
index fcaceed1b3a..9dea66252e5 100644
--- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
+++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
@@ -79,7 +79,7 @@ module UnsafeDeserialization {
* for unsafe deserialization. The `YAML` module is an alias of `Psych` in
* recent versions of Ruby.
* the `this = yamlNode().getAMethodCall("load").getArgument(0)` is safe
- * in recent versions of YAML library, so it will be removed in future.
+ * in psych/yaml library after [v4.0.0](https://github.com/ruby/psych/releases/tag/v4.0.0), so it will be removed in future.
*/
class YamlLoadArgument extends Sink {
YamlLoadArgument() {
From b8c3cba4ff0fa9819982425cca1bf41dcbd0e2c0 Mon Sep 17 00:00:00 2001
From: Harry Maclean
Date: Fri, 26 May 2023 14:48:16 +0000
Subject: [PATCH 13/21] Ruby: Consolidate unsafe deserialization queries
Merge the experimental YAMLUnsafeDeserialization and
PlistUnsafeDeserialization queries into the generate
UnsafeDeserialization query in the default suite.
These queries look for some specific sinks that we now find in the
general query.
Also apply some small code and comment refactors.
---
ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll | 34 +++----
.../UnsafeDeserializationCustomizations.qll | 25 +++---
.../cwe-502/PlistUnsafeDeserialization.qhelp | 24 -----
.../cwe-502/PlistUnsafeDeserialization.ql | 57 ------------
.../cwe-502/PlistUnsafeDeserialization.rb | 17 ----
.../cwe-502/YAMLUnsafeDeserialization.qhelp | 26 ------
.../cwe-502/YAMLUnsafeDeserialization.ql | 88 -------------------
.../cwe-502/UnsafeDeserialization.qhelp | 22 +++--
.../PlistUnsafeDeserialization.expected | 12 ---
.../cwe-502/PlistUnsafeDeserialization.qlref | 1 -
.../YAMLUnsafeDeserialization.expected | 34 -------
.../cwe-502/YAMLUnsafeDeserialization.qlref | 1 -
.../cwe-502/YAMLUnsafeDeserialization.rb | 22 -----
.../PlistUnsafeDeserialization.rb | 0
.../UnsafeDeserialization.expected | 42 +++++++++
.../YAMLUnsafeDeserialization.rb | 0
16 files changed, 75 insertions(+), 330 deletions(-)
delete mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp
delete mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql
delete mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb
delete mode 100644 ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp
delete mode 100644 ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref
delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb
rename ruby/ql/test/query-tests/{experimental/Security/cwe-502 => security/cwe-502/unsafe-deserialization}/PlistUnsafeDeserialization.rb (100%)
rename ruby/ql/{src/experimental/cwe-502 => test/query-tests/security/cwe-502/unsafe-deserialization}/YAMLUnsafeDeserialization.rb (100%)
diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll
index 81afdcbed7b..65596df7fe2 100644
--- a/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll
+++ b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll
@@ -8,36 +8,28 @@ private import codeql.ruby.ApiGraphs
/**
* A taint step related to the result of `YAML.parse` calls, or similar.
- *In the following example, this step will propagate taint from
- *`source` to `sink`:
+ * In the following example, this step will propagate taint from
+ * `source` to `sink`:
*
- *```rb
- *x = source
- *result = YAML.parse(x)
- *sink result.to_ruby # Unsafe call
+ * ```rb
+ * x = source
+ * result = YAML.parse(x)
+ * sink result.to_ruby # Unsafe call
* ```
*/
private class YamlParseStep extends AdditionalTaintStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(DataFlow::CallNode yamlParserMethod |
- yamlParserMethod = yamlNode().getAMethodCall(["parse", "parse_stream"]) and
+ succ = yamlParserMethod.getAMethodCall("to_ruby") and
(
- pred = yamlParserMethod.getArgument(0) or
- pred = yamlParserMethod.getKeywordArgument("yaml")
- ) and
- succ = yamlParserMethod.getAMethodCall("to_ruby")
- or
- yamlParserMethod = yamlNode().getAMethodCall("parse_file") and
- (
- pred = yamlParserMethod.getArgument(0) or
- pred = yamlParserMethod.getKeywordArgument("filename")
- ) and
- succ = yamlParserMethod.getAMethodCall("to_ruby")
+ yamlParserMethod = yamlNode().getAMethodCall(["parse", "parse_stream"]) and
+ pred = [yamlParserMethod.getArgument(0), yamlParserMethod.getKeywordArgument("yaml")]
+ or
+ yamlParserMethod = yamlNode().getAMethodCall("parse_file") and
+ pred = [yamlParserMethod.getArgument(0), yamlParserMethod.getKeywordArgument("filename")]
+ )
)
}
}
-/**
- * YAML/Psych Top level Class member
- */
private API::Node yamlNode() { result = API::getTopLevelMember(["YAML", "Psych"]) }
diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
index 9dea66252e5..e38a38af2dc 100644
--- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
+++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll
@@ -75,14 +75,13 @@ module UnsafeDeserialization {
}
/**
- * An argument in a call to `YAML.unsafe_*` and `YAML.load_stream` , considered sinks
+ * An argument in a call to `YAML.unsafe_*` and `YAML.load_stream` , considered a sink
* for unsafe deserialization. The `YAML` module is an alias of `Psych` in
* recent versions of Ruby.
- * the `this = yamlNode().getAMethodCall("load").getArgument(0)` is safe
- * in psych/yaml library after [v4.0.0](https://github.com/ruby/psych/releases/tag/v4.0.0), so it will be removed in future.
*/
class YamlLoadArgument extends Sink {
YamlLoadArgument() {
+ // Note: this is safe in psych/yaml >= 4.0.0.
this = yamlNode().getAMethodCall("load").getArgument(0)
or
this =
@@ -94,16 +93,11 @@ module UnsafeDeserialization {
}
}
- /**
- * YAML/Psych Top level Class member
- */
private API::Node yamlNode() { result = API::getTopLevelMember(["YAML", "Psych"]) }
/**
- * An argument in a call to `YAML.parse*`, considered sinks
- * for unsafe deserialization if there is a call to `to_ruby` on returned value of them,
- * so this need some additional taint steps. The `YAML` module is an alias of `Psych` in
- * recent versions of Ruby.
+ * An argument in a call to `YAML.parse*`, considered a sink for unsafe deserialization
+ * if there is a call to `to_ruby` on the returned value.
*/
class YamlParseArgument extends Sink {
YamlParseArgument() {
@@ -237,7 +231,7 @@ module UnsafeDeserialization {
}
/**
- * An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is
+ * An argument in a call to `Plist.parse_xml` where `marshal` is `true` (which is
* the default), considered a sink for unsafe deserialization.
*/
class UnsafePlistParsexmlArgument extends Sink {
@@ -246,10 +240,11 @@ module UnsafeDeserialization {
plistParseXml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml")
|
this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and
- plistParseXml.getKeywordArgument("marshal").getConstantValue().isBoolean(true)
- or
- this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and
- plistParseXml.getNumberOfArguments() = 1
+ (
+ plistParseXml.getKeywordArgument("marshal").getConstantValue().isBoolean(true)
+ or
+ plistParseXml.getNumberOfArguments() = 1
+ )
)
}
}
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp
deleted file mode 100644
index 9863402d583..00000000000
--- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
- Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application.
- Unsafe deserializing the malicious serialized xml document through the Plist library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain.
-
-
-
-
- This vulnerability in Plist can be prevented by calling Plist.parse_xml FileOrXmlString, marshal: false.
-
-
-
- In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for Plist.parse_xml to use it safe.
-
-
-
-
-
- Security considerations from library documentation: patsplat/plist Repository.
-
-
-
\ No newline at end of file
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql
deleted file mode 100644
index 4ba55824598..00000000000
--- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * @name Unsafe Deserialization of user-controlled data by Plist
- * @description Deserializing user-controlled data may allow attackers to
- * execute arbitrary code.
- * @kind path-problem
- * @problem.severity warning
- * @security-severity 9.8
- * @precision high
- * @id rb/plist-unsafe-deserialization
- * @tags security
- * experimental
- * external/cwe/cwe-502
- */
-
-import codeql.ruby.ApiGraphs
-import codeql.ruby.DataFlow
-import codeql.ruby.TaintTracking
-import codeql.ruby.CFG
-import DataFlow::PathGraph
-import codeql.ruby.security.UnsafeDeserializationCustomizations
-
-abstract class PlistUnsafeSinks extends DataFlow::Node { }
-
-/**
- * An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is
- * the default), considered a sink for unsafe deserialization.
- */
-class UnsafePlistParsexmlArgument extends PlistUnsafeSinks {
- UnsafePlistParsexmlArgument() {
- exists(DataFlow::CallNode plistParseXml |
- plistParseXml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml")
- |
- this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and
- plistParseXml.getKeywordArgument("marshal").getConstantValue().isBoolean(true)
- or
- this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and
- plistParseXml.getNumberOfArguments() = 1
- )
- }
-}
-
-class Configuration extends TaintTracking::Configuration {
- Configuration() { this = "PlistUnsafeDeserialization" }
-
- override predicate isSource(DataFlow::Node source) {
- // to detect CVE-2021-33575, we should uncomment following line instead of current UnsafeDeserialization::Source
- // source instanceof DataFlow::LocalSourceNode
- source instanceof UnsafeDeserialization::Source
- }
-
- override predicate isSink(DataFlow::Node sink) { sink instanceof PlistUnsafeSinks }
-}
-
-from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
-where config.hasFlowPath(source, sink)
-select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(),
- "potentially untrusted source"
diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb
deleted file mode 100644
index 433873d6fa0..00000000000
--- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-require 'plist'
-class UsersController < ActionController::Base
- def example
- # not safe
- config = true
- result = Plist.parse_xml(params[:yaml_string])
- result = Plist.parse_xml(params[:yaml_string], marshal: config)
- result = Plist.parse_xml(params[:yaml_string], marshal: true)
-
- # safe
- config = false
- result = Plist.parse_xml(params[:yaml_string], marshal: false)
- result = Plist.parse_xml(params[:yaml_string], marshal: config)
- end
-end
-
-
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp
deleted file mode 100644
index c644f495271..00000000000
--- a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
- Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application.
- Unsafe deserializing the malicious serialized yaml document through the Psych (YAML) library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain.
-
-
-
-
- After Psych(YAML) 4.0.0, the load method is same as safe_load method.
- This vulnerability can be prevented by using YAML.load (same as YAML.safe_load), YAML.load_file (same as YAML.safe_load_file) instead of YAML.unsafe_* methods.
- Be careful that YAML.load_stream don't use safe_load method, Also Be careful the to_ruby method of Psych get called on a trusted parsed (YAML.parse*) yaml document.
-
-
-
- In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.
-
-
-
-
- You can read that how unsafe yaml load methods can lead to code executions.
- Universal Deserialisation Gadget for Ruby 2.x-3.x .
-
-
-
\ No newline at end of file
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql
deleted file mode 100644
index 5cb720d19da..00000000000
--- a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * @name Unsafe Deserialization of user-controlled data by YAML
- * @description Deserializing user-controlled data may allow attackers to
- * execute arbitrary code.
- * @kind path-problem
- * @problem.severity warning
- * @security-severity 9.8
- * @precision high
- * @id rb/YAML-unsafe-deserialization
- * @tags security
- * experimental
- * external/cwe/cwe-502
- */
-
-import codeql.ruby.ApiGraphs
-import codeql.ruby.DataFlow
-import codeql.ruby.TaintTracking
-import DataFlow::PathGraph
-import codeql.ruby.security.UnsafeDeserializationCustomizations
-
-abstract class YamlUnsafeSinks extends DataFlow::Node { }
-
-class YamlUnsafeArgument extends YamlUnsafeSinks {
- YamlUnsafeArgument() {
- this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"])
- .getArgument(0)
- or
- this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall(["unsafe_load", "load_stream"])
- .getKeywordArgument("yaml")
- or
- this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall("unsafe_load_file")
- .getKeywordArgument("filename")
- or
- this =
- API::getTopLevelMember(["YAML", "Psych"])
- .getAMethodCall(["parse", "parse_stream", "parse_file"])
- .getAMethodCall("to_ruby")
- }
-}
-
-class Configuration extends TaintTracking::Configuration {
- Configuration() { this = "YamlUnsafeDeserialization" }
-
- override predicate isSource(DataFlow::Node source) {
- // to detect CVE-2022-32224, we should uncomment following line instead of current UnsafeDeserialization::Source
- // source instanceof DataFlow::LocalSourceNode
- source instanceof UnsafeDeserialization::Source
- }
-
- override predicate isSink(DataFlow::Node sink) {
- // after changing the isSource for detecting CVE-2022-32224
- // uncomment the following line only see the CVE sink not other files similar sinks
- // sink.getLocation().getFile().toString().matches("%yaml_column%") and
- sink instanceof YamlUnsafeSinks
- }
-
- override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
- exists(DataFlow::CallNode yaml_parser_methods |
- yaml_parser_methods =
- API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and
- (
- nodeFrom = yaml_parser_methods.getArgument(0) or
- nodeFrom = yaml_parser_methods.getKeywordArgument("yaml")
- ) and
- nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
- )
- or
- exists(DataFlow::CallNode yaml_parser_methods |
- yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and
- (
- nodeFrom = yaml_parser_methods.getArgument(0) or
- nodeFrom = yaml_parser_methods.getKeywordArgument("filename")
- ) and
- nodeTo = yaml_parser_methods.getAMethodCall("to_ruby")
- )
- }
-}
-
-from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
-where config.hasFlowPath(source, sink)
-select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(),
- "potentially untrusted source"
diff --git a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
index 1ebf32750a1..17f03853570 100644
--- a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
+++ b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
@@ -19,14 +19,19 @@ deserialization of arbitrary objects.
-YAML/Psych recommendation:
-After Psych(YAML) 4.0.0, the load method is same as safe_load method.
-This vulnerability can be prevented by using YAML.load (same as YAML.safe_load), YAML.load_file (same as YAML.safe_load_file) instead of YAML.unsafe_* methods.
-Be careful that YAML.load_stream don't use safe_load method, Also Be careful the to_ruby method of Psych get called on a trusted parsed (YAML.parse*) yaml document.
+If deserializing an untrusted YAML document using the psych gem
+prior to version 4.0.0, the load method is vulnerable. Use
+safe_load instead. With psych version 4.0.0 and later,
+the load is safe. The same applies to load_file.
+load_stream is vulnerable in all versions. The safe versions of these
+methods (safe_load and safe_load_file) are not vulnerable
+in any known version.
-This vulnerability in Plist can be prevented by calling Plist.parse_xml FileOrXmlString, marshal: false.
+To safely deserialize Property List
+files using the plist gem, ensure that you pass marshal: false
+when calling Plist.parse_xml.
@@ -39,13 +44,6 @@ to arbitrary objects, this is inherently unsafe.
-In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.
-
-
-In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for Plist.parse_xml to use it safe.
-
-
-
Using JSON.parse and YAML.safe_load instead, as in the
following example, removes the vulnerability. Similarly, calling
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected
deleted file mode 100644
index 967ef978a3b..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected
+++ /dev/null
@@ -1,12 +0,0 @@
-edges
-| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] |
-| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] |
-nodes
-| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | semmle.label | call to params : |
-| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | semmle.label | ...[...] |
-| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | semmle.label | call to params : |
-| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | semmle.label | ...[...] |
-subpaths
-#select
-| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | potentially untrusted source |
-| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref
deleted file mode 100644
index f7bfbada7b5..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref
+++ /dev/null
@@ -1 +0,0 @@
-experimental/cwe-502/PlistUnsafeDeserialization.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected
deleted file mode 100644
index 9a9bd05e514..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected
+++ /dev/null
@@ -1,34 +0,0 @@
-edges
-| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] |
-| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] |
-| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] |
-| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : |
-| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby |
-| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : |
-| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby |
-| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : |
-| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby |
-nodes
-| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] |
-| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] |
-| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] |
-| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : |
-| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : |
-| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby |
-| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : |
-| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : |
-subpaths
-#select
-| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source |
-| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source |
-| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source |
-| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source |
-| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source |
-| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source |
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref
deleted file mode 100644
index e06e0921159..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref
+++ /dev/null
@@ -1 +0,0 @@
-experimental/cwe-502/YAMLUnsafeDeserialization.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb
deleted file mode 100644
index 6e836a0a049..00000000000
--- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'yaml'
-class UsersController < ActionController::Base
- def example
- # safe
- Psych.load(params[:yaml_string])
- Psych.load_file(params[:yaml_file])
- Psych.parse_stream(params[:yaml_string])
- Psych.parse(params[:yaml_string])
- Psych.parse_file(params[:yaml_file])
- # unsafe
- Psych.unsafe_load(params[:yaml_string])
- Psych.unsafe_load_file(params[:yaml_file])
- Psych.load_stream(params[:yaml_string])
- parse_output = Psych.parse_stream(params[:yaml_string])
- parse_output.to_ruby
- Psych.parse(params[:yaml_string]).to_ruby
- Psych.parse_file(params[:yaml_file]).to_ruby
-
- end
-end
-
-
diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.rb b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/PlistUnsafeDeserialization.rb
similarity index 100%
rename from ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.rb
rename to ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/PlistUnsafeDeserialization.rb
diff --git a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected
index 6fbbb14ef8a..b1f1d701a73 100644
--- a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected
+++ b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected
@@ -1,4 +1,6 @@
edges
+| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] |
+| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] |
| UnsafeDeserialization.rb:10:5:10:19 | serialized_data | UnsafeDeserialization.rb:11:27:11:41 | serialized_data |
| UnsafeDeserialization.rb:10:23:10:50 | call to decode64 | UnsafeDeserialization.rb:10:5:10:19 | serialized_data |
| UnsafeDeserialization.rb:10:39:10:44 | call to params | UnsafeDeserialization.rb:10:39:10:50 | ...[...] |
@@ -29,7 +31,21 @@ edges
| UnsafeDeserialization.rb:87:5:87:13 | yaml_data | UnsafeDeserialization.rb:88:25:88:33 | yaml_data |
| UnsafeDeserialization.rb:87:17:87:22 | call to params | UnsafeDeserialization.rb:87:17:87:28 | ...[...] |
| UnsafeDeserialization.rb:87:17:87:28 | ...[...] | UnsafeDeserialization.rb:87:5:87:13 | yaml_data |
+| YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] |
+| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] |
+| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] |
+| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] |
+| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] |
+| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby |
+| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] |
+| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby |
+| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] |
+| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby |
nodes
+| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | semmle.label | call to params |
+| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | semmle.label | ...[...] |
+| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | semmle.label | call to params |
+| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:10:5:10:19 | serialized_data | semmle.label | serialized_data |
| UnsafeDeserialization.rb:10:23:10:50 | call to decode64 | semmle.label | call to decode64 |
| UnsafeDeserialization.rb:10:39:10:44 | call to params | semmle.label | call to params |
@@ -74,8 +90,27 @@ nodes
| UnsafeDeserialization.rb:98:24:98:32 | call to read | semmle.label | call to read |
| UnsafeDeserialization.rb:101:24:101:27 | call to gets | semmle.label | call to gets |
| UnsafeDeserialization.rb:104:24:104:32 | call to readlines | semmle.label | call to readlines |
+| YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | semmle.label | call to params |
+| YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | semmle.label | call to params |
+| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | semmle.label | call to params |
+| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | semmle.label | call to params |
+| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | semmle.label | call to params |
+| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | semmle.label | call to params |
+| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] | semmle.label | ...[...] |
+| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby |
+| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | semmle.label | call to params |
+| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] | semmle.label | ...[...] |
subpaths
#select
+| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | user-provided value |
+| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | user-provided value |
| UnsafeDeserialization.rb:11:27:11:41 | serialized_data | UnsafeDeserialization.rb:10:39:10:44 | call to params | UnsafeDeserialization.rb:11:27:11:41 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:10:39:10:44 | call to params | user-provided value |
| UnsafeDeserialization.rb:17:30:17:44 | serialized_data | UnsafeDeserialization.rb:16:39:16:44 | call to params | UnsafeDeserialization.rb:17:30:17:44 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:16:39:16:44 | call to params | user-provided value |
| UnsafeDeserialization.rb:23:24:23:32 | json_data | UnsafeDeserialization.rb:22:17:22:22 | call to params | UnsafeDeserialization.rb:23:24:23:32 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:22:17:22:22 | call to params | user-provided value |
@@ -91,3 +126,10 @@ subpaths
| UnsafeDeserialization.rb:98:24:98:32 | call to read | UnsafeDeserialization.rb:98:24:98:32 | call to read | UnsafeDeserialization.rb:98:24:98:32 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:98:24:98:32 | call to read | value from stdin |
| UnsafeDeserialization.rb:101:24:101:27 | call to gets | UnsafeDeserialization.rb:101:24:101:27 | call to gets | UnsafeDeserialization.rb:101:24:101:27 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:101:24:101:27 | call to gets | value from stdin |
| UnsafeDeserialization.rb:104:24:104:32 | call to readlines | UnsafeDeserialization.rb:104:24:104:32 | call to readlines | UnsafeDeserialization.rb:104:24:104:32 | call to readlines | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:104:24:104:32 | call to readlines | value from stdin |
+| YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] | YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | user-provided value |
+| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | user-provided value |
+| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | user-provided value |
+| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | user-provided value |
+| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | user-provided value |
+| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | user-provided value |
+| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | user-provided value |
diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.rb b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/YAMLUnsafeDeserialization.rb
similarity index 100%
rename from ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.rb
rename to ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/YAMLUnsafeDeserialization.rb
From 562065f29e6fd387534e517942e89f907117a290 Mon Sep 17 00:00:00 2001
From: Harry Maclean
Date: Sat, 27 May 2023 00:59:36 +0000
Subject: [PATCH 14/21] Ruby: Add change note
---
ruby/ql/lib/change-notes/2023-05-27-unsafe-deserialization.md | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 ruby/ql/lib/change-notes/2023-05-27-unsafe-deserialization.md
diff --git a/ruby/ql/lib/change-notes/2023-05-27-unsafe-deserialization.md b/ruby/ql/lib/change-notes/2023-05-27-unsafe-deserialization.md
new file mode 100644
index 00000000000..4039e7c90dc
--- /dev/null
+++ b/ruby/ql/lib/change-notes/2023-05-27-unsafe-deserialization.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* Additional sinks for `rb/unsafe-deserialization` have been added. This includes various methods from the `yaml` and `plist` gems, which deserialize YAML and Property List data, respectively.
From e515981c81d1fd82d586de9bc4afa8f5e4988470 Mon Sep 17 00:00:00 2001
From: Harry Maclean
Date: Sat, 27 May 2023 12:01:00 +0000
Subject: [PATCH 15/21] Ruby: Remove unused examples
---
.../examples/PlistUnsafeDeserialization.rb | 17 --------------
.../examples/YAMLUnsafeDeserialization.rb | 22 -------------------
2 files changed, 39 deletions(-)
delete mode 100644 ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb
delete mode 100644 ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb
diff --git a/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb b/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb
deleted file mode 100644
index 433873d6fa0..00000000000
--- a/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-require 'plist'
-class UsersController < ActionController::Base
- def example
- # not safe
- config = true
- result = Plist.parse_xml(params[:yaml_string])
- result = Plist.parse_xml(params[:yaml_string], marshal: config)
- result = Plist.parse_xml(params[:yaml_string], marshal: true)
-
- # safe
- config = false
- result = Plist.parse_xml(params[:yaml_string], marshal: false)
- result = Plist.parse_xml(params[:yaml_string], marshal: config)
- end
-end
-
-
diff --git a/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb b/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb
deleted file mode 100644
index 6e836a0a049..00000000000
--- a/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'yaml'
-class UsersController < ActionController::Base
- def example
- # safe
- Psych.load(params[:yaml_string])
- Psych.load_file(params[:yaml_file])
- Psych.parse_stream(params[:yaml_string])
- Psych.parse(params[:yaml_string])
- Psych.parse_file(params[:yaml_file])
- # unsafe
- Psych.unsafe_load(params[:yaml_string])
- Psych.unsafe_load_file(params[:yaml_file])
- Psych.load_stream(params[:yaml_string])
- parse_output = Psych.parse_stream(params[:yaml_string])
- parse_output.to_ruby
- Psych.parse(params[:yaml_string]).to_ruby
- Psych.parse_file(params[:yaml_file]).to_ruby
-
- end
-end
-
-
From ca1024e2858c6f541c5adef4e0405dbc6b7625f1 Mon Sep 17 00:00:00 2001
From: Harry Maclean
Date: Mon, 29 May 2023 03:46:30 +0000
Subject: [PATCH 16/21] Ruby: Reword unsafe deserialization qhelp
---
.../security/cwe-502/UnsafeDeserialization.qhelp | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
index 17f03853570..8bacb266423 100644
--- a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
+++ b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
@@ -19,13 +19,12 @@ deserialization of arbitrary objects.
-If deserializing an untrusted YAML document using the psych gem
-prior to version 4.0.0, the load method is vulnerable. Use
-safe_load instead. With psych version 4.0.0 and later,
-the load is safe. The same applies to load_file.
-load_stream is vulnerable in all versions. The safe versions of these
-methods (safe_load and safe_load_file) are not vulnerable
-in any known version.
+If deserializing an untrusted YAML document using the psych gem,
+prefer the safe_load and safe_load_file methods over
+load and load_file, as the former will safely
+handle untrusted data. Avoid passing untrusted data to the load_stream
+method. In psych version 4.0.0 and above, the load can
+safely be used.
From e70e3e52dcf7456465fdc6f59e687f08293c40d2 Mon Sep 17 00:00:00 2001
From: Harry Maclean
Date: Mon, 29 May 2023 04:05:42 +0000
Subject: [PATCH 17/21] Ruby: fix typo in qhelp
---
.../ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
index 8bacb266423..e361b62338e 100644
--- a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
+++ b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp
@@ -23,7 +23,7 @@ If deserializing an untrusted YAML document using the psych gem,
prefer the safe_load and safe_load_file methods over
load and load_file, as the former will safely
handle untrusted data. Avoid passing untrusted data to the load_stream
-method. In psych version 4.0.0 and above, the load can
+method. In psych version 4.0.0 and above, the load method can
safely be used.
From 0c8b4251cf6bc10e59977033d6252d95838e3b00 Mon Sep 17 00:00:00 2001
From: Rasmus Wriedt Larsen
Date: Wed, 7 Jun 2023 10:07:01 +0200
Subject: [PATCH 18/21] Python: Avoid duplicated query-id
---
.../ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql b/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql
index 671bc0998fd..5a38a673080 100644
--- a/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql
+++ b/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql
@@ -5,7 +5,7 @@
* @problem.severity error
* @security-severity 9.3
* @precision high
- * @id py/command-injection
+ * @id py/paramiko-command-injection
* @tags security
* experimental
* external/cwe/cwe-074
From 6dfeb2536bd274a3068e17c63d50f872150dd56e Mon Sep 17 00:00:00 2001
From: erik-krogh
Date: Thu, 1 Jun 2023 09:44:30 +0200
Subject: [PATCH 19/21] delete old deprecations
---
python/ql/lib/semmle/python/Files.qll | 6 -
.../python/dataflow/old/TaintTracking.qll | 8 -
.../lib/semmle/python/frameworks/Django.qll | 33 -----
.../lib/semmle/python/frameworks/FastApi.qll | 3 -
.../python/frameworks/RestFramework.qll | 3 -
.../semmle/python/frameworks/SqlAlchemy.qll | 3 -
.../lib/semmle/python/frameworks/Stdlib.qll | 39 -----
.../lib/semmle/python/frameworks/Tornado.qll | 3 -
.../lib/semmle/python/pointsto/PointsTo.qll | 48 ------
.../lib/semmle/python/security/ClearText.qll | 54 -------
.../ql/lib/semmle/python/security/Crypto.qll | 139 ------------------
.../semmle/python/security/SensitiveData.qll | 118 ---------------
.../security/dataflow/ChainedConfigs12.qll | 95 ------------
.../security/dataflow/CleartextLogging.qll | 14 --
.../security/dataflow/CleartextStorage.qll | 14 --
.../security/dataflow/CodeInjection.qll | 13 --
.../security/dataflow/CommandInjection.qll | 13 --
.../security/dataflow/LdapInjection.qll | 12 --
.../python/security/dataflow/LogInjection.qll | 10 --
.../security/dataflow/PathInjection.qll | 133 -----------------
.../security/dataflow/PolynomialReDoS.qll | 10 --
.../python/security/dataflow/ReflectedXSS.qll | 16 --
.../dataflow/ReflectedXSSCustomizations.qll | 3 -
.../security/dataflow/RegexInjection.qll | 10 --
.../dataflow/ServerSideRequestForgery.qll | 25 ----
.../python/security/dataflow/SqlInjection.qll | 16 --
.../security/dataflow/StackTraceExposure.qll | 13 --
.../dataflow/UnsafeDeserialization.qll | 13 --
.../python/security/dataflow/UrlRedirect.qll | 13 --
.../dataflow/WeakSensitiveDataHashing.qll | 19 ---
.../security/dataflow/XpathInjection.qll | 10 --
.../semmle/python/security/flow/AnyCall.qll | 9 --
.../security/injection/Deserialization.qll | 8 -
.../semmle/python/security/injection/Exec.qll | 29 ----
.../python/security/injection/Marshal.qll | 33 -----
.../semmle/python/security/injection/Path.qll | 81 ----------
.../python/security/injection/Pickle.qll | 36 -----
.../security/injection/RegexInjection.qll | 6 -
.../RegexInjectionCustomizations.qll | 6 -
.../semmle/python/security/injection/Xml.qll | 70 ---------
.../semmle/python/security/injection/Yaml.qll | 28 ----
.../ql/lib/semmle/python/types/Extensions.qll | 25 ----
.../CWE-020-ExternalAPIs/ExternalAPIs.qll | 15 --
.../experimental/semmle/python/Concepts.qll | 48 ------
.../python/security/LDAPInsecureAuth.qll | 24 ---
.../security/injection/NoSQLInjection.qll | 3 -
.../security/sensitive/Sources.expected | 6 -
.../security/sensitive/Sources.ql | 5 -
.../library-tests/security/sensitive/test.py | 21 ---
.../web/bottle/HttpResponseSinks.expected | 5 -
.../web/bottle/HttpResponseSinks.ql | 7 -
.../web/bottle/HttpSources.expected | 9 --
.../library-tests/web/bottle/HttpSources.ql | 7 -
.../library-tests/web/bottle/Routing.expected | 8 -
.../test/library-tests/web/bottle/Routing.ql | 5 -
.../library-tests/web/bottle/Taint.expected | 23 ---
.../ql/test/library-tests/web/bottle/Taint.ql | 7 -
.../ql/test/library-tests/web/bottle/options | 1 -
.../ql/test/library-tests/web/bottle/test.py | 36 -----
.../web/cherrypy/HttpResponseSinks.expected | 4 -
.../web/cherrypy/HttpResponseSinks.ql | 7 -
.../web/cherrypy/HttpSources.expected | 4 -
.../library-tests/web/cherrypy/HttpSources.ql | 7 -
.../test/library-tests/web/cherrypy/options | 1 -
.../ql/test/library-tests/web/cherrypy/red.py | 11 --
.../test/library-tests/web/cherrypy/test.py | 23 ---
.../requests/ClientHttpRequests.expected | 3 -
.../web/client/requests/ClientHttpRequests.ql | 7 -
.../library-tests/web/client/requests/options | 1 -
.../library-tests/web/client/requests/test.py | 4 -
.../client/six/ClientHttpRequests.expected | 11 --
.../web/client/six/ClientHttpRequests.ql | 7 -
.../test/library-tests/web/client/six/options | 2 -
.../test/library-tests/web/client/six/test.py | 37 -----
.../client/stdlib/ClientHttpRequests.expected | 11 --
.../web/client/stdlib/ClientHttpRequests.ql | 7 -
.../library-tests/web/client/stdlib/options | 1 -
.../library-tests/web/client/stdlib/test.py | 44 ------
.../web/django/HttpRedirectSinks.expected | 5 -
.../web/django/HttpRedirectSinks.ql | 7 -
.../web/django/HttpResponseSinks.expected | 32 ----
.../web/django/HttpResponseSinks.ql | 7 -
.../web/django/HttpSources.expected | 53 -------
.../library-tests/web/django/HttpSources.ql | 7 -
.../web/django/SqlInjectionSinks.expected | 9 --
.../web/django/SqlInjectionSinks.ql | 8 -
.../ql/test/library-tests/web/django/options | 1 -
.../ql/test/library-tests/web/django/sql.py | 53 -------
.../test/library-tests/web/django/test_1x.py | 19 ---
.../library-tests/web/django/test_2x_3x.py | 19 ---
.../test/library-tests/web/django/views_1x.py | 107 --------------
.../library-tests/web/django/views_2x_3x.py | 128 ----------------
.../web/falcon/HttpResponseSinks.expected | 1 -
.../web/falcon/HttpResponseSinks.ql | 8 -
.../web/falcon/HttpSources.expected | 4 -
.../library-tests/web/falcon/HttpSources.ql | 7 -
.../library-tests/web/falcon/Routing.expected | 4 -
.../test/library-tests/web/falcon/Routing.ql | 5 -
.../library-tests/web/falcon/Sinks.expected | 0
.../ql/test/library-tests/web/falcon/Sinks.ql | 8 -
.../library-tests/web/falcon/Taint.expected | 20 ---
.../ql/test/library-tests/web/falcon/Taint.ql | 8 -
.../ql/test/library-tests/web/falcon/options | 1 -
.../ql/test/library-tests/web/falcon/test.py | 28 ----
.../web/flask/HttpResponseSinks.expected | 17 ---
.../web/flask/HttpResponseSinks.ql | 7 -
.../web/flask/HttpSources.expected | 10 --
.../library-tests/web/flask/HttpSources.ql | 7 -
.../library-tests/web/flask/Routing.expected | 11 --
.../test/library-tests/web/flask/Routing.ql | 6 -
.../library-tests/web/flask/Taint.expected | 33 -----
.../ql/test/library-tests/web/flask/Taint.ql | 8 -
.../ql/test/library-tests/web/flask/options | 1 -
.../ql/test/library-tests/web/flask/test.py | 67 ---------
.../web/pyramid/HttpResponseSinks.expected | 4 -
.../web/pyramid/HttpResponseSinks.ql | 7 -
.../web/pyramid/HttpSources.expected | 4 -
.../library-tests/web/pyramid/HttpSources.ql | 7 -
.../web/pyramid/Routing.expected | 4 -
.../test/library-tests/web/pyramid/Routing.ql | 6 -
.../library-tests/web/pyramid/Taint.expected | 11 --
.../test/library-tests/web/pyramid/Taint.ql | 8 -
.../ql/test/library-tests/web/pyramid/options | 1 -
.../ql/test/library-tests/web/pyramid/test.py | 25 ----
.../web/stdlib/HttpResponseSinks.expected | 3 -
.../web/stdlib/HttpResponseSinks.ql | 7 -
.../web/stdlib/HttpSources.expected | 35 -----
.../library-tests/web/stdlib/HttpSources.ql | 9 --
.../web/stdlib/TestTaint.expected | 32 ----
.../library-tests/web/stdlib/TestTaint.ql | 32 ----
.../ql/test/library-tests/web/stdlib/test.py | 108 --------------
.../web/tornado/Classes.expected | 5 -
.../test/library-tests/web/tornado/Classes.ql | 7 -
.../web/tornado/HttpRedirectSinks.expected | 2 -
.../web/tornado/HttpRedirectSinks.ql | 7 -
.../web/tornado/HttpResponseSinks.expected | 4 -
.../web/tornado/HttpResponseSinks.ql | 7 -
.../web/tornado/HttpSources.expected | 5 -
.../library-tests/web/tornado/HttpSources.ql | 7 -
.../library-tests/web/tornado/Taint.expected | 12 --
.../test/library-tests/web/tornado/Taint.ql | 10 --
.../ql/test/library-tests/web/tornado/options | 1 -
.../ql/test/library-tests/web/tornado/test.py | 26 ----
.../web/turbogears/Controller.expected | 6 -
.../web/turbogears/Controller.ql | 5 -
.../web/turbogears/HttpResponseSinks.expected | 6 -
.../web/turbogears/HttpResponseSinks.ql | 7 -
.../web/turbogears/HttpSources.expected | 4 -
.../web/turbogears/HttpSources.ql | 7 -
.../web/turbogears/Taint.expected | 12 --
.../library-tests/web/turbogears/Taint.ql | 7 -
.../test/library-tests/web/turbogears/options | 1 -
.../test/library-tests/web/turbogears/test.py | 27 ----
.../web/twisted/Classes.expected | 6 -
.../test/library-tests/web/twisted/Classes.ql | 7 -
.../web/twisted/HttpResponseSinks.expected | 11 --
.../web/twisted/HttpResponseSinks.ql | 7 -
.../web/twisted/HttpSources.expected | 9 --
.../library-tests/web/twisted/HttpSources.ql | 7 -
.../web/twisted/Methods.expected | 9 --
.../test/library-tests/web/twisted/Methods.ql | 7 -
.../library-tests/web/twisted/Taint.expected | 41 ------
.../test/library-tests/web/twisted/Taint.ql | 8 -
.../ql/test/library-tests/web/twisted/options | 1 -
.../ql/test/library-tests/web/twisted/test.py | 51 -------
.../ql/lib/BytecodeExpr.qll | 33 -----
.../ql/lib/RecordedCalls.qll | 15 --
167 files changed, 3068 deletions(-)
delete mode 100644 python/ql/lib/semmle/python/security/ClearText.qll
delete mode 100644 python/ql/lib/semmle/python/security/Crypto.qll
delete mode 100644 python/ql/lib/semmle/python/security/SensitiveData.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/CleartextLogging.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/CleartextStorage.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/CodeInjection.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/CommandInjection.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/LdapInjection.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/LogInjection.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/PathInjection.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/PolynomialReDoS.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/ReflectedXSS.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/RegexInjection.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgery.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/SqlInjection.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/StackTraceExposure.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/UnsafeDeserialization.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/UrlRedirect.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashing.qll
delete mode 100644 python/ql/lib/semmle/python/security/dataflow/XpathInjection.qll
delete mode 100644 python/ql/lib/semmle/python/security/flow/AnyCall.qll
delete mode 100644 python/ql/lib/semmle/python/security/injection/Deserialization.qll
delete mode 100644 python/ql/lib/semmle/python/security/injection/Exec.qll
delete mode 100644 python/ql/lib/semmle/python/security/injection/Marshal.qll
delete mode 100644 python/ql/lib/semmle/python/security/injection/Path.qll
delete mode 100644 python/ql/lib/semmle/python/security/injection/Pickle.qll
delete mode 100644 python/ql/lib/semmle/python/security/injection/RegexInjection.qll
delete mode 100644 python/ql/lib/semmle/python/security/injection/RegexInjectionCustomizations.qll
delete mode 100644 python/ql/lib/semmle/python/security/injection/Xml.qll
delete mode 100644 python/ql/lib/semmle/python/security/injection/Yaml.qll
delete mode 100644 python/ql/test/library-tests/security/sensitive/Sources.expected
delete mode 100644 python/ql/test/library-tests/security/sensitive/Sources.ql
delete mode 100644 python/ql/test/library-tests/security/sensitive/test.py
delete mode 100644 python/ql/test/library-tests/web/bottle/HttpResponseSinks.expected
delete mode 100644 python/ql/test/library-tests/web/bottle/HttpResponseSinks.ql
delete mode 100644 python/ql/test/library-tests/web/bottle/HttpSources.expected
delete mode 100644 python/ql/test/library-tests/web/bottle/HttpSources.ql
delete mode 100644 python/ql/test/library-tests/web/bottle/Routing.expected
delete mode 100644 python/ql/test/library-tests/web/bottle/Routing.ql
delete mode 100644 python/ql/test/library-tests/web/bottle/Taint.expected
delete mode 100644 python/ql/test/library-tests/web/bottle/Taint.ql
delete mode 100644 python/ql/test/library-tests/web/bottle/options
delete mode 100644 python/ql/test/library-tests/web/bottle/test.py
delete mode 100644 python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.expected
delete mode 100644 python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.ql
delete mode 100644 python/ql/test/library-tests/web/cherrypy/HttpSources.expected
delete mode 100644 python/ql/test/library-tests/web/cherrypy/HttpSources.ql
delete mode 100644 python/ql/test/library-tests/web/cherrypy/options
delete mode 100644 python/ql/test/library-tests/web/cherrypy/red.py
delete mode 100644 python/ql/test/library-tests/web/cherrypy/test.py
delete mode 100644 python/ql/test/library-tests/web/client/requests/ClientHttpRequests.expected
delete mode 100644 python/ql/test/library-tests/web/client/requests/ClientHttpRequests.ql
delete mode 100644 python/ql/test/library-tests/web/client/requests/options
delete mode 100644 python/ql/test/library-tests/web/client/requests/test.py
delete mode 100644 python/ql/test/library-tests/web/client/six/ClientHttpRequests.expected
delete mode 100644 python/ql/test/library-tests/web/client/six/ClientHttpRequests.ql
delete mode 100644 python/ql/test/library-tests/web/client/six/options
delete mode 100644 python/ql/test/library-tests/web/client/six/test.py
delete mode 100644 python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.expected
delete mode 100644 python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.ql
delete mode 100644 python/ql/test/library-tests/web/client/stdlib/options
delete mode 100644 python/ql/test/library-tests/web/client/stdlib/test.py
delete mode 100644 python/ql/test/library-tests/web/django/HttpRedirectSinks.expected
delete mode 100644 python/ql/test/library-tests/web/django/HttpRedirectSinks.ql
delete mode 100644 python/ql/test/library-tests/web/django/HttpResponseSinks.expected
delete mode 100644 python/ql/test/library-tests/web/django/HttpResponseSinks.ql
delete mode 100644 python/ql/test/library-tests/web/django/HttpSources.expected
delete mode 100644 python/ql/test/library-tests/web/django/HttpSources.ql
delete mode 100644 python/ql/test/library-tests/web/django/SqlInjectionSinks.expected
delete mode 100644 python/ql/test/library-tests/web/django/SqlInjectionSinks.ql
delete mode 100644 python/ql/test/library-tests/web/django/options
delete mode 100644 python/ql/test/library-tests/web/django/sql.py
delete mode 100644 python/ql/test/library-tests/web/django/test_1x.py
delete mode 100644 python/ql/test/library-tests/web/django/test_2x_3x.py
delete mode 100644 python/ql/test/library-tests/web/django/views_1x.py
delete mode 100644 python/ql/test/library-tests/web/django/views_2x_3x.py
delete mode 100644 python/ql/test/library-tests/web/falcon/HttpResponseSinks.expected
delete mode 100644 python/ql/test/library-tests/web/falcon/HttpResponseSinks.ql
delete mode 100644 python/ql/test/library-tests/web/falcon/HttpSources.expected
delete mode 100644 python/ql/test/library-tests/web/falcon/HttpSources.ql
delete mode 100644 python/ql/test/library-tests/web/falcon/Routing.expected
delete mode 100644 python/ql/test/library-tests/web/falcon/Routing.ql
delete mode 100644 python/ql/test/library-tests/web/falcon/Sinks.expected
delete mode 100644 python/ql/test/library-tests/web/falcon/Sinks.ql
delete mode 100644 python/ql/test/library-tests/web/falcon/Taint.expected
delete mode 100644 python/ql/test/library-tests/web/falcon/Taint.ql
delete mode 100644 python/ql/test/library-tests/web/falcon/options
delete mode 100644 python/ql/test/library-tests/web/falcon/test.py
delete mode 100644 python/ql/test/library-tests/web/flask/HttpResponseSinks.expected
delete mode 100644 python/ql/test/library-tests/web/flask/HttpResponseSinks.ql
delete mode 100644 python/ql/test/library-tests/web/flask/HttpSources.expected
delete mode 100644 python/ql/test/library-tests/web/flask/HttpSources.ql
delete mode 100644 python/ql/test/library-tests/web/flask/Routing.expected
delete mode 100644 python/ql/test/library-tests/web/flask/Routing.ql
delete mode 100644 python/ql/test/library-tests/web/flask/Taint.expected
delete mode 100644 python/ql/test/library-tests/web/flask/Taint.ql
delete mode 100644 python/ql/test/library-tests/web/flask/options
delete mode 100644 python/ql/test/library-tests/web/flask/test.py
delete mode 100644 python/ql/test/library-tests/web/pyramid/HttpResponseSinks.expected
delete mode 100644 python/ql/test/library-tests/web/pyramid/HttpResponseSinks.ql
delete mode 100644 python/ql/test/library-tests/web/pyramid/HttpSources.expected
delete mode 100644 python/ql/test/library-tests/web/pyramid/HttpSources.ql
delete mode 100644 python/ql/test/library-tests/web/pyramid/Routing.expected
delete mode 100644 python/ql/test/library-tests/web/pyramid/Routing.ql
delete mode 100644 python/ql/test/library-tests/web/pyramid/Taint.expected
delete mode 100644 python/ql/test/library-tests/web/pyramid/Taint.ql
delete mode 100644 python/ql/test/library-tests/web/pyramid/options
delete mode 100644 python/ql/test/library-tests/web/pyramid/test.py
delete mode 100644 python/ql/test/library-tests/web/stdlib/HttpResponseSinks.expected
delete mode 100644 python/ql/test/library-tests/web/stdlib/HttpResponseSinks.ql
delete mode 100644 python/ql/test/library-tests/web/stdlib/HttpSources.expected
delete mode 100644 python/ql/test/library-tests/web/stdlib/HttpSources.ql
delete mode 100644 python/ql/test/library-tests/web/stdlib/TestTaint.expected
delete mode 100644 python/ql/test/library-tests/web/stdlib/TestTaint.ql
delete mode 100644 python/ql/test/library-tests/web/stdlib/test.py
delete mode 100644 python/ql/test/library-tests/web/tornado/Classes.expected
delete mode 100644 python/ql/test/library-tests/web/tornado/Classes.ql
delete mode 100644 python/ql/test/library-tests/web/tornado/HttpRedirectSinks.expected
delete mode 100644 python/ql/test/library-tests/web/tornado/HttpRedirectSinks.ql
delete mode 100644 python/ql/test/library-tests/web/tornado/HttpResponseSinks.expected
delete mode 100644 python/ql/test/library-tests/web/tornado/HttpResponseSinks.ql
delete mode 100644 python/ql/test/library-tests/web/tornado/HttpSources.expected
delete mode 100644 python/ql/test/library-tests/web/tornado/HttpSources.ql
delete mode 100644 python/ql/test/library-tests/web/tornado/Taint.expected
delete mode 100644 python/ql/test/library-tests/web/tornado/Taint.ql
delete mode 100644 python/ql/test/library-tests/web/tornado/options
delete mode 100644 python/ql/test/library-tests/web/tornado/test.py
delete mode 100644 python/ql/test/library-tests/web/turbogears/Controller.expected
delete mode 100644 python/ql/test/library-tests/web/turbogears/Controller.ql
delete mode 100644 python/ql/test/library-tests/web/turbogears/HttpResponseSinks.expected
delete mode 100644 python/ql/test/library-tests/web/turbogears/HttpResponseSinks.ql
delete mode 100644 python/ql/test/library-tests/web/turbogears/HttpSources.expected
delete mode 100644 python/ql/test/library-tests/web/turbogears/HttpSources.ql
delete mode 100644 python/ql/test/library-tests/web/turbogears/Taint.expected
delete mode 100644 python/ql/test/library-tests/web/turbogears/Taint.ql
delete mode 100644 python/ql/test/library-tests/web/turbogears/options
delete mode 100644 python/ql/test/library-tests/web/turbogears/test.py
delete mode 100644 python/ql/test/library-tests/web/twisted/Classes.expected
delete mode 100644 python/ql/test/library-tests/web/twisted/Classes.ql
delete mode 100644 python/ql/test/library-tests/web/twisted/HttpResponseSinks.expected
delete mode 100644 python/ql/test/library-tests/web/twisted/HttpResponseSinks.ql
delete mode 100644 python/ql/test/library-tests/web/twisted/HttpSources.expected
delete mode 100644 python/ql/test/library-tests/web/twisted/HttpSources.ql
delete mode 100644 python/ql/test/library-tests/web/twisted/Methods.expected
delete mode 100644 python/ql/test/library-tests/web/twisted/Methods.ql
delete mode 100644 python/ql/test/library-tests/web/twisted/Taint.expected
delete mode 100644 python/ql/test/library-tests/web/twisted/Taint.ql
delete mode 100644 python/ql/test/library-tests/web/twisted/options
delete mode 100644 python/ql/test/library-tests/web/twisted/test.py
diff --git a/python/ql/lib/semmle/python/Files.qll b/python/ql/lib/semmle/python/Files.qll
index 4d331a26308..059a0d72b28 100644
--- a/python/ql/lib/semmle/python/Files.qll
+++ b/python/ql/lib/semmle/python/Files.qll
@@ -154,12 +154,6 @@ abstract class Container extends @container {
*/
string toString() { result = this.getAbsolutePath() }
- /**
- * Gets the name of this container.
- * DEPRECATED: Use `getAbsolutePath` instead.
- */
- deprecated string getName() { result = this.getAbsolutePath() }
-
/**
* Gets the relative path of this file or folder from the root folder of the
* analyzed source location. The relative path of the root folder itself is
diff --git a/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll b/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll
index d0293522404..0ce4bc27790 100644
--- a/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll
+++ b/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll
@@ -664,14 +664,6 @@ module DataFlow {
}
}
-deprecated private class DataFlowType extends TaintKind {
- // this only exists to avoid an empty recursion error in the type checker
- DataFlowType() {
- this = "Data flow" and
- 1 = 2
- }
-}
-
pragma[noinline]
private predicate dict_construct(ControlFlowNode itemnode, ControlFlowNode dictnode) {
dictnode.(DictNode).getAValue() = itemnode
diff --git a/python/ql/lib/semmle/python/frameworks/Django.qll b/python/ql/lib/semmle/python/frameworks/Django.qll
index 2240894a3f4..7fcc64f181e 100644
--- a/python/ql/lib/semmle/python/frameworks/Django.qll
+++ b/python/ql/lib/semmle/python/frameworks/Django.qll
@@ -534,9 +534,6 @@ module PrivateDjango {
/** Gets a reference to the `django` module. */
API::Node django() { result = API::moduleImport("django") }
- /** DEPRECATED: Alias for `DjangoImpl` */
- deprecated module django = DjangoImpl;
-
/** Provides models for the `django` module. */
module DjangoImpl {
// -------------------------------------------------------------------------
@@ -552,9 +549,6 @@ module PrivateDjango {
DjangoDb() { this = API::moduleImport("django").getMember("db") }
}
- /** DEPRECATED: Alias for `DB` */
- deprecated module db = DB;
-
/** Provides models for the `django.db` module. */
module DB {
/** Gets a reference to the `django.db.connection` object. */
@@ -571,9 +565,6 @@ module PrivateDjango {
/** Gets a reference to the `django.db.models` module. */
API::Node models() { result = db().getMember("models") }
- /** DEPRECATED: Alias for `Models` */
- deprecated module models = Models;
-
/** Provides models for the `django.db.models` module. */
module Models {
/**
@@ -819,9 +810,6 @@ module PrivateDjango {
/** Gets a reference to the `django.db.models.expressions` module. */
API::Node expressions() { result = models().getMember("expressions") }
- /** DEPRECATED: Alias for `Expressions` */
- deprecated module expressions = Expressions;
-
/** Provides models for the `django.db.models.expressions` module. */
module Expressions {
/** Provides models for the `django.db.models.expressions.RawSql` class. */
@@ -858,9 +846,6 @@ module PrivateDjango {
instance(DataFlow::TypeTracker::end(), sql).flowsTo(result)
}
}
-
- /** DEPRECATED: Alias for RawSql */
- deprecated module RawSQL = RawSql;
}
/** This internal module provides data-flow modeling of Django ORM. */
@@ -1099,9 +1084,6 @@ module PrivateDjango {
/** Gets a reference to the `django.urls` module. */
API::Node urls() { result = django().getMember("urls") }
- /** DEPRECATED: Alias for `Urls` */
- deprecated module urls = Urls;
-
/** Provides models for the `django.urls` module */
module Urls {
/**
@@ -1123,14 +1105,8 @@ module PrivateDjango {
/** Gets a reference to the `django.conf` module. */
API::Node conf() { result = django().getMember("conf") }
- /** DEPRECATED: Alias for `Conf` */
- deprecated module conf = Conf;
-
/** Provides models for the `django.conf` module */
module Conf {
- /** DEPRECATED: Alias for `ConfUrls` */
- deprecated module conf_urls = ConfUrls;
-
/** Provides models for the `django.conf.urls` module */
module ConfUrls {
// -------------------------------------------------------------------------
@@ -1166,9 +1142,6 @@ module PrivateDjango {
/** Gets a reference to the `django.http.request` module. */
API::Node request() { result = http().getMember("request") }
- /** DEPRECATED: Alias for `Request` */
- deprecated module request = Request;
-
/** Provides models for the `django.http.request` module. */
module Request {
/**
@@ -1331,9 +1304,6 @@ module PrivateDjango {
/** Gets a reference to the `django.http.response` module. */
API::Node response() { result = http().getMember("response") }
- /** DEPRECATED: Alias for `Response` */
- deprecated module response = Response;
-
/** Provides models for the `django.http.response` module */
module Response {
/**
@@ -2189,9 +2159,6 @@ module PrivateDjango {
/** Gets a reference to the `django.shortcuts` module. */
API::Node shortcuts() { result = django().getMember("shortcuts") }
- /** DEPRECATED: Alias for `Shortcuts` */
- deprecated module shortcuts = Shortcuts;
-
/** Provides models for the `django.shortcuts` module */
module Shortcuts {
/**
diff --git a/python/ql/lib/semmle/python/frameworks/FastApi.qll b/python/ql/lib/semmle/python/frameworks/FastApi.qll
index d6f5bba6d9f..07dbd982653 100644
--- a/python/ql/lib/semmle/python/frameworks/FastApi.qll
+++ b/python/ql/lib/semmle/python/frameworks/FastApi.qll
@@ -37,9 +37,6 @@ private module FastApi {
}
}
- /** DEPRECATED: Alias for ApiRouter */
- deprecated module APIRouter = ApiRouter;
-
// ---------------------------------------------------------------------------
// routing modeling
// ---------------------------------------------------------------------------
diff --git a/python/ql/lib/semmle/python/frameworks/RestFramework.qll b/python/ql/lib/semmle/python/frameworks/RestFramework.qll
index dcbd247a1c5..23b32946e31 100644
--- a/python/ql/lib/semmle/python/frameworks/RestFramework.qll
+++ b/python/ql/lib/semmle/python/frameworks/RestFramework.qll
@@ -359,7 +359,4 @@ private module RestFramework {
override string getMimetypeDefault() { none() }
}
}
-
- /** DEPRECATED: Alias for ApiException */
- deprecated module APIException = ApiException;
}
diff --git a/python/ql/lib/semmle/python/frameworks/SqlAlchemy.qll b/python/ql/lib/semmle/python/frameworks/SqlAlchemy.qll
index c1712e7e7eb..0bb0125cf5c 100644
--- a/python/ql/lib/semmle/python/frameworks/SqlAlchemy.qll
+++ b/python/ql/lib/semmle/python/frameworks/SqlAlchemy.qll
@@ -169,9 +169,6 @@ module SqlAlchemy {
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
}
- /** DEPRECATED: Alias for DBApiConnection */
- deprecated module DBAPIConnection = DBApiConnection;
-
/**
* Provides models for the `sqlalchemy.orm.Session` class
*
diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll
index cd5ec31945e..8af918f4bb4 100644
--- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll
+++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll
@@ -130,9 +130,6 @@ module Stdlib {
}
}
- /** DEPRECATED: Alias for HttpMessage */
- deprecated module HTTPMessage = HttpMessage;
-
/**
* Provides models for the `http.cookies.Morsel` class
*
@@ -1821,9 +1818,6 @@ private module StdlibPrivate {
/** Gets a reference to the `BaseHttpServer` module. */
API::Node baseHttpServer() { result = API::moduleImport("BaseHTTPServer") }
- /** DEPRECATED: Alias for baseHttpServer */
- deprecated API::Node baseHTTPServer() { result = baseHttpServer() }
-
/** Provides models for the `BaseHttpServer` module. */
module BaseHttpServer {
/**
@@ -1833,23 +1827,14 @@ private module StdlibPrivate {
/** Gets a reference to the `BaseHttpServer.BaseHttpRequestHandler` class. */
API::Node classRef() { result = baseHttpServer().getMember("BaseHTTPRequestHandler") }
}
-
- /** DEPRECATED: Alias for BaseHttpRequestHandler */
- deprecated module BaseHTTPRequestHandler = BaseHttpRequestHandler;
}
- /** DEPRECATED: Alias for BaseHttpServer */
- deprecated module BaseHTTPServer = BaseHttpServer;
-
// ---------------------------------------------------------------------------
// SimpleHTTPServer (Python 2 only)
// ---------------------------------------------------------------------------
/** Gets a reference to the `SimpleHttpServer` module. */
API::Node simpleHttpServer() { result = API::moduleImport("SimpleHTTPServer") }
- /** DEPRECATED: Alias for simpleHttpServer */
- deprecated API::Node simpleHTTPServer() { result = simpleHttpServer() }
-
/** Provides models for the `SimpleHttpServer` module. */
module SimpleHttpServer {
/**
@@ -1859,23 +1844,14 @@ private module StdlibPrivate {
/** Gets a reference to the `SimpleHttpServer.SimpleHttpRequestHandler` class. */
API::Node classRef() { result = simpleHttpServer().getMember("SimpleHTTPRequestHandler") }
}
-
- /** DEPRECATED: Alias for SimpleHttpRequestHandler */
- deprecated module SimpleHTTPRequestHandler = SimpleHttpRequestHandler;
}
- /** DEPRECATED: Alias for SimpleHttpServer */
- deprecated module SimpleHTTPServer = SimpleHttpServer;
-
// ---------------------------------------------------------------------------
// CGIHTTPServer (Python 2 only)
// ---------------------------------------------------------------------------
/** Gets a reference to the `CGIHTTPServer` module. */
API::Node cgiHttpServer() { result = API::moduleImport("CGIHTTPServer") }
- /** DEPRECATED: Alias for cgiHttpServer */
- deprecated API::Node cgiHTTPServer() { result = cgiHttpServer() }
-
/** Provides models for the `CGIHTTPServer` module. */
module CgiHttpServer {
/**
@@ -1919,9 +1895,6 @@ private module StdlibPrivate {
API::Node classRef() { result = server().getMember("BaseHTTPRequestHandler") }
}
- /** DEPRECATED: Alias for BaseHttpRequestHandler */
- deprecated module BaseHTTPRequestHandler = BaseHttpRequestHandler;
-
/**
* Provides models for the `http.server.SimpleHTTPRequestHandler` class (Python 3 only).
*
@@ -1932,9 +1905,6 @@ private module StdlibPrivate {
API::Node classRef() { result = server().getMember("SimpleHTTPRequestHandler") }
}
- /** DEPRECATED: Alias for SimpleHttpRequestHandler */
- deprecated module SimpleHTTPRequestHandler = SimpleHttpRequestHandler;
-
/**
* Provides models for the `http.server.CGIHTTPRequestHandler` class (Python 3 only).
*
@@ -1978,9 +1948,6 @@ private module StdlibPrivate {
HttpRequestHandlerClassDef() { this.getParent() = subclassRef().asSource().asExpr() }
}
- /** DEPRECATED: Alias for HttpRequestHandlerClassDef */
- deprecated class HTTPRequestHandlerClassDef = HttpRequestHandlerClassDef;
-
/**
* A source of instances of the `BaseHTTPRequestHandler` class or any subclass, extend this class to model new instances.
*
@@ -2352,9 +2319,6 @@ private module StdlibPrivate {
}
}
- /** DEPRECATED: Alias for HttpConnection */
- deprecated module HTTPConnection = HttpConnection;
-
/**
* Provides models for the `http.client.HTTPResponse` class
*
@@ -2424,9 +2388,6 @@ private module StdlibPrivate {
}
}
- /** DEPRECATED: Alias for HttpResponse */
- deprecated module HTTPResponse = HttpResponse;
-
// ---------------------------------------------------------------------------
// sqlite3
// ---------------------------------------------------------------------------
diff --git a/python/ql/lib/semmle/python/frameworks/Tornado.qll b/python/ql/lib/semmle/python/frameworks/Tornado.qll
index 12a69908f80..73c016ed927 100644
--- a/python/ql/lib/semmle/python/frameworks/Tornado.qll
+++ b/python/ql/lib/semmle/python/frameworks/Tornado.qll
@@ -64,9 +64,6 @@ module Tornado {
}
}
- /** DEPRECATED: Alias for HttpHeaders */
- deprecated module HTTPHeaders = HttpHeaders;
-
// ---------------------------------------------------------------------------
// tornado
// ---------------------------------------------------------------------------
diff --git a/python/ql/lib/semmle/python/pointsto/PointsTo.qll b/python/ql/lib/semmle/python/pointsto/PointsTo.qll
index 1369d6d6ce7..fb05e9b49ff 100644
--- a/python/ql/lib/semmle/python/pointsto/PointsTo.qll
+++ b/python/ql/lib/semmle/python/pointsto/PointsTo.qll
@@ -1445,14 +1445,6 @@ module Expressions {
)
}
- deprecated predicate subscriptPointsTo(
- SubscriptNode subscr, PointsToContext context, ObjectInternal value, ControlFlowNode origin,
- ControlFlowNode obj, ObjectInternal objvalue
- ) {
- subscriptPointsTo(subscr, context, value, obj, objvalue) and
- origin = subscr
- }
-
pragma[noinline]
private predicate subscriptPointsTo(
SubscriptNode subscr, PointsToContext context, ObjectInternal value, ControlFlowNode obj,
@@ -1489,14 +1481,6 @@ module Expressions {
index = subscr.getIndex()
}
- deprecated predicate binaryPointsTo(
- BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode origin,
- ControlFlowNode operand, ObjectInternal opvalue
- ) {
- binaryPointsTo(b, context, value, operand, opvalue) and
- origin = b
- }
-
/**
* Tracking too many binary expressions is likely to kill performance, so just say anything other than addition or bitwise or is 'unknown'.
*/
@@ -1521,14 +1505,6 @@ module Expressions {
)
}
- deprecated predicate addPointsTo(
- BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode origin,
- ControlFlowNode operand, ObjectInternal opvalue
- ) {
- addPointsTo(b, context, value, operand, opvalue) and
- origin = b
- }
-
pragma[noinline]
private predicate addPointsTo(
BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode operand,
@@ -1545,14 +1521,6 @@ module Expressions {
)
}
- deprecated predicate bitOrPointsTo(
- BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode origin,
- ControlFlowNode operand, ObjectInternal opvalue
- ) {
- bitOrPointsTo(b, context, value, operand, opvalue) and
- origin = b
- }
-
pragma[noinline]
private predicate bitOrPointsTo(
BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode operand,
@@ -1577,14 +1545,6 @@ module Expressions {
value = obj.intValue()
}
- deprecated predicate unaryPointsTo(
- UnaryExprNode u, PointsToContext context, ObjectInternal value, ControlFlowNode origin,
- ControlFlowNode operand, ObjectInternal opvalue
- ) {
- unaryPointsTo(u, context, value, operand, opvalue) and
- origin = u
- }
-
pragma[noinline]
private predicate unaryPointsTo(
UnaryExprNode u, PointsToContext context, ObjectInternal value, ControlFlowNode operand,
@@ -1603,14 +1563,6 @@ module Expressions {
)
}
- deprecated predicate builtinCallPointsTo(
- CallNode call, PointsToContext context, ObjectInternal value, ControlFlowNode origin,
- ControlFlowNode arg, ObjectInternal argvalue
- ) {
- builtinCallPointsTo(call, context, value, arg, argvalue) and
- origin = call
- }
-
pragma[noinline]
private predicate builtinCallPointsTo(
CallNode call, PointsToContext context, ObjectInternal value, ControlFlowNode arg,
diff --git a/python/ql/lib/semmle/python/security/ClearText.qll b/python/ql/lib/semmle/python/security/ClearText.qll
deleted file mode 100644
index c466be17ae6..00000000000
--- a/python/ql/lib/semmle/python/security/ClearText.qll
+++ /dev/null
@@ -1,54 +0,0 @@
-import python
-import semmle.python.dataflow.TaintTracking
-import semmle.python.security.SensitiveData
-import semmle.python.dataflow.Files
-import semmle.python.web.Http
-
-deprecated module ClearTextStorage {
- abstract class Sink extends TaintSink {
- override predicate sinks(TaintKind kind) { kind instanceof SensitiveData }
- }
-
- class CookieStorageSink extends Sink {
- CookieStorageSink() { any(CookieSet cookie).getValue() = this }
- }
-
- class FileStorageSink extends Sink {
- FileStorageSink() {
- exists(CallNode call, AttrNode meth, string name |
- any(OpenFile fd).taints(meth.getObject(name)) and
- call.getFunction() = meth and
- call.getAnArg() = this
- |
- name = "write"
- )
- }
- }
-}
-
-deprecated module ClearTextLogging {
- abstract class Sink extends TaintSink {
- override predicate sinks(TaintKind kind) { kind instanceof SensitiveData }
- }
-
- class PrintSink extends Sink {
- PrintSink() {
- exists(CallNode call |
- call.getAnArg() = this and
- call = Value::named("print").getACall()
- )
- }
- }
-
- class LoggingSink extends Sink {
- LoggingSink() {
- exists(CallNode call, AttrNode meth, string name |
- call.getFunction() = meth and
- meth.getObject(name).(NameNode).getId().matches("logg%") and
- call.getAnArg() = this
- |
- name = ["error", "warn", "warning", "debug", "info"]
- )
- }
- }
-}
diff --git a/python/ql/lib/semmle/python/security/Crypto.qll b/python/ql/lib/semmle/python/security/Crypto.qll
deleted file mode 100644
index dbf53f8a0fa..00000000000
--- a/python/ql/lib/semmle/python/security/Crypto.qll
+++ /dev/null
@@ -1,139 +0,0 @@
-import python
-import semmle.python.dataflow.TaintTracking
-private import semmle.python.security.SensitiveData
-private import semmle.crypto.Crypto as CryptoLib
-
-abstract deprecated class WeakCryptoSink extends TaintSink {
- override predicate sinks(TaintKind taint) { taint instanceof SensitiveData }
-}
-
-/** Modeling the 'pycrypto' package https://github.com/dlitz/pycrypto (latest release 2013) */
-deprecated module Pycrypto {
- ModuleValue cipher(string name) { result = Module::named("Crypto.Cipher").attr(name) }
-
- class CipherInstance extends TaintKind {
- string name;
-
- CipherInstance() {
- this = "Crypto.Cipher." + name and
- exists(cipher(name))
- }
-
- string getName() { result = name }
-
- CryptoLib::CryptographicAlgorithm getAlgorithm() { result.getName() = name }
-
- predicate isWeak() { this.getAlgorithm().isWeak() }
- }
-
- class CipherInstanceSource extends TaintSource {
- CipherInstance instance;
-
- CipherInstanceSource() {
- exists(AttrNode attr |
- this.(CallNode).getFunction() = attr and
- attr.getObject("new").pointsTo(cipher(instance.getName()))
- )
- }
-
- override string toString() { result = "Source of " + instance }
-
- override predicate isSourceOf(TaintKind kind) { kind = instance }
- }
-
- class PycryptoWeakCryptoSink extends WeakCryptoSink {
- string name;
-
- PycryptoWeakCryptoSink() {
- exists(CallNode call, AttrNode method, CipherInstance cipher |
- call.getAnArg() = this and
- call.getFunction() = method and
- cipher.taints(method.getObject("encrypt")) and
- cipher.isWeak() and
- cipher.getName() = name
- )
- }
-
- override string toString() { result = "Use of weak crypto algorithm " + name }
- }
-}
-
-deprecated module Cryptography {
- ModuleValue ciphers() {
- result = Module::named("cryptography.hazmat.primitives.ciphers") and
- result.isPackage()
- }
-
- class CipherClass extends ClassValue {
- CipherClass() { ciphers().attr("Cipher") = this }
- }
-
- class AlgorithmClass extends ClassValue {
- AlgorithmClass() { ciphers().attr("algorithms").attr(_) = this }
-
- string getAlgorithmName() { result = this.declaredAttribute("name").(StringValue).getText() }
-
- predicate isWeak() {
- exists(CryptoLib::CryptographicAlgorithm algo |
- algo.getName() = this.getAlgorithmName() and
- algo.isWeak()
- )
- }
- }
-
- class CipherInstance extends TaintKind {
- AlgorithmClass cls;
-
- CipherInstance() { this = "cryptography.Cipher." + cls.getAlgorithmName() }
-
- AlgorithmClass getAlgorithm() { result = cls }
-
- predicate isWeak() { cls.isWeak() }
-
- override TaintKind getTaintOfMethodResult(string name) {
- name = "encryptor" and
- result.(Encryptor).getAlgorithm() = this.getAlgorithm()
- }
- }
-
- class CipherSource extends TaintSource {
- CipherSource() { this.(CallNode).getFunction().pointsTo(any(CipherClass cls)) }
-
- override predicate isSourceOf(TaintKind kind) {
- this.(CallNode).getArg(0).pointsTo().getClass() = kind.(CipherInstance).getAlgorithm()
- }
-
- override string toString() { result = "cryptography.Cipher.source" }
- }
-
- class Encryptor extends TaintKind {
- AlgorithmClass cls;
-
- Encryptor() { this = "cryptography.encryptor." + cls.getAlgorithmName() }
-
- AlgorithmClass getAlgorithm() { result = cls }
- }
-
- class CryptographyWeakCryptoSink extends WeakCryptoSink {
- CryptographyWeakCryptoSink() {
- exists(CallNode call, AttrNode method, Encryptor encryptor |
- call.getAnArg() = this and
- call.getFunction() = method and
- encryptor.taints(method.getObject("update")) and
- encryptor.getAlgorithm().isWeak()
- )
- }
-
- override string toString() { result = "Use of weak crypto algorithm" }
- }
-}
-
-deprecated private class CipherConfig extends TaintTracking::Configuration {
- CipherConfig() { this = "Crypto cipher config" }
-
- override predicate isSource(TaintTracking::Source source) {
- source instanceof Pycrypto::CipherInstanceSource
- or
- source instanceof Cryptography::CipherSource
- }
-}
diff --git a/python/ql/lib/semmle/python/security/SensitiveData.qll b/python/ql/lib/semmle/python/security/SensitiveData.qll
deleted file mode 100644
index 7a955c0fd5a..00000000000
--- a/python/ql/lib/semmle/python/security/SensitiveData.qll
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * Provides classes and predicates for identifying sensitive data and methods for security.
- *
- * 'Sensitive' data in general is anything that should not be sent around in unencrypted form. This
- * library tries to guess where sensitive data may either be stored in a variable or produced by a
- * method.
- *
- * In addition, there are methods that ought not to be executed or not in a fashion that the user
- * can control. This includes authorization methods such as logins, and sending of data, etc.
- */
-
-import python
-import semmle.python.dataflow.TaintTracking
-import semmle.python.web.HttpRequest
-import semmle.python.security.internal.SensitiveDataHeuristics
-private import HeuristicNames
-
-abstract deprecated class SensitiveData extends TaintKind {
- bindingset[this]
- SensitiveData() { this = this }
-
- /** Gets the classification of this sensitive data taint kind. */
- abstract SensitiveDataClassification getClassification();
-}
-
-deprecated module SensitiveData {
- class Secret extends SensitiveData {
- Secret() { this = "sensitive.data.secret" }
-
- override string repr() { result = "a secret" }
-
- override SensitiveDataClassification getClassification() {
- result = SensitiveDataClassification::secret()
- }
- }
-
- class Id extends SensitiveData {
- Id() { this = "sensitive.data.id" }
-
- override string repr() { result = "an ID" }
-
- override SensitiveDataClassification getClassification() {
- result = SensitiveDataClassification::id()
- }
- }
-
- class Password extends SensitiveData {
- Password() { this = "sensitive.data.password" }
-
- override string repr() { result = "a password" }
-
- override SensitiveDataClassification getClassification() {
- result = SensitiveDataClassification::password()
- }
- }
-
- class Certificate extends SensitiveData {
- Certificate() { this = "sensitive.data.certificate" }
-
- override string repr() { result = "a certificate or key" }
-
- override SensitiveDataClassification getClassification() {
- result = SensitiveDataClassification::certificate()
- }
- }
-
- private SensitiveData fromFunction(Value func) {
- nameIndicatesSensitiveData(func.getName(), result.getClassification())
- }
-
- abstract class Source extends TaintSource {
- abstract string repr();
- }
-
- private class SensitiveCallSource extends Source {
- SensitiveData data;
-
- SensitiveCallSource() {
- exists(Value callee | callee.getACall() = this | data = fromFunction(callee))
- }
-
- override predicate isSourceOf(TaintKind kind) { kind = data }
-
- override string repr() { result = "a call returning " + data.repr() }
- }
-
- /** An access to a variable or property that might contain sensitive data. */
- private class SensitiveVariableAccess extends SensitiveData::Source {
- SensitiveData data;
-
- SensitiveVariableAccess() {
- nameIndicatesSensitiveData(this.(AttrNode).getName(), data.getClassification())
- }
-
- override predicate isSourceOf(TaintKind kind) { kind = data }
-
- override string repr() { result = "an attribute or property containing " + data.repr() }
- }
-
- private class SensitiveRequestParameter extends SensitiveData::Source {
- SensitiveData data;
-
- SensitiveRequestParameter() {
- this.(CallNode).getFunction().(AttrNode).getName() = "get" and
- exists(StringValue sensitive |
- this.(CallNode).getAnArg().pointsTo(sensitive) and
- nameIndicatesSensitiveData(sensitive.getText(), data.getClassification())
- )
- }
-
- override predicate isSourceOf(TaintKind kind) { kind = data }
-
- override string repr() { result = "a request parameter containing " + data.repr() }
- }
-}
-
-//Backwards compatibility
-deprecated class SensitiveDataSource = SensitiveData::Source;
diff --git a/python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll b/python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll
deleted file mode 100644
index 7eee413131b..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * DEPRECATED -- use flow state instead
- *
- * This defines a `PathGraph` where sinks from `TaintTracking::Configuration`s are identified with
- * sources from `TaintTracking2::Configuration`s if they represent the same `ControlFlowNode`.
- *
- * Paths are then connected appropriately.
- */
-
-import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.DataFlow2
-import semmle.python.dataflow.new.TaintTracking
-import semmle.python.dataflow.new.TaintTracking2
-
-/**
- * A `DataFlow::Node` that appears as a sink in Config1 and a source in Config2.
- */
-private predicate crossoverNode(DataFlow::Node n) {
- any(TaintTracking::Configuration t1).isSink(n) and
- any(TaintTracking2::Configuration t2).isSource(n)
-}
-
-/**
- * A new type which represents the union of the two sets of nodes.
- */
-private newtype TCustomPathNode =
- Config1Node(DataFlow::PathNode node1) { not crossoverNode(node1.getNode()) } or
- Config2Node(DataFlow2::PathNode node2) { not crossoverNode(node2.getNode()) } or
- CrossoverNode(DataFlow::Node node) { crossoverNode(node) }
-
-/**
- * DEPRECATED: Use flow state instead
- *
- * A class representing the set of all the path nodes in either config.
- */
-deprecated class CustomPathNode extends TCustomPathNode {
- /** Gets the PathNode if it is in Config1. */
- DataFlow::PathNode asNode1() {
- this = Config1Node(result) or this = CrossoverNode(result.getNode())
- }
-
- /** Gets the PathNode if it is in Config2. */
- DataFlow2::PathNode asNode2() {
- this = Config2Node(result) or this = CrossoverNode(result.getNode())
- }
-
- /**
- * Holds if this element is at the specified location.
- * The location spans column `startcolumn` of line `startline` to
- * column `endcolumn` of line `endline` in file `filepath`.
- * For more information, see
- * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
- */
- predicate hasLocationInfo(
- string filepath, int startline, int startcolumn, int endline, int endcolumn
- ) {
- this.asNode1().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
- or
- this.asNode2().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
- }
-
- /** Gets a textual representation of this element. */
- string toString() {
- result = this.asNode1().toString()
- or
- result = this.asNode2().toString()
- }
-}
-
-/**
- * DEPRECATED: Use flow state instead
- *
- * Holds if `(a,b)` is an edge in the graph of data flow path explanations.
- */
-deprecated query predicate edges(CustomPathNode a, CustomPathNode b) {
- // Edge is in Config1 graph
- DataFlow::PathGraph::edges(a.asNode1(), b.asNode1())
- or
- // Edge is in Config2 graph
- DataFlow2::PathGraph::edges(a.asNode2(), b.asNode2())
-}
-
-/**
- * DEPRECATED: Use flow state instead
- *
- * Holds if `n` is a node in the graph of data flow path explanations.
- */
-deprecated query predicate nodes(CustomPathNode n, string key, string val) {
- // Node is in Config1 graph
- DataFlow::PathGraph::nodes(n.asNode1(), key, val)
- or
- // Node is in Config2 graph
- DataFlow2::PathGraph::nodes(n.asNode2(), key, val)
-}
diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextLogging.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextLogging.qll
deleted file mode 100644
index 4471c9f4c34..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/CleartextLogging.qll
+++ /dev/null
@@ -1,14 +0,0 @@
-/** DEPRECATED. Import `CleartextLoggingQuery` instead. */
-
-private import python
-private import semmle.python.dataflow.new.DataFlow
-private import semmle.python.dataflow.new.TaintTracking
-private import semmle.python.Concepts
-private import semmle.python.dataflow.new.RemoteFlowSources
-private import semmle.python.dataflow.new.BarrierGuards
-private import semmle.python.dataflow.new.SensitiveDataSources
-
-/** DEPRECATED. Import `CleartextLoggingQuery` instead. */
-deprecated module CleartextLogging {
- import CleartextLoggingQuery // ignore-query-import
-}
diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextStorage.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextStorage.qll
deleted file mode 100644
index 105510aaeb5..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/CleartextStorage.qll
+++ /dev/null
@@ -1,14 +0,0 @@
-/** DEPRECATED. Import `CleartextStorageQuery` instead. */
-
-private import python
-private import semmle.python.dataflow.new.DataFlow
-private import semmle.python.dataflow.new.TaintTracking
-private import semmle.python.Concepts
-private import semmle.python.dataflow.new.RemoteFlowSources
-private import semmle.python.dataflow.new.BarrierGuards
-private import semmle.python.dataflow.new.SensitiveDataSources
-
-/** DEPRECATED. Import `CleartextStorageQuery` instead. */
-deprecated module CleartextStorage {
- import CleartextStorageQuery // ignore-query-import
-}
diff --git a/python/ql/lib/semmle/python/security/dataflow/CodeInjection.qll b/python/ql/lib/semmle/python/security/dataflow/CodeInjection.qll
deleted file mode 100644
index 35f6d96b753..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/CodeInjection.qll
+++ /dev/null
@@ -1,13 +0,0 @@
-/** DEPRECATED. Import `CodeInjectionQuery` instead. */
-
-private import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `CodeInjectionQuery` instead. */
-deprecated module CodeInjection {
- import CodeInjectionQuery // ignore-query-import
-}
-
-/** DEPRECATED. Import `CodeInjectionQuery` instead. */
-deprecated class CodeInjectionConfiguration = CodeInjection::Configuration;
diff --git a/python/ql/lib/semmle/python/security/dataflow/CommandInjection.qll b/python/ql/lib/semmle/python/security/dataflow/CommandInjection.qll
deleted file mode 100644
index c72be4985fc..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/CommandInjection.qll
+++ /dev/null
@@ -1,13 +0,0 @@
-/** DEPRECATED. Import `CommandInjectionQuery` instead. */
-
-private import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `CommandInjectionQuery` instead. */
-deprecated module CommandInjection {
- import CommandInjectionQuery // ignore-query-import
-}
-
-/** DEPRECATED. Import `CommandInjectionQuery` instead. */
-deprecated class CommandInjectionConfiguration = CommandInjection::Configuration;
diff --git a/python/ql/lib/semmle/python/security/dataflow/LdapInjection.qll b/python/ql/lib/semmle/python/security/dataflow/LdapInjection.qll
deleted file mode 100644
index df9e89dbf82..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/LdapInjection.qll
+++ /dev/null
@@ -1,12 +0,0 @@
-/** DEPRECATED. Import `LdapInjectionQuery` instead. */
-
-import python
-import semmle.python.Concepts
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-import semmle.python.dataflow.new.RemoteFlowSources
-
-/** DEPRECATED. Import `LdapInjectionQuery` instead. */
-deprecated module LdapInjection {
- import LdapInjectionQuery // ignore-query-import
-}
diff --git a/python/ql/lib/semmle/python/security/dataflow/LogInjection.qll b/python/ql/lib/semmle/python/security/dataflow/LogInjection.qll
deleted file mode 100644
index 0a00e695483..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/LogInjection.qll
+++ /dev/null
@@ -1,10 +0,0 @@
-/** DEPRECATED. Import `LogInjectionQuery` instead. */
-
-import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `LogInjectionQuery` instead. */
-deprecated module LogInjection {
- import LogInjectionQuery // ignore-query-import
-}
diff --git a/python/ql/lib/semmle/python/security/dataflow/PathInjection.qll b/python/ql/lib/semmle/python/security/dataflow/PathInjection.qll
deleted file mode 100644
index 79e61abb0ce..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/PathInjection.qll
+++ /dev/null
@@ -1,133 +0,0 @@
-/** DEPRECATED. Import `PathInjectionQuery` instead. */
-
-private import python
-private import semmle.python.Concepts
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `PathInjectionQuery` instead. */
-deprecated module PathInjection {
- import PathInjectionQuery // ignore-query-import
-}
-
-// ---------------------------------------------------------------------------
-// Old, deprecated code
-// ---------------------------------------------------------------------------
-private import semmle.python.dataflow.new.DataFlow2
-private import semmle.python.dataflow.new.TaintTracking2
-private import ChainedConfigs12
-import PathInjectionCustomizations::PathInjection
-
-// ---------------------------------------------------------------------------
-// Case 1. The path is never normalized.
-// ---------------------------------------------------------------------------
-/**
- * DEPRECATED: Import `PathInjectionQuery` instead.
- *
- * Configuration to find paths from sources to sinks that contain no normalization.
- */
-deprecated class PathNotNormalizedConfiguration extends TaintTracking::Configuration {
- PathNotNormalizedConfiguration() { this = "PathNotNormalizedConfiguration" }
-
- override predicate isSource(DataFlow::Node source) { source instanceof Source }
-
- override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
-
- override predicate isSanitizer(DataFlow::Node node) {
- node instanceof Sanitizer
- or
- node instanceof Path::PathNormalization
- }
-
- override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
- guard instanceof SanitizerGuard
- }
-}
-
-/**
- * DEPRECATED: Import `PathInjectionQuery` instead.
- *
- * Holds if there is a path injection from source to sink, where the (python) path is
- * not normalized.
- */
-deprecated predicate pathNotNormalized(CustomPathNode source, CustomPathNode sink) {
- any(PathNotNormalizedConfiguration config).hasFlowPath(source.asNode1(), sink.asNode1())
-}
-
-// ---------------------------------------------------------------------------
-// Case 2. The path is normalized at least once, but never checked afterwards.
-// ---------------------------------------------------------------------------
-/**
- * DEPRECATED: Import `PathInjectionQuery` instead.
- *
- * Configuration to find paths from sources to normalizations that contain no prior normalizations.
- */
-deprecated class FirstNormalizationConfiguration extends TaintTracking::Configuration {
- FirstNormalizationConfiguration() { this = "FirstNormalizationConfiguration" }
-
- override predicate isSource(DataFlow::Node source) { source instanceof Source }
-
- override predicate isSink(DataFlow::Node sink) { sink instanceof Path::PathNormalization }
-
- override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
-
- override predicate isSanitizerOut(DataFlow::Node node) { node instanceof Path::PathNormalization }
-
- override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
- guard instanceof SanitizerGuard
- }
-}
-
-/**
- * DEPRECATED: Import `PathInjectionQuery` instead.
- *
- * Configuration to find paths from normalizations to sinks that do not go through a check.
- */
-deprecated class NormalizedPathNotCheckedConfiguration extends TaintTracking2::Configuration {
- NormalizedPathNotCheckedConfiguration() { this = "NormalizedPathNotCheckedConfiguration" }
-
- override predicate isSource(DataFlow::Node source) { source instanceof Path::PathNormalization }
-
- override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
-
- override predicate isSanitizer(DataFlow::Node node) {
- node instanceof Path::SafeAccessCheck
- or
- node instanceof Sanitizer
- }
-
- override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
- guard instanceof SanitizerGuard
- }
-}
-
-/**
- * DEPRECATED: Import `PathInjectionQuery` instead.
- *
- * Holds if there is a path injection from source to sink, where the (python) path is
- * normalized at least once, but never checked afterwards.
- */
-deprecated predicate pathNotCheckedAfterNormalization(CustomPathNode source, CustomPathNode sink) {
- exists(
- FirstNormalizationConfiguration config, DataFlow::PathNode mid1, DataFlow2::PathNode mid2,
- NormalizedPathNotCheckedConfiguration config2
- |
- config.hasFlowPath(source.asNode1(), mid1) and
- config2.hasFlowPath(mid2, sink.asNode2()) and
- mid1.getNode().asCfgNode() = mid2.getNode().asCfgNode()
- )
-}
-
-// ---------------------------------------------------------------------------
-// Query: Either case 1 or case 2.
-// ---------------------------------------------------------------------------
-/**
- * DEPRECATED: Import `PathInjectionQuery` instead.
- *
- * Holds if there is a path injection from source to sink
- */
-deprecated predicate pathInjection(CustomPathNode source, CustomPathNode sink) {
- pathNotNormalized(source, sink)
- or
- pathNotCheckedAfterNormalization(source, sink)
-}
diff --git a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoS.qll b/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoS.qll
deleted file mode 100644
index 5454b889f03..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoS.qll
+++ /dev/null
@@ -1,10 +0,0 @@
-/** DEPRECATED. Import `PolynomialReDoSQuery` instead. */
-
-private import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `PolynomialReDoSQuery` instead. */
-deprecated module PolynomialReDoS {
- import PolynomialReDoSQuery // ignore-query-import
-}
diff --git a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSS.qll b/python/ql/lib/semmle/python/security/dataflow/ReflectedXSS.qll
deleted file mode 100644
index 2e481d25cf7..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSS.qll
+++ /dev/null
@@ -1,16 +0,0 @@
-/** DEPRECATED. Import `ReflectedXSSQuery` instead. */
-
-private import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `ReflectedXSSQuery` instead. */
-deprecated module ReflectedXss {
- import ReflectedXssQuery // ignore-query-import
-}
-
-/** DEPRECATED. Import `ReflectedXSSQuery` instead. */
-deprecated module ReflectedXSS = ReflectedXss;
-
-/** DEPRECATED. Import `ReflectedXSSQuery` instead. */
-deprecated class ReflectedXssConfiguration = ReflectedXss::Configuration;
diff --git a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll
index ea826c3b0c5..2229d0c758c 100644
--- a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll
+++ b/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll
@@ -76,6 +76,3 @@ module ReflectedXss {
*/
class StringConstCompareAsSanitizerGuard extends Sanitizer, StringConstCompareBarrier { }
}
-
-/** DEPRECATED: Alias for ReflectedXss */
-deprecated module ReflectedXSS = ReflectedXss;
diff --git a/python/ql/lib/semmle/python/security/dataflow/RegexInjection.qll b/python/ql/lib/semmle/python/security/dataflow/RegexInjection.qll
deleted file mode 100644
index decc9b00946..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/RegexInjection.qll
+++ /dev/null
@@ -1,10 +0,0 @@
-/** DEPRECATED. Import `RegexInjectionQuery` instead. */
-
-private import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `RegexInjectionQuery` instead. */
-deprecated module RegexInjection {
- import RegexInjectionQuery // ignore-query-import
-}
diff --git a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgery.qll b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgery.qll
deleted file mode 100644
index dd04ccf4cf5..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgery.qll
+++ /dev/null
@@ -1,25 +0,0 @@
-/** DEPRECATED. Import `ServerSideRequestForgeryQuery` instead. */
-
-private import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-import semmle.python.Concepts
-import ServerSideRequestForgeryQuery as ServerSideRequestForgeryQuery // ignore-query-import
-
-/** DEPRECATED. Import `ServerSideRequestForgeryQuery` instead. */
-deprecated module FullServerSideRequestForgery {
- import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery
-
- class Configuration = ServerSideRequestForgeryQuery::FullServerSideRequestForgeryConfiguration;
-}
-
-/** DEPRECATED. Import `ServerSideRequestForgeryQuery` instead. */
-deprecated predicate fullyControlledRequest =
- ServerSideRequestForgeryQuery::fullyControlledRequest/1;
-
-/** DEPRECATED. Import `ServerSideRequestForgeryQuery` instead. */
-deprecated module PartialServerSideRequestForgery {
- import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery
-
- class Configuration = ServerSideRequestForgeryQuery::PartialServerSideRequestForgeryConfiguration;
-}
diff --git a/python/ql/lib/semmle/python/security/dataflow/SqlInjection.qll b/python/ql/lib/semmle/python/security/dataflow/SqlInjection.qll
deleted file mode 100644
index eebe6251c22..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/SqlInjection.qll
+++ /dev/null
@@ -1,16 +0,0 @@
-/** DEPRECATED. Import `SqlInjectionQuery` instead. */
-
-private import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `SqlInjectionQuery` instead. */
-deprecated module SqlInjection {
- import SqlInjectionQuery // ignore-query-import
-}
-
-/** DEPRECATED. Import `SqlInjectionQuery` instead. */
-deprecated class SqlInjectionConfiguration = SqlInjection::Configuration;
-
-/** DEPRECATED. Import `SqlInjectionQuery` instead. */
-deprecated class SQLInjectionConfiguration = SqlInjectionConfiguration;
diff --git a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposure.qll b/python/ql/lib/semmle/python/security/dataflow/StackTraceExposure.qll
deleted file mode 100644
index 64e59756dff..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposure.qll
+++ /dev/null
@@ -1,13 +0,0 @@
-/** DEPRECATED. Import `StackTraceExposureQuery` instead. */
-
-private import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `StackTraceExposureQuery` instead. */
-deprecated module StackTraceExposure {
- import StackTraceExposureQuery // ignore-query-import
-}
-
-/** DEPRECATED. Import `StackTraceExposureQuery` instead. */
-deprecated class StackTraceExposureConfiguration = StackTraceExposure::Configuration;
diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserialization.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserialization.qll
deleted file mode 100644
index 3bdd569128d..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserialization.qll
+++ /dev/null
@@ -1,13 +0,0 @@
-/** DEPRECATED. Import `UnsafeDeserializationQuery` instead. */
-
-private import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `UnsafeDeserializationQuery` instead. */
-deprecated module UnsafeDeserialization {
- import UnsafeDeserializationQuery // ignore-query-import
-}
-
-/** DEPRECATED. Import `UnsafeDeserializationQuery` instead. */
-deprecated class UnsafeDeserializationConfiguration = UnsafeDeserialization::Configuration;
diff --git a/python/ql/lib/semmle/python/security/dataflow/UrlRedirect.qll b/python/ql/lib/semmle/python/security/dataflow/UrlRedirect.qll
deleted file mode 100644
index 4cb354eabf8..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/UrlRedirect.qll
+++ /dev/null
@@ -1,13 +0,0 @@
-/** DEPRECATED. Import `UrlRedirectQuery` instead. */
-
-private import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `UrlRedirectQuery` instead. */
-deprecated module UrlRedirect {
- import UrlRedirectQuery // ignore-query-import
-}
-
-/** DEPRECATED. Import `UrlRedirectQuery` instead. */
-deprecated class UrlRedirectConfiguration = UrlRedirect::Configuration;
diff --git a/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashing.qll b/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashing.qll
deleted file mode 100644
index 867b3bedd0b..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashing.qll
+++ /dev/null
@@ -1,19 +0,0 @@
-/** DEPRECATED. Import `WeakSensitiveDataHashingQuery` instead. */
-
-private import python
-private import semmle.python.dataflow.new.DataFlow
-private import semmle.python.dataflow.new.TaintTracking
-private import semmle.python.Concepts
-private import semmle.python.dataflow.new.RemoteFlowSources
-private import semmle.python.dataflow.new.BarrierGuards
-private import semmle.python.dataflow.new.SensitiveDataSources
-
-/** DEPRECATED. Import `WeakSensitiveDataHashingQuery` instead. */
-deprecated module NormalHashFunction {
- import WeakSensitiveDataHashingQuery::NormalHashFunction // ignore-query-import
-}
-
-/** DEPRECATED. Import `WeakSensitiveDataHashingQuery` instead. */
-deprecated module ComputationallyExpensiveHashFunction {
- import WeakSensitiveDataHashingQuery::ComputationallyExpensiveHashFunction // ignore-query-import
-}
diff --git a/python/ql/lib/semmle/python/security/dataflow/XpathInjection.qll b/python/ql/lib/semmle/python/security/dataflow/XpathInjection.qll
deleted file mode 100644
index 2ed69d035f9..00000000000
--- a/python/ql/lib/semmle/python/security/dataflow/XpathInjection.qll
+++ /dev/null
@@ -1,10 +0,0 @@
-/** DEPRECATED. Import `XpathInjectionQuery` instead. */
-
-private import python
-import semmle.python.dataflow.new.DataFlow
-import semmle.python.dataflow.new.TaintTracking
-
-/** DEPRECATED. Import `XpathInjectionQuery` instead. */
-deprecated module XpathInjection {
- import XpathInjectionQuery // ignore-query-import
-}
diff --git a/python/ql/lib/semmle/python/security/flow/AnyCall.qll b/python/ql/lib/semmle/python/security/flow/AnyCall.qll
deleted file mode 100644
index 6c93f3841b2..00000000000
--- a/python/ql/lib/semmle/python/security/flow/AnyCall.qll
+++ /dev/null
@@ -1,9 +0,0 @@
-import python
-import semmle.python.security.strings.Basic
-
-/** Assume that taint flows from argument to result for *any* call */
-deprecated class AnyCallStringFlow extends DataFlowExtension::DataFlowNode {
- AnyCallStringFlow() { any(CallNode call).getAnArg() = this }
-
- override ControlFlowNode getASuccessorNode() { result.(CallNode).getAnArg() = this }
-}
diff --git a/python/ql/lib/semmle/python/security/injection/Deserialization.qll b/python/ql/lib/semmle/python/security/injection/Deserialization.qll
deleted file mode 100644
index b516a2d6b2f..00000000000
--- a/python/ql/lib/semmle/python/security/injection/Deserialization.qll
+++ /dev/null
@@ -1,8 +0,0 @@
-import python
-import semmle.python.dataflow.TaintTracking
-
-/** `pickle.loads(untrusted)` vulnerability. */
-abstract deprecated class DeserializationSink extends TaintSink {
- bindingset[this]
- DeserializationSink() { this = this }
-}
diff --git a/python/ql/lib/semmle/python/security/injection/Exec.qll b/python/ql/lib/semmle/python/security/injection/Exec.qll
deleted file mode 100644
index 3ff84915ae0..00000000000
--- a/python/ql/lib/semmle/python/security/injection/Exec.qll
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Provides class and predicates to track external data that
- * may represent malicious Python code.
- *
- * This module is intended to be imported into a taint-tracking query
- * to extend `TaintKind` and `TaintSink`.
- */
-
-import python
-import semmle.python.dataflow.TaintTracking
-import semmle.python.security.strings.Untrusted
-
-/**
- * A taint sink that represents an argument to exec or eval that is vulnerable to malicious input.
- * The `vuln` in `exec(vuln)` or similar.
- */
-deprecated class StringEvaluationNode extends TaintSink {
- override string toString() { result = "exec or eval" }
-
- StringEvaluationNode() {
- exists(Exec exec | exec.getASubExpression().getAFlowNode() = this)
- or
- Value::named("exec").getACall().getAnArg() = this
- or
- Value::named("eval").getACall().getAnArg() = this
- }
-
- override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
-}
diff --git a/python/ql/lib/semmle/python/security/injection/Marshal.qll b/python/ql/lib/semmle/python/security/injection/Marshal.qll
deleted file mode 100644
index 815890903bd..00000000000
--- a/python/ql/lib/semmle/python/security/injection/Marshal.qll
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Provides class and predicates to track external data that
- * may represent malicious marshals.
- *
- * This module is intended to be imported into a taint-tracking query
- * to extend `TaintKind` and `TaintSink`.
- */
-
-import python
-import semmle.python.dataflow.TaintTracking
-import semmle.python.security.strings.Untrusted
-import semmle.python.security.injection.Deserialization
-
-deprecated private FunctionObject marshalLoads() {
- result = ModuleObject::named("marshal").attr("loads")
-}
-
-/**
- * A taint sink that is potentially vulnerable to malicious marshaled objects.
- * The `vuln` in `marshal.loads(vuln)`.
- */
-deprecated class UnmarshalingNode extends DeserializationSink {
- override string toString() { result = "unmarshaling vulnerability" }
-
- UnmarshalingNode() {
- exists(CallNode call |
- marshalLoads().getACall() = call and
- call.getAnArg() = this
- )
- }
-
- override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
-}
diff --git a/python/ql/lib/semmle/python/security/injection/Path.qll b/python/ql/lib/semmle/python/security/injection/Path.qll
deleted file mode 100644
index 73d76104493..00000000000
--- a/python/ql/lib/semmle/python/security/injection/Path.qll
+++ /dev/null
@@ -1,81 +0,0 @@
-import python
-import semmle.python.dataflow.TaintTracking
-import semmle.python.security.strings.Untrusted
-
-/**
- * Prevents taint flowing through ntpath.normpath()
- * NormalizedPath below handles that case.
- */
-deprecated class PathSanitizer extends Sanitizer {
- PathSanitizer() { this = "path.sanitizer" }
-
- override predicate sanitizingNode(TaintKind taint, ControlFlowNode node) {
- taint instanceof ExternalStringKind and
- abspath_call(node, _)
- }
-}
-
-deprecated private FunctionObject abspath() {
- exists(ModuleObject os_path | ModuleObject::named("os").attr("path") = os_path |
- os_path.attr("abspath") = result
- or
- os_path.attr("normpath") = result
- )
-}
-
-/** A path that has been normalized, but not verified to be safe */
-deprecated class NormalizedPath extends TaintKind {
- NormalizedPath() { this = "normalized.path.injection" }
-
- override string repr() { result = "normalized path" }
-}
-
-deprecated private predicate abspath_call(CallNode call, ControlFlowNode arg) {
- call.getFunction().refersTo(abspath()) and
- arg = call.getArg(0)
-}
-
-deprecated class AbsPath extends DataFlowExtension::DataFlowNode {
- AbsPath() { abspath_call(_, this) }
-
- override ControlFlowNode getASuccessorNode(TaintKind fromkind, TaintKind tokind) {
- abspath_call(result, this) and
- tokind instanceof NormalizedPath and
- fromkind instanceof ExternalStringKind
- }
-}
-
-deprecated class NormalizedPathSanitizer extends Sanitizer {
- NormalizedPathSanitizer() { this = "normalized.path.sanitizer" }
-
- override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
- taint instanceof NormalizedPath and
- test.getTest().(CallNode).getFunction().(AttrNode).getName() = "startswith" and
- test.getSense() = true
- }
-}
-
-/**
- * A taint sink that is vulnerable to malicious paths.
- * The `vuln` in `open(vuln)` and similar.
- */
-deprecated class OpenNode extends TaintSink {
- override string toString() { result = "argument to open()" }
-
- OpenNode() {
- exists(CallNode call |
- call = Value::named("open").getACall() and
- (
- call.getArg(0) = this
- or
- call.getArgByName("file") = this
- )
- )
- }
-
- override predicate sinks(TaintKind kind) {
- kind instanceof ExternalStringKind
- or
- kind instanceof NormalizedPath
- }
-}
diff --git a/python/ql/lib/semmle/python/security/injection/Pickle.qll b/python/ql/lib/semmle/python/security/injection/Pickle.qll
deleted file mode 100644
index 621eccbd6ce..00000000000
--- a/python/ql/lib/semmle/python/security/injection/Pickle.qll
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Provides class and predicates to track external data that
- * may represent malicious pickles.
- *
- * This module is intended to be imported into a taint-tracking query
- * to extend `TaintKind` and `TaintSink`.
- */
-
-import python
-import semmle.python.dataflow.TaintTracking
-import semmle.python.security.strings.Untrusted
-import semmle.python.security.injection.Deserialization
-
-deprecated private ModuleObject pickleModule() {
- result.getName() = "pickle"
- or
- result.getName() = "cPickle"
- or
- result.getName() = "dill"
-}
-
-deprecated private FunctionObject pickleLoads() { result = pickleModule().attr("loads") }
-
-/** `pickle.loads(untrusted)` vulnerability. */
-deprecated class UnpicklingNode extends DeserializationSink {
- override string toString() { result = "unpickling untrusted data" }
-
- UnpicklingNode() {
- exists(CallNode call |
- pickleLoads().getACall() = call and
- call.getAnArg() = this
- )
- }
-
- override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
-}
diff --git a/python/ql/lib/semmle/python/security/injection/RegexInjection.qll b/python/ql/lib/semmle/python/security/injection/RegexInjection.qll
deleted file mode 100644
index c0c0f42dbd6..00000000000
--- a/python/ql/lib/semmle/python/security/injection/RegexInjection.qll
+++ /dev/null
@@ -1,6 +0,0 @@
-/** DEPRECATED: use semmle.python.security.dataflow.RegexInjection instead. */
-
-private import semmle.python.security.dataflow.RegexInjection as New
-
-/** DEPRECATED: use semmle.python.security.dataflow.RegexInjection instead. */
-deprecated module RegexInjection = New::RegexInjection;
diff --git a/python/ql/lib/semmle/python/security/injection/RegexInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/injection/RegexInjectionCustomizations.qll
deleted file mode 100644
index 0738f2b58b6..00000000000
--- a/python/ql/lib/semmle/python/security/injection/RegexInjectionCustomizations.qll
+++ /dev/null
@@ -1,6 +0,0 @@
-/** DEPRECATED: use semmle.python.security.dataflow.RegexInjectionCustomizations instead. */
-
-private import semmle.python.security.dataflow.RegexInjectionCustomizations as New
-
-/** DEPRECATED: use semmle.python.security.dataflow.RegexInjectionCustomizations instead. */
-deprecated module RegexInjection = New::RegexInjection;
diff --git a/python/ql/lib/semmle/python/security/injection/Xml.qll b/python/ql/lib/semmle/python/security/injection/Xml.qll
deleted file mode 100644
index 6f61e0a5ef5..00000000000
--- a/python/ql/lib/semmle/python/security/injection/Xml.qll
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * Provides class and predicates to track external data that
- * may represent malicious XML objects.
- *
- * This module is intended to be imported into a taint-tracking query
- * to extend `TaintKind` and `TaintSink`.
- */
-
-import python
-import semmle.python.dataflow.TaintTracking
-import semmle.python.security.strings.Untrusted
-import semmle.python.security.injection.Deserialization
-
-deprecated private ModuleObject xmlElementTreeModule() {
- result.getName() = "xml.etree.ElementTree"
-}
-
-deprecated private ModuleObject xmlMiniDomModule() { result.getName() = "xml.dom.minidom" }
-
-deprecated private ModuleObject xmlPullDomModule() { result.getName() = "xml.dom.pulldom" }
-
-deprecated private ModuleObject xmlSaxModule() { result.getName() = "xml.sax" }
-
-deprecated private class ExpatParser extends TaintKind {
- ExpatParser() { this = "expat.parser" }
-}
-
-deprecated private FunctionObject expatCreateParseFunction() {
- result = ModuleObject::named("xml.parsers.expat").attr("ParserCreate")
-}
-
-deprecated private class ExpatCreateParser extends TaintSource {
- ExpatCreateParser() { expatCreateParseFunction().getACall() = this }
-
- override predicate isSourceOf(TaintKind kind) { kind instanceof ExpatParser }
-
- override string toString() { result = "expat.create.parser" }
-}
-
-deprecated private FunctionObject xmlFromString() {
- result = xmlElementTreeModule().attr("fromstring")
- or
- result = xmlMiniDomModule().attr("parseString")
- or
- result = xmlPullDomModule().attr("parseString")
- or
- result = xmlSaxModule().attr("parseString")
-}
-
-/** A (potentially) malicious XML string. */
-deprecated class ExternalXmlString extends ExternalStringKind {
- ExternalXmlString() { this = "external xml encoded object" }
-}
-
-/**
- * A call to an XML library function that is potentially vulnerable to a
- * specially crafted XML string.
- */
-deprecated class XmlLoadNode extends DeserializationSink {
- override string toString() { result = "xml.load vulnerability" }
-
- XmlLoadNode() {
- exists(CallNode call | call.getAnArg() = this |
- xmlFromString().getACall() = call or
- any(ExpatParser parser).taints(call.getFunction().(AttrNode).getObject("Parse"))
- )
- }
-
- override predicate sinks(TaintKind kind) { kind instanceof ExternalXmlString }
-}
diff --git a/python/ql/lib/semmle/python/security/injection/Yaml.qll b/python/ql/lib/semmle/python/security/injection/Yaml.qll
deleted file mode 100644
index 585552442f7..00000000000
--- a/python/ql/lib/semmle/python/security/injection/Yaml.qll
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * Provides class and predicates to track external data that
- * may represent malicious yaml-encoded objects.
- *
- * This module is intended to be imported into a taint-tracking query
- * to extend `TaintKind` and `TaintSink`.
- */
-
-import python
-import semmle.python.dataflow.TaintTracking
-import semmle.python.security.strings.Untrusted
-import semmle.python.security.injection.Deserialization
-
-deprecated private FunctionObject yamlLoad() { result = ModuleObject::named("yaml").attr("load") }
-
-/** `yaml.load(untrusted)` vulnerability. */
-deprecated class YamlLoadNode extends DeserializationSink {
- override string toString() { result = "yaml.load vulnerability" }
-
- YamlLoadNode() {
- exists(CallNode call |
- yamlLoad().getACall() = call and
- call.getAnArg() = this
- )
- }
-
- override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
-}
diff --git a/python/ql/lib/semmle/python/types/Extensions.qll b/python/ql/lib/semmle/python/types/Extensions.qll
index 8b5b357723f..f6c824f9ab2 100644
--- a/python/ql/lib/semmle/python/types/Extensions.qll
+++ b/python/ql/lib/semmle/python/types/Extensions.qll
@@ -14,7 +14,6 @@ import python
private import semmle.python.pointsto.PointsTo
private import semmle.python.pointsto.PointsToContext
private import semmle.python.objects.TObject
-private import semmle.python.web.HttpConstants
/* Make ObjectInternal visible to save extra imports in user code */
import semmle.python.objects.ObjectInternal
@@ -52,30 +51,6 @@ class RangeIterationVariableFact extends PointsToExtension {
}
}
-/* bottle module route constants */
-deprecated class BottleRoutePointToExtension extends PointsToExtension {
- string name;
-
- BottleRoutePointToExtension() {
- exists(DefinitionNode defn |
- defn.getScope().(Module).getName() = "bottle" and
- this = defn.getValue() and
- name = defn.(NameNode).getId()
- |
- name = "route" or
- name = httpVerbLower()
- )
- }
-
- override predicate pointsTo(Context context, ObjectInternal value, ControlFlowNode origin) {
- context.isImport() and
- exists(CfgOrigin orig |
- Module::named("bottle").attr("Bottle").(ClassObjectInternal).attribute(name, value, orig) and
- origin = orig.asCfgNodeOrHere(this)
- )
- }
-}
-
/* Python 3.6+ regex module constants */
string short_flag(string flag) {
flag in ["ASCII", "IGNORECASE", "LOCALE", "UNICODE", "MULTILINE", "TEMPLATE"] and
diff --git a/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll b/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll
index bdf55bfc4f2..766cf6845af 100644
--- a/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll
+++ b/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll
@@ -33,9 +33,6 @@ class SafeExternalApi extends Unit {
DataFlowPrivate::DataFlowCallable getSafeCallable() { none() }
}
-/** DEPRECATED: Alias for SafeExternalApi */
-deprecated class SafeExternalAPI = SafeExternalApi;
-
/** The default set of "safe" external APIs. */
private class DefaultSafeExternalApi extends SafeExternalApi {
override DataFlow::CallCfgNode getSafeCall() {
@@ -170,9 +167,6 @@ class ExternalApiDataNode extends DataFlow::Node {
}
}
-/** DEPRECATED: Alias for ExternalApiDataNode */
-deprecated class ExternalAPIDataNode = ExternalApiDataNode;
-
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */
class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration {
UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" }
@@ -182,9 +176,6 @@ class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }
}
-/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */
-deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig;
-
/** A node representing untrusted data being passed to an external API. */
class UntrustedExternalApiDataNode extends ExternalApiDataNode {
UntrustedExternalApiDataNode() { any(UntrustedDataToExternalApiConfig c).hasFlow(_, this) }
@@ -195,9 +186,6 @@ class UntrustedExternalApiDataNode extends ExternalApiDataNode {
}
}
-/** DEPRECATED: Alias for UntrustedExternalApiDataNode */
-deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode;
-
/** An external API which is used with untrusted data. */
private newtype TExternalApi =
MkExternalApi(string repr, DataFlowPrivate::ArgumentPosition apos) {
@@ -230,6 +218,3 @@ class ExternalApiUsedWithUntrustedData extends MkExternalApi {
/** Gets a textual representation of this element. */
string toString() { result = repr + " [" + apos + "]" }
}
-
-/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */
-deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData;
diff --git a/python/ql/src/experimental/semmle/python/Concepts.qll b/python/ql/src/experimental/semmle/python/Concepts.qll
index 65f1e0d8e01..3331e1117e0 100644
--- a/python/ql/src/experimental/semmle/python/Concepts.qll
+++ b/python/ql/src/experimental/semmle/python/Concepts.qll
@@ -90,9 +90,6 @@ module LdapQuery {
}
}
-/** DEPRECATED: Alias for LdapQuery */
-deprecated module LDAPQuery = LdapQuery;
-
/**
* A data-flow node that collect methods executing a LDAP query.
*
@@ -106,9 +103,6 @@ class LdapQuery extends DataFlow::Node instanceof LdapQuery::Range {
DataFlow::Node getQuery() { result = super.getQuery() }
}
-/** DEPRECATED: Alias for LdapQuery */
-deprecated class LDAPQuery = LdapQuery;
-
/** Provides classes for modeling LDAP components escape-related APIs. */
module LdapEscape {
/**
@@ -125,9 +119,6 @@ module LdapEscape {
}
}
-/** DEPRECATED: Alias for LdapEscape */
-deprecated module LDAPEscape = LdapEscape;
-
/**
* A data-flow node that collects functions escaping LDAP components.
*
@@ -141,9 +132,6 @@ class LdapEscape extends DataFlow::Node instanceof LdapEscape::Range {
DataFlow::Node getAnInput() { result = super.getAnInput() }
}
-/** DEPRECATED: Alias for LdapEscape */
-deprecated class LDAPEscape = LdapEscape;
-
/** Provides classes for modeling LDAP bind-related APIs. */
module LdapBind {
/**
@@ -173,9 +161,6 @@ module LdapBind {
}
}
-/** DEPRECATED: Alias for LdapBind */
-deprecated module LDAPBind = LdapBind;
-
/**
* A data-flow node that collects methods binding a LDAP connection.
*
@@ -202,9 +187,6 @@ class LdapBind extends DataFlow::Node instanceof LdapBind::Range {
deprecated predicate useSSL() { this.useSsl() }
}
-/** DEPRECATED: Alias for LdapBind */
-deprecated class LDAPBind = LdapBind;
-
/** Provides classes for modeling SQL sanitization libraries. */
module SqlEscape {
/**
@@ -221,9 +203,6 @@ module SqlEscape {
}
}
-/** DEPRECATED: Alias for SqlEscape */
-deprecated module SQLEscape = SqlEscape;
-
/**
* A data-flow node that collects functions escaping SQL statements.
*
@@ -237,9 +216,6 @@ class SqlEscape extends DataFlow::Node instanceof SqlEscape::Range {
DataFlow::Node getAnInput() { result = super.getAnInput() }
}
-/** DEPRECATED: Alias for SqlEscape */
-deprecated class SQLEscape = SqlEscape;
-
/** Provides a class for modeling NoSql execution APIs. */
module NoSqlQuery {
/**
@@ -254,9 +230,6 @@ module NoSqlQuery {
}
}
-/** DEPRECATED: Alias for NoSqlQuery */
-deprecated module NoSQLQuery = NoSqlQuery;
-
/**
* A data-flow node that executes NoSQL queries.
*
@@ -268,9 +241,6 @@ class NoSqlQuery extends DataFlow::Node instanceof NoSqlQuery::Range {
DataFlow::Node getQuery() { result = super.getQuery() }
}
-/** DEPRECATED: Alias for NoSqlQuery */
-deprecated class NoSQLQuery = NoSqlQuery;
-
/** Provides classes for modeling NoSql sanitization-related APIs. */
module NoSqlSanitizer {
/**
@@ -285,9 +255,6 @@ module NoSqlSanitizer {
}
}
-/** DEPRECATED: Alias for NoSqlSanitizer */
-deprecated module NoSQLSanitizer = NoSqlSanitizer;
-
/**
* A data-flow node that collects functions sanitizing NoSQL queries.
*
@@ -299,9 +266,6 @@ class NoSqlSanitizer extends DataFlow::Node instanceof NoSqlSanitizer::Range {
DataFlow::Node getAnInput() { result = super.getAnInput() }
}
-/** DEPRECATED: Alias for NoSqlSanitizer */
-deprecated class NoSQLSanitizer = NoSqlSanitizer;
-
/** Provides classes for modeling HTTP Header APIs. */
module HeaderDeclaration {
/**
@@ -450,9 +414,6 @@ module JwtEncoding {
}
}
-/** DEPRECATED: Alias for JwtEncoding */
-deprecated module JWTEncoding = JwtEncoding;
-
/**
* A data-flow node that collects methods encoding a JWT token.
*
@@ -481,9 +442,6 @@ class JwtEncoding extends DataFlow::Node instanceof JwtEncoding::Range {
string getAlgorithmString() { result = super.getAlgorithmString() }
}
-/** DEPRECATED: Alias for JwtEncoding */
-deprecated class JWTEncoding = JwtEncoding;
-
/** Provides classes for modeling JWT decoding-related APIs. */
module JwtDecoding {
/**
@@ -525,9 +483,6 @@ module JwtDecoding {
}
}
-/** DEPRECATED: Alias for JwtDecoding */
-deprecated module JWTDecoding = JwtDecoding;
-
/**
* A data-flow node that collects methods encoding a JWT token.
*
@@ -566,9 +521,6 @@ class JwtDecoding extends DataFlow::Node instanceof JwtDecoding::Range {
predicate verifiesSignature() { super.verifiesSignature() }
}
-/** DEPRECATED: Alias for JwtDecoding */
-deprecated class JWTDecoding = JwtDecoding;
-
/** Provides classes for modeling Email APIs. */
module EmailSender {
/**
diff --git a/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll b/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll
index dbe1cbe4117..56fffe3a2a0 100644
--- a/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll
+++ b/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll
@@ -29,23 +29,14 @@ class LdapFullHost extends StrConst {
}
}
-/** DEPRECATED: Alias for LdapFullHost */
-deprecated class LDAPFullHost = LdapFullHost;
-
class LdapSchema extends StrConst {
LdapSchema() { this.getText().regexpMatch(getSchemaRegex()) }
}
-/** DEPRECATED: Alias for LdapSchema */
-deprecated class LDAPSchema = LdapSchema;
-
class LdapPrivateHost extends StrConst {
LdapPrivateHost() { this.getText().regexpMatch(getPrivateHostRegex()) }
}
-/** DEPRECATED: Alias for LdapPrivateHost */
-deprecated class LDAPPrivateHost = LdapPrivateHost;
-
predicate concatAndCompareAgainstFullHostRegex(LdapSchema schema, StrConst host) {
not host instanceof LdapPrivateHost and
(schema.getText() + host.getText()).regexpMatch(getFullHostRegex())
@@ -56,9 +47,6 @@ class LdapBothStrings extends BinaryExpr {
LdapBothStrings() { concatAndCompareAgainstFullHostRegex(this.getLeft(), this.getRight()) }
}
-/** DEPRECATED: Alias for LdapBothStrings */
-deprecated class LDAPBothStrings = LdapBothStrings;
-
// schema + host
class LdapBothVar extends BinaryExpr {
LdapBothVar() {
@@ -73,9 +61,6 @@ class LdapBothVar extends BinaryExpr {
}
}
-/** DEPRECATED: Alias for LdapBothVar */
-deprecated class LDAPBothVar = LdapBothVar;
-
// schema + "somethingon.theinternet.com"
class LdapVarString extends BinaryExpr {
LdapVarString() {
@@ -89,9 +74,6 @@ class LdapVarString extends BinaryExpr {
}
}
-/** DEPRECATED: Alias for LdapVarString */
-deprecated class LDAPVarString = LdapVarString;
-
// "ldap://" + host
class LdapStringVar extends BinaryExpr {
LdapStringVar() {
@@ -103,9 +85,6 @@ class LdapStringVar extends BinaryExpr {
}
}
-/** DEPRECATED: Alias for LdapStringVar */
-deprecated class LDAPStringVar = LdapStringVar;
-
/**
* A taint-tracking configuration for detecting LDAP insecure authentications.
*/
@@ -125,6 +104,3 @@ class LdapInsecureAuthConfig extends TaintTracking::Configuration {
exists(LdapBind ldapBind | not ldapBind.useSsl() and sink = ldapBind.getHost())
}
}
-
-/** DEPRECATED: Alias for LdapInsecureAuthConfig */
-deprecated class LDAPInsecureAuthConfig = LdapInsecureAuthConfig;
diff --git a/python/ql/src/experimental/semmle/python/security/injection/NoSQLInjection.qll b/python/ql/src/experimental/semmle/python/security/injection/NoSQLInjection.qll
index e6f3832e4ff..f7a40fb3ee6 100644
--- a/python/ql/src/experimental/semmle/python/security/injection/NoSQLInjection.qll
+++ b/python/ql/src/experimental/semmle/python/security/injection/NoSQLInjection.qll
@@ -52,6 +52,3 @@ module NoSqlInjection {
ConvertedToDict() { this = "ConvertedToDict" }
}
}
-
-/** DEPRECATED: Alias for NoSqlInjection */
-deprecated module NoSQLInjection = NoSqlInjection;
diff --git a/python/ql/test/library-tests/security/sensitive/Sources.expected b/python/ql/test/library-tests/security/sensitive/Sources.expected
deleted file mode 100644
index 4500a2c23a5..00000000000
--- a/python/ql/test/library-tests/security/sensitive/Sources.expected
+++ /dev/null
@@ -1,6 +0,0 @@
-WARNING: Module SensitiveData has been deprecated and may be removed in future (Sources.ql:4,6-19)
-| test.py:16:1:16:14 | test.py:16 | a call returning a password |
-| test.py:17:1:17:12 | test.py:17 | a call returning a password |
-| test.py:18:1:18:12 | test.py:18 | a call returning a secret |
-| test.py:19:1:19:19 | test.py:19 | a call returning a certificate or key |
-| test.py:20:1:20:12 | test.py:20 | a call returning an ID |
diff --git a/python/ql/test/library-tests/security/sensitive/Sources.ql b/python/ql/test/library-tests/security/sensitive/Sources.ql
deleted file mode 100644
index b5328a9f105..00000000000
--- a/python/ql/test/library-tests/security/sensitive/Sources.ql
+++ /dev/null
@@ -1,5 +0,0 @@
-import python
-import semmle.python.security.SensitiveData
-
-from SensitiveData::Source src
-select src.getLocation(), src.repr()
diff --git a/python/ql/test/library-tests/security/sensitive/test.py b/python/ql/test/library-tests/security/sensitive/test.py
deleted file mode 100644
index bd5aaf238d8..00000000000
--- a/python/ql/test/library-tests/security/sensitive/test.py
+++ /dev/null
@@ -1,21 +0,0 @@
-
-from not_found import get_passwd, account_id
-
-def get_password():
- pass
-
-def get_secret():
- pass
-
-def fetch_certificate():
- pass
-
-def encrypt_password(pwd):
- pass
-
-get_password()
-get_passwd()
-get_secret()
-fetch_certificate()
-account_id()
-safe_to_store = encrypt_password(pwd)
diff --git a/python/ql/test/library-tests/web/bottle/HttpResponseSinks.expected b/python/ql/test/library-tests/web/bottle/HttpResponseSinks.expected
deleted file mode 100644
index 196468fd4c1..00000000000
--- a/python/ql/test/library-tests/web/bottle/HttpResponseSinks.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27)
-| test.py:9:12:9:26 | bottle handler function result | externally controlled string |
-| test.py:13:12:13:24 | bottle handler function result | externally controlled string |
-| test.py:19:12:19:33 | bottle handler function result | externally controlled string |
-| test.py:36:21:36:51 | Taint sink | externally controlled string |
diff --git a/python/ql/test/library-tests/web/bottle/HttpResponseSinks.ql b/python/ql/test/library-tests/web/bottle/HttpResponseSinks.ql
deleted file mode 100644
index e62ec486da6..00000000000
--- a/python/ql/test/library-tests/web/bottle/HttpResponseSinks.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from HttpResponseTaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/bottle/HttpSources.expected b/python/ql/test/library-tests/web/bottle/HttpSources.expected
deleted file mode 100644
index 63d149e955a..00000000000
--- a/python/ql/test/library-tests/web/bottle/HttpSources.expected
+++ /dev/null
@@ -1,9 +0,0 @@
-WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28)
-| ../../../query-tests/Security/lib/bottle.py:64:11:64:24 | LocalRequest() | bottle.request |
-| test.py:3:35:3:41 | ImportMember | bottle.request |
-| test.py:8:11:8:14 | name | externally controlled string |
-| test.py:12:9:12:12 | name | externally controlled string |
-| test.py:18:12:18:18 | request | bottle.request |
-| test.py:27:12:27:16 | where | externally controlled string |
-| test.py:32:14:32:20 | request | bottle.request |
-| test.py:36:34:36:40 | request | bottle.request |
diff --git a/python/ql/test/library-tests/web/bottle/HttpSources.ql b/python/ql/test/library-tests/web/bottle/HttpSources.ql
deleted file mode 100644
index 6fa1a7d2a6b..00000000000
--- a/python/ql/test/library-tests/web/bottle/HttpSources.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.security.strings.Untrusted
-
-from HttpRequestTaintSource source, TaintKind kind
-where source.isSourceOf(kind)
-select source.(ControlFlowNode).getNode(), kind
diff --git a/python/ql/test/library-tests/web/bottle/Routing.expected b/python/ql/test/library-tests/web/bottle/Routing.expected
deleted file mode 100644
index d07889879a3..00000000000
--- a/python/ql/test/library-tests/web/bottle/Routing.expected
+++ /dev/null
@@ -1,8 +0,0 @@
-WARNING: Type BottleRoute has been deprecated and may be removed in future (Routing.ql:4,6-17)
-| /args | test.py:31:1:31:14 | Function unsafe2 |
-| /bye/ | test.py:12:1:12:25 | Function bye |
-| /hello/ | test.py:8:1:8:27 | Function hello |
-| /other | test.py:17:1:17:12 | Function other |
-| /wrong/ | test.py:27:1:27:31 | Function unsafe |
-| /wrong/url | test.py:23:1:23:11 | Function safe |
-| /xss | test.py:35:1:35:16 | Function maybe_xss |
diff --git a/python/ql/test/library-tests/web/bottle/Routing.ql b/python/ql/test/library-tests/web/bottle/Routing.ql
deleted file mode 100644
index 988b8398f04..00000000000
--- a/python/ql/test/library-tests/web/bottle/Routing.ql
+++ /dev/null
@@ -1,5 +0,0 @@
-import python
-import semmle.python.web.bottle.General
-
-from BottleRoute route
-select route.getUrl(), route.getFunction()
diff --git a/python/ql/test/library-tests/web/bottle/Taint.expected b/python/ql/test/library-tests/web/bottle/Taint.expected
deleted file mode 100644
index 451b1ee3e00..00000000000
--- a/python/ql/test/library-tests/web/bottle/Taint.expected
+++ /dev/null
@@ -1,23 +0,0 @@
-| ../../../query-tests/Security/lib/bottle.py:64 | LocalRequest() | bottle.request |
-| ../../../query-tests/Security/lib/bottle.py:68 | url | externally controlled string |
-| test.py:3 | ImportMember | bottle.request |
-| test.py:8 | name | externally controlled string |
-| test.py:9 | BinaryExpr | externally controlled string |
-| test.py:9 | name | externally controlled string |
-| test.py:12 | name | externally controlled string |
-| test.py:13 | BinaryExpr | externally controlled string |
-| test.py:13 | name | externally controlled string |
-| test.py:18 | Attribute | bottle.FormsDict |
-| test.py:18 | Attribute | externally controlled string |
-| test.py:18 | request | bottle.request |
-| test.py:19 | BinaryExpr | externally controlled string |
-| test.py:19 | name | externally controlled string |
-| test.py:27 | where | externally controlled string |
-| test.py:28 | where | externally controlled string |
-| test.py:32 | Attribute | bottle.FormsDict |
-| test.py:32 | Attribute | externally controlled string |
-| test.py:32 | request | bottle.request |
-| test.py:36 | Attribute | bottle.FormsDict |
-| test.py:36 | Attribute | externally controlled string |
-| test.py:36 | BinaryExpr | externally controlled string |
-| test.py:36 | request | bottle.request |
diff --git a/python/ql/test/library-tests/web/bottle/Taint.ql b/python/ql/test/library-tests/web/bottle/Taint.ql
deleted file mode 100644
index 09972af5f98..00000000000
--- a/python/ql/test/library-tests/web/bottle/Taint.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from TaintedNode node
-select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind()
diff --git a/python/ql/test/library-tests/web/bottle/options b/python/ql/test/library-tests/web/bottle/options
deleted file mode 100644
index 7fb713d5924..00000000000
--- a/python/ql/test/library-tests/web/bottle/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: --max-import-depth=3 -p ../../../query-tests/Security/lib/
diff --git a/python/ql/test/library-tests/web/bottle/test.py b/python/ql/test/library-tests/web/bottle/test.py
deleted file mode 100644
index 8975de72ea4..00000000000
--- a/python/ql/test/library-tests/web/bottle/test.py
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-from bottle import Bottle, route, request, redirect, response
-
-app = Bottle()
-
-@app.route('/hello/')
-def hello(name = "World!"):
- return "Hello " + name
-
-@route('/bye/')
-def bye(name = "World!"):
- return "Bye " + name
-
-
-@route('/other')
-def other():
- name = request.cookies.username
- return "User name is " + name
-
-
-@route('/wrong/url')
-def safe():
- redirect("/right/url")
-
-@route('/wrong/')
-def unsafe(where="/right/url"):
- redirect(where)
-
-@route('/args')
-def unsafe2():
- redirect(request.query.where, code)
-
-@route('/xss')
-def maybe_xss():
- response.body = "name is " + request.query.name
diff --git a/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.expected b/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.expected
deleted file mode 100644
index d45cfd65989..00000000000
--- a/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27)
-| red.py:8:16:8:20 | cherrypy handler function result | externally controlled string |
-| test.py:11:16:11:29 | cherrypy handler function result | externally controlled string |
-| test.py:17:16:17:27 | cherrypy handler function result | externally controlled string |
diff --git a/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.ql b/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.ql
deleted file mode 100644
index e62ec486da6..00000000000
--- a/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from HttpResponseTaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/cherrypy/HttpSources.expected b/python/ql/test/library-tests/web/cherrypy/HttpSources.expected
deleted file mode 100644
index e0d1d7c4e59..00000000000
--- a/python/ql/test/library-tests/web/cherrypy/HttpSources.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28)
-| ../../../query-tests/Security/lib/cherrypy/__init__.py:10:11:10:38 | _ThreadLocalProxy() | cherrypy.request |
-| test.py:10:17:10:19 | arg | externally controlled string |
-| test.py:16:17:16:19 | arg | externally controlled string |
diff --git a/python/ql/test/library-tests/web/cherrypy/HttpSources.ql b/python/ql/test/library-tests/web/cherrypy/HttpSources.ql
deleted file mode 100644
index 6fa1a7d2a6b..00000000000
--- a/python/ql/test/library-tests/web/cherrypy/HttpSources.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.security.strings.Untrusted
-
-from HttpRequestTaintSource source, TaintKind kind
-where source.isSourceOf(kind)
-select source.(ControlFlowNode).getNode(), kind
diff --git a/python/ql/test/library-tests/web/cherrypy/options b/python/ql/test/library-tests/web/cherrypy/options
deleted file mode 100644
index 7fb713d5924..00000000000
--- a/python/ql/test/library-tests/web/cherrypy/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: --max-import-depth=3 -p ../../../query-tests/Security/lib/
diff --git a/python/ql/test/library-tests/web/cherrypy/red.py b/python/ql/test/library-tests/web/cherrypy/red.py
deleted file mode 100644
index 5fa25b5aa0f..00000000000
--- a/python/ql/test/library-tests/web/cherrypy/red.py
+++ /dev/null
@@ -1,11 +0,0 @@
-
-import cherrypy
-
-class MultiPath(object):
-
- @cherrypy.expose(['color', 'colour'])
- def red(self):
- return "RED"
-
-if __name__ == '__main__':
- cherrypy.quickstart(MultiPath())
diff --git a/python/ql/test/library-tests/web/cherrypy/test.py b/python/ql/test/library-tests/web/cherrypy/test.py
deleted file mode 100644
index 5d44b54077b..00000000000
--- a/python/ql/test/library-tests/web/cherrypy/test.py
+++ /dev/null
@@ -1,23 +0,0 @@
-
-import random
-import string
-
-import cherrypy
-
-class A(object):
-
- @cherrypy.expose
- def a(self, arg):
- return "hello " + arg
-
-class B(object):
-
- @cherrypy.expose
- def b(self, arg):
- return "bye " + arg
-
-cherrypy.tree.mount(A(), '/a', a_conf)
-cherrypy.tree.mount(B(), '/b', b_conf)
-
-cherrypy.engine.start()
-cherrypy.engine.block()
\ No newline at end of file
diff --git a/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.expected b/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.expected
deleted file mode 100644
index fa93ffe7e88..00000000000
--- a/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.expected
+++ /dev/null
@@ -1,3 +0,0 @@
-WARNING: Module Client has been deprecated and may be removed in future (ClientHttpRequests.ql:5,6-12)
-| test.py:3:1:3:27 | ControlFlowNode for Attribute() | test.py:3:14:3:26 | ControlFlowNode for Str | GET |
-| test.py:4:1:4:28 | ControlFlowNode for Attribute() | test.py:4:15:4:27 | ControlFlowNode for Str | POST |
diff --git a/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.ql b/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.ql
deleted file mode 100644
index 52fd7ff218e..00000000000
--- a/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.Http
-import semmle.python.web.ClientHttpRequest
-
-from Client::HttpRequest req, string method
-where if exists(req.getMethodUpper()) then method = req.getMethodUpper() else method = ""
-select req, req.getAUrlPart(), method
diff --git a/python/ql/test/library-tests/web/client/requests/options b/python/ql/test/library-tests/web/client/requests/options
deleted file mode 100644
index f1858a6caf9..00000000000
--- a/python/ql/test/library-tests/web/client/requests/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: -p ../../../../query-tests/Security/lib/ --max-import-depth=1
diff --git a/python/ql/test/library-tests/web/client/requests/test.py b/python/ql/test/library-tests/web/client/requests/test.py
deleted file mode 100644
index 1cb5e47e166..00000000000
--- a/python/ql/test/library-tests/web/client/requests/test.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import requests
-
-requests.get('example.com')
-requests.post('example.com')
diff --git a/python/ql/test/library-tests/web/client/six/ClientHttpRequests.expected b/python/ql/test/library-tests/web/client/six/ClientHttpRequests.expected
deleted file mode 100644
index 40400cce819..00000000000
--- a/python/ql/test/library-tests/web/client/six/ClientHttpRequests.expected
+++ /dev/null
@@ -1,11 +0,0 @@
-WARNING: Module Client has been deprecated and may be removed in future (ClientHttpRequests.ql:5,6-12)
-| test.py:6:5:6:32 | ControlFlowNode for Attribute() | test.py:5:27:5:39 | ControlFlowNode for Str | GET |
-| test.py:6:5:6:32 | ControlFlowNode for Attribute() | test.py:6:25:6:31 | ControlFlowNode for Str | GET |
-| test.py:15:5:15:33 | ControlFlowNode for Attribute() | test.py:10:28:10:40 | ControlFlowNode for Str | POST |
-| test.py:15:5:15:33 | ControlFlowNode for Attribute() | test.py:15:26:15:32 | ControlFlowNode for Str | POST |
-| test.py:20:5:20:33 | ControlFlowNode for Attribute() | test.py:19:27:19:39 | ControlFlowNode for Str | |
-| test.py:20:5:20:33 | ControlFlowNode for Attribute() | test.py:20:26:20:32 | ControlFlowNode for Str | |
-| test.py:30:5:30:32 | ControlFlowNode for Attribute() | test.py:28:27:28:30 | ControlFlowNode for fake | GET |
-| test.py:30:5:30:32 | ControlFlowNode for Attribute() | test.py:30:25:30:31 | ControlFlowNode for Str | GET |
-| test.py:37:5:37:29 | ControlFlowNode for req_meth() | test.py:35:27:35:39 | ControlFlowNode for Str | HEAD |
-| test.py:37:5:37:29 | ControlFlowNode for req_meth() | test.py:37:22:37:28 | ControlFlowNode for Str | HEAD |
diff --git a/python/ql/test/library-tests/web/client/six/ClientHttpRequests.ql b/python/ql/test/library-tests/web/client/six/ClientHttpRequests.ql
deleted file mode 100644
index 52fd7ff218e..00000000000
--- a/python/ql/test/library-tests/web/client/six/ClientHttpRequests.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.Http
-import semmle.python.web.ClientHttpRequest
-
-from Client::HttpRequest req, string method
-where if exists(req.getMethodUpper()) then method = req.getMethodUpper() else method = ""
-select req, req.getAUrlPart(), method
diff --git a/python/ql/test/library-tests/web/client/six/options b/python/ql/test/library-tests/web/client/six/options
deleted file mode 100644
index 1f95e64d742..00000000000
--- a/python/ql/test/library-tests/web/client/six/options
+++ /dev/null
@@ -1,2 +0,0 @@
-semmle-extractor-options: --max-import-depth=2
-optimize: true
diff --git a/python/ql/test/library-tests/web/client/six/test.py b/python/ql/test/library-tests/web/client/six/test.py
deleted file mode 100644
index cdd79021d87..00000000000
--- a/python/ql/test/library-tests/web/client/six/test.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from six.moves.http_client import HTTPConnection, HTTPSConnection
-
-
-def basic():
- conn = HTTPConnection('example.com')
- conn.request('GET', '/path')
-
-
-def indirect_caller():
- conn = HTTPSConnection('example.com')
- indirect_callee(conn)
-
-
-def indirect_callee(conn):
- conn.request('POST', '/path')
-
-
-def method_not_known(method):
- conn = HTTPConnection('example.com')
- conn.request(method, '/path')
-
-
-def sneaky_setting_host():
- # We don't handle that the host is overwritten directly.
- # A contrived example; you're not supposed to do this, but you certainly can.
- fake = 'fakehost.com'
- real = 'realhost.com'
- conn = HTTPConnection(fake)
- conn.host = real
- conn.request('GET', '/path')
-
-
-def tricky_not_attribute_node():
- # A contrived example; you're not supposed to do this, but you certainly can.
- conn = HTTPConnection('example.com')
- req_meth = conn.request
- req_meth('HEAD', '/path')
diff --git a/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.expected b/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.expected
deleted file mode 100644
index 73540db65e6..00000000000
--- a/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.expected
+++ /dev/null
@@ -1,11 +0,0 @@
-WARNING: Module Client has been deprecated and may be removed in future (ClientHttpRequests.ql:5,6-12)
-| test.py:13:5:13:32 | ControlFlowNode for Attribute() | test.py:12:27:12:39 | ControlFlowNode for Str | GET |
-| test.py:13:5:13:32 | ControlFlowNode for Attribute() | test.py:13:25:13:31 | ControlFlowNode for Str | GET |
-| test.py:22:5:22:33 | ControlFlowNode for Attribute() | test.py:17:28:17:40 | ControlFlowNode for Str | POST |
-| test.py:22:5:22:33 | ControlFlowNode for Attribute() | test.py:22:26:22:32 | ControlFlowNode for Str | POST |
-| test.py:27:5:27:33 | ControlFlowNode for Attribute() | test.py:26:27:26:39 | ControlFlowNode for Str | |
-| test.py:27:5:27:33 | ControlFlowNode for Attribute() | test.py:27:26:27:32 | ControlFlowNode for Str | |
-| test.py:37:5:37:32 | ControlFlowNode for Attribute() | test.py:35:27:35:30 | ControlFlowNode for fake | GET |
-| test.py:37:5:37:32 | ControlFlowNode for Attribute() | test.py:37:25:37:31 | ControlFlowNode for Str | GET |
-| test.py:44:5:44:29 | ControlFlowNode for req_meth() | test.py:42:27:42:39 | ControlFlowNode for Str | HEAD |
-| test.py:44:5:44:29 | ControlFlowNode for req_meth() | test.py:44:22:44:28 | ControlFlowNode for Str | HEAD |
diff --git a/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.ql b/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.ql
deleted file mode 100644
index 52fd7ff218e..00000000000
--- a/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.Http
-import semmle.python.web.ClientHttpRequest
-
-from Client::HttpRequest req, string method
-where if exists(req.getMethodUpper()) then method = req.getMethodUpper() else method = ""
-select req, req.getAUrlPart(), method
diff --git a/python/ql/test/library-tests/web/client/stdlib/options b/python/ql/test/library-tests/web/client/stdlib/options
deleted file mode 100644
index eb214fc2931..00000000000
--- a/python/ql/test/library-tests/web/client/stdlib/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: --max-import-depth=1
diff --git a/python/ql/test/library-tests/web/client/stdlib/test.py b/python/ql/test/library-tests/web/client/stdlib/test.py
deleted file mode 100644
index 179f9b30858..00000000000
--- a/python/ql/test/library-tests/web/client/stdlib/test.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import sys
-PY2 = sys.version_info[0] == 2
-PY3 = sys.version_info[0] == 3
-
-if PY2:
- from httplib import HTTPConnection, HTTPSConnection
-if PY3:
- from http.client import HTTPConnection, HTTPSConnection
-
-
-def basic():
- conn = HTTPConnection('example.com')
- conn.request('GET', '/path')
-
-
-def indirect_caller():
- conn = HTTPSConnection('example.com')
- indirect_callee(conn)
-
-
-def indirect_callee(conn):
- conn.request('POST', '/path')
-
-
-def method_not_known(method):
- conn = HTTPConnection('example.com')
- conn.request(method, '/path')
-
-
-def sneaky_setting_host():
- # We don't handle that the host is overwritten directly.
- # A contrived example; you're not supposed to do this, but you certainly can.
- fake = 'fakehost.com'
- real = 'realhost.com'
- conn = HTTPConnection(fake)
- conn.host = real
- conn.request('GET', '/path')
-
-
-def tricky_not_attribute_node():
- # A contrived example; you're not supposed to do this, but you certainly can.
- conn = HTTPConnection('example.com')
- req_meth = conn.request
- req_meth('HEAD', '/path')
diff --git a/python/ql/test/library-tests/web/django/HttpRedirectSinks.expected b/python/ql/test/library-tests/web/django/HttpRedirectSinks.expected
deleted file mode 100644
index 6753f22d31f..00000000000
--- a/python/ql/test/library-tests/web/django/HttpRedirectSinks.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-WARNING: Type HttpRedirectTaintSink has been deprecated and may be removed in future (HttpRedirectSinks.ql:5,6-27)
-| test_1x.py:13:21:13:24 | DjangoShortcutsRedirectSink | externally controlled string |
-| test_2x_3x.py:13:21:13:24 | DjangoShortcutsRedirectSink | externally controlled string |
-| views_1x.py:99:33:99:55 | DjangoRedirectResponseSink | externally controlled string |
-| views_2x_3x.py:120:33:120:55 | DjangoRedirectResponseSink | externally controlled string |
diff --git a/python/ql/test/library-tests/web/django/HttpRedirectSinks.ql b/python/ql/test/library-tests/web/django/HttpRedirectSinks.ql
deleted file mode 100644
index 157ef2d4430..00000000000
--- a/python/ql/test/library-tests/web/django/HttpRedirectSinks.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRedirect
-import semmle.python.security.strings.Untrusted
-
-from HttpRedirectTaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/django/HttpResponseSinks.expected b/python/ql/test/library-tests/web/django/HttpResponseSinks.expected
deleted file mode 100644
index 2f620ac508f..00000000000
--- a/python/ql/test/library-tests/web/django/HttpResponseSinks.expected
+++ /dev/null
@@ -1,32 +0,0 @@
-WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27)
-| views_1x.py:8:25:8:63 | django.Response(...) | externally controlled string |
-| views_1x.py:12:25:12:52 | django.Response(...) | externally controlled string |
-| views_1x.py:16:25:16:53 | django.Response(...) | externally controlled string |
-| views_1x.py:21:15:21:42 | django.Response.write(...) | externally controlled string |
-| views_1x.py:30:29:30:60 | django.Response(...) | externally controlled string |
-| views_1x.py:36:29:36:65 | django.Response(...) | externally controlled string |
-| views_1x.py:41:25:41:63 | django.Response(...) | externally controlled string |
-| views_1x.py:45:25:45:70 | django.Response(...) | externally controlled string |
-| views_1x.py:66:25:66:55 | django.Response(...) | externally controlled string |
-| views_1x.py:75:25:75:33 | django.Response(...) | externally controlled string |
-| views_1x.py:90:25:90:33 | django.Response(...) | externally controlled string |
-| views_1x.py:94:25:94:58 | django.Response(...) | externally controlled string |
-| views_1x.py:103:33:103:55 | django.Response(...) | externally controlled string |
-| views_1x.py:107:25:107:47 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:8:25:8:63 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:12:25:12:52 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:16:25:16:53 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:21:15:21:42 | django.Response.write(...) | externally controlled string |
-| views_2x_3x.py:30:29:30:60 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:36:29:36:65 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:41:25:41:63 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:45:25:45:70 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:66:25:66:40 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:79:25:79:61 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:82:25:82:69 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:85:25:85:64 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:88:25:88:32 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:111:25:111:33 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:115:25:115:58 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:124:33:124:55 | django.Response(...) | externally controlled string |
-| views_2x_3x.py:128:25:128:47 | django.Response(...) | externally controlled string |
diff --git a/python/ql/test/library-tests/web/django/HttpResponseSinks.ql b/python/ql/test/library-tests/web/django/HttpResponseSinks.ql
deleted file mode 100644
index e62ec486da6..00000000000
--- a/python/ql/test/library-tests/web/django/HttpResponseSinks.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from HttpResponseTaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/django/HttpSources.expected b/python/ql/test/library-tests/web/django/HttpSources.expected
deleted file mode 100644
index 2aa9c979334..00000000000
--- a/python/ql/test/library-tests/web/django/HttpSources.expected
+++ /dev/null
@@ -1,53 +0,0 @@
-WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28)
-| test_1x.py:6:19:6:25 | request | django.request.HttpRequest |
-| test_1x.py:6:28:6:31 | path | externally controlled string |
-| test_1x.py:12:19:12:25 | request | django.request.HttpRequest |
-| test_1x.py:12:28:12:31 | path | externally controlled string |
-| test_2x_3x.py:6:19:6:25 | request | django.request.HttpRequest |
-| test_2x_3x.py:6:28:6:31 | path | externally controlled string |
-| test_2x_3x.py:12:19:12:25 | request | django.request.HttpRequest |
-| test_2x_3x.py:12:28:12:31 | path | externally controlled string |
-| views_1x.py:7:19:7:25 | request | django.request.HttpRequest |
-| views_1x.py:7:28:7:30 | foo | externally controlled string |
-| views_1x.py:7:33:7:35 | bar | externally controlled string |
-| views_1x.py:11:20:11:26 | request | django.request.HttpRequest |
-| views_1x.py:15:21:15:27 | request | django.request.HttpRequest |
-| views_1x.py:19:21:19:27 | request | django.request.HttpRequest |
-| views_1x.py:29:20:29:26 | request | django.request.HttpRequest |
-| views_1x.py:29:29:29:37 | untrusted | externally controlled string |
-| views_1x.py:35:19:35:25 | request | django.request.HttpRequest |
-| views_1x.py:35:28:35:36 | untrusted | externally controlled string |
-| views_1x.py:39:19:39:25 | request | django.request.HttpRequest |
-| views_1x.py:39:28:39:38 | page_number | externally controlled string |
-| views_1x.py:44:24:44:30 | request | django.request.HttpRequest |
-| views_1x.py:44:33:44:36 | arg0 | externally controlled string |
-| views_1x.py:44:39:44:42 | arg1 | externally controlled string |
-| views_1x.py:65:15:65:21 | request | django.request.HttpRequest |
-| views_1x.py:65:24:65:31 | username | externally controlled string |
-| views_1x.py:74:13:74:19 | request | django.request.HttpRequest |
-| views_2x_3x.py:7:19:7:25 | request | django.request.HttpRequest |
-| views_2x_3x.py:7:28:7:30 | foo | externally controlled string |
-| views_2x_3x.py:7:33:7:35 | bar | externally controlled string |
-| views_2x_3x.py:11:20:11:26 | request | django.request.HttpRequest |
-| views_2x_3x.py:15:21:15:27 | request | django.request.HttpRequest |
-| views_2x_3x.py:19:21:19:27 | request | django.request.HttpRequest |
-| views_2x_3x.py:29:20:29:26 | request | django.request.HttpRequest |
-| views_2x_3x.py:29:29:29:37 | untrusted | externally controlled string |
-| views_2x_3x.py:35:19:35:25 | request | django.request.HttpRequest |
-| views_2x_3x.py:35:28:35:36 | untrusted | externally controlled string |
-| views_2x_3x.py:39:19:39:25 | request | django.request.HttpRequest |
-| views_2x_3x.py:39:28:39:38 | page_number | externally controlled string |
-| views_2x_3x.py:44:24:44:30 | request | django.request.HttpRequest |
-| views_2x_3x.py:44:33:44:36 | arg0 | externally controlled string |
-| views_2x_3x.py:44:39:44:42 | arg1 | externally controlled string |
-| views_2x_3x.py:65:20:65:26 | request | django.request.HttpRequest |
-| views_2x_3x.py:78:17:78:23 | request | django.request.HttpRequest |
-| views_2x_3x.py:78:26:78:36 | page_number | externally controlled string |
-| views_2x_3x.py:81:17:81:23 | request | django.request.HttpRequest |
-| views_2x_3x.py:81:26:81:28 | foo | externally controlled string |
-| views_2x_3x.py:81:31:81:33 | bar | externally controlled string |
-| views_2x_3x.py:81:36:81:38 | baz | externally controlled string |
-| views_2x_3x.py:84:17:84:23 | request | django.request.HttpRequest |
-| views_2x_3x.py:84:26:84:28 | foo | externally controlled string |
-| views_2x_3x.py:84:31:84:33 | bar | externally controlled string |
-| views_2x_3x.py:87:26:87:32 | request | django.request.HttpRequest |
diff --git a/python/ql/test/library-tests/web/django/HttpSources.ql b/python/ql/test/library-tests/web/django/HttpSources.ql
deleted file mode 100644
index 6fa1a7d2a6b..00000000000
--- a/python/ql/test/library-tests/web/django/HttpSources.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.security.strings.Untrusted
-
-from HttpRequestTaintSource source, TaintKind kind
-where source.isSourceOf(kind)
-select source.(ControlFlowNode).getNode(), kind
diff --git a/python/ql/test/library-tests/web/django/SqlInjectionSinks.expected b/python/ql/test/library-tests/web/django/SqlInjectionSinks.expected
deleted file mode 100644
index d9850f2f7c6..00000000000
--- a/python/ql/test/library-tests/web/django/SqlInjectionSinks.expected
+++ /dev/null
@@ -1,9 +0,0 @@
-| sql.py:13:24:13:64 | db.connection.execute | externally controlled string |
-| sql.py:14:26:14:66 | django.models.QuerySet.raw(sink,...) | externally controlled string |
-| sql.py:17:24:17:77 | db.connection.execute | externally controlled string |
-| sql.py:20:38:20:95 | django.db.models.expressions.RawSQL(sink,...) | externally controlled string |
-| sql.py:21:26:21:83 | django.models.QuerySet.raw(sink,...) | externally controlled string |
-| sql.py:22:28:22:85 | django.models.QuerySet.extra(sink,...) | externally controlled string |
-| sql.py:36:26:36:68 | django.models.QuerySet.raw(sink,...) | externally controlled string |
-| sql.py:42:11:42:52 | django.models.QuerySet.raw(sink,...) | externally controlled string |
-| sql.py:47:13:47:54 | django.models.QuerySet.extra(sink,...) | externally controlled string |
diff --git a/python/ql/test/library-tests/web/django/SqlInjectionSinks.ql b/python/ql/test/library-tests/web/django/SqlInjectionSinks.ql
deleted file mode 100644
index b12dd8ea041..00000000000
--- a/python/ql/test/library-tests/web/django/SqlInjectionSinks.ql
+++ /dev/null
@@ -1,8 +0,0 @@
-import python
-import semmle.python.security.injection.Sql
-import semmle.python.web.django.Db
-import semmle.python.web.django.Model
-
-from SqlInjectionSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/django/options b/python/ql/test/library-tests/web/django/options
deleted file mode 100644
index a87f995c396..00000000000
--- a/python/ql/test/library-tests/web/django/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: --lang=3 --max-import-depth=3 -p ../../../query-tests/Security/lib/
diff --git a/python/ql/test/library-tests/web/django/sql.py b/python/ql/test/library-tests/web/django/sql.py
deleted file mode 100644
index 7809c24edc1..00000000000
--- a/python/ql/test/library-tests/web/django/sql.py
+++ /dev/null
@@ -1,53 +0,0 @@
-from django.db import connection, models
-from django.db.models.expressions import RawSQL
-
-
-class User(models.Model):
- username = models.CharField(max_length=100)
- description = models.TextField(blank=True)
-
-
-def show_user(username):
- with connection.cursor() as cursor:
- # GOOD -- Using parameters
- cursor.execute("SELECT * FROM users WHERE username = %s", username)
- User.objects.raw("SELECT * FROM users WHERE username = %s", (username,))
-
- # BAD -- Using string formatting
- cursor.execute("SELECT * FROM users WHERE username = '%s'" % username)
-
- # BAD -- other ways of executing raw SQL code with string interpolation
- User.objects.annotate(RawSQL("insert into names_file ('name') values ('%s')" % username))
- User.objects.raw("insert into names_file ('name') values ('%s')" % username)
- User.objects.extra("insert into names_file ('name') values ('%s')" % username)
-
- # BAD (but currently no custom query to find this)
- #
- # It is exposed to SQL injection (https://docs.djangoproject.com/en/2.2/ref/models/querysets/#extra)
- # For example, using name = "; DROP ALL TABLES -- "
- # will result in SQL: SELECT * FROM name WHERE name = ''; DROP ALL TABLES -- ''
- #
- # This shouldn't be very widespread, since using a normal string will result in invalid SQL
- # Using name = "example", will result in SQL: SELECT * FROM name WHERE name = ''example''
- # which in MySQL will give a syntax error
- #
- # When testing this out locally, none of the queries worked against SQLite3, but I could use
- # the SQL injection against MySQL.
- User.objects.raw("SELECT * FROM users WHERE username = '%s'", (username,))
-
-
-def raw3(arg):
- m = User.objects.filter('foo')
- m = m.filter('bar')
- m.raw("select foo from bar where baz = %s" % arg)
-
-
-def raw4(arg):
- m = User.objects.filter('foo')
- m.extra("select foo from bar where baz = %s" % arg)
-
-
-def update_user(key, description1):
- # Neither of these are exposed to sql-injections
- user = User.objects.get(pk=key)
- item.description = description
diff --git a/python/ql/test/library-tests/web/django/test_1x.py b/python/ql/test/library-tests/web/django/test_1x.py
deleted file mode 100644
index ce15a5e71bf..00000000000
--- a/python/ql/test/library-tests/web/django/test_1x.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""tests for Django 1.x"""
-from django.conf.urls import url
-from django.shortcuts import redirect, render
-
-
-def with_template(request, path='default'):
- env = {'path': path}
- # We would need to understand django templates to know if this is safe or not
- return render(request, 'possibly-vulnerable-template.html', env)
-
-
-def vuln_redirect(request, path):
- return redirect(path)
-
-
-urlpatterns = [
- url(r'^(?P.*)$', with_template),
- url(r'^redirect/(?P.*)$', vuln_redirect),
-]
diff --git a/python/ql/test/library-tests/web/django/test_2x_3x.py b/python/ql/test/library-tests/web/django/test_2x_3x.py
deleted file mode 100644
index da08a80c27c..00000000000
--- a/python/ql/test/library-tests/web/django/test_2x_3x.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""tests for Django 2.x and 3.x"""
-from django.urls import path
-from django.shortcuts import redirect, render
-
-
-def with_template(request, path='default'):
- env = {'path': path}
- # We would need to understand django templates to know if this is safe or not
- return render(request, 'possibly-vulnerable-template.html', env)
-
-
-def vuln_redirect(request, path):
- return redirect(path)
-
-
-urlpatterns = [
- path('/', with_template),
- path('/redirect/', vuln_redirect),
-]
diff --git a/python/ql/test/library-tests/web/django/views_1x.py b/python/ql/test/library-tests/web/django/views_1x.py
deleted file mode 100644
index f5476a13cef..00000000000
--- a/python/ql/test/library-tests/web/django/views_1x.py
+++ /dev/null
@@ -1,107 +0,0 @@
-"""test of views for Django 1.x"""
-from django.conf.urls import patterns, url
-from django.http.response import HttpResponse, HttpResponseRedirect, JsonResponse, HttpResponseNotFound
-from django.views.generic import View
-
-
-def url_match_xss(request, foo, bar, no_taint=None):
- return HttpResponse('url_match_xss: {} {}'.format(foo, bar))
-
-
-def get_params_xss(request):
- return HttpResponse(request.GET.get("untrusted"))
-
-
-def post_params_xss(request):
- return HttpResponse(request.POST.get("untrusted"))
-
-
-def http_resp_write(request):
- rsp = HttpResponse()
- rsp.write(request.GET.get("untrusted"))
- return rsp
-
-
-class Foo(object):
- # Note: since Foo is used as the super type in a class view, it will be able to handle requests.
-
-
- def post(self, request, untrusted):
- return HttpResponse('Foo post: {}'.format(untrusted))
-
-
-class ClassView(View, Foo):
-
- def get(self, request, untrusted):
- return HttpResponse('ClassView get: {}'.format(untrusted))
-
-
-def show_articles(request, page_number=1):
- page_number = int(page_number)
- return HttpResponse('articles page: {}'.format(page_number))
-
-
-def xxs_positional_arg(request, arg0, arg1, no_taint=None):
- return HttpResponse('xxs_positional_arg: {} {}'.format(arg0, arg1))
-
-
-urlpatterns = [
- url(r'^url_match/(?P[^/]+)/(?P[^/]+)$', url_match_xss),
- url(r'^get_params$', get_params_xss),
- url(r'^post_params$', post_params_xss),
- url(r'^http_resp_write$', http_resp_write),
- url(r'^class_view/(?P.+)$', ClassView.as_view()),
-
- # one pattern to support `articles/page-` and ensuring that articles/ goes to page-1
- url(r'articles/^(?:page-(?P\d+)/)?$', show_articles),
- # passing as positional argument is not the recommended way of doing things, but it is certainly
- # possible
- url(r'^([^/]+)/(?:foo|bar)/([^/]+)$', xxs_positional_arg, name='xxs_positional_arg'),
-]
-
-################################################################################
-# Using patterns() for routing
-
-def show_user(request, username):
- return HttpResponse('show_user {}'.format(username))
-
-
-urlpatterns = patterns(url(r'^users/(?P[^/]+)$', show_user))
-
-################################################################################
-# Show we understand the keyword arguments to django.conf.urls.url
-
-def kw_args(request):
- return HttpResponse('kw_args')
-
-urlpatterns = [
- url(view=kw_args, regex=r'^kw_args$')
-]
-
-# Not an XSS sink, since the Content-Type is not "text/html"
-# FP reported in https://github.com/github/codeql-python-team/issues/38
-def fp_json_response(request):
- # implicitly sets Content-Type to "application/json"
- return JsonResponse({"foo": request.GET.get("foo")})
-
-# Not an XSS sink, since the Content-Type is not "text/html"
-def fp_manual_json_response(request):
- json_data = '{"json": "{}"}'.format(request.GET.get("foo"))
- return HttpResponse(json_data, content_type="application/json")
-
-# Not an XSS sink, since the Content-Type is not "text/html"
-def fp_manual_content_type(reuqest):
- return HttpResponse('
', content_type="text/plain")
-
-# XSS FP reported in https://github.com/github/codeql/issues/3466
-# Note: This should be a open-redirect sink, but not a XSS sink.
-def fp_redirect(request):
- return HttpResponseRedirect(request.GET.get("next"))
-
-# Ensure that simple subclasses are still vuln to XSS
-def tp_not_found(request):
- return HttpResponseNotFound(request.GET.get("name"))
-
-# Ensure we still have a XSS sink when manually setting the content_type to HTML
-def tp_manual_response_type(request):
- return HttpResponse(request.GET.get("name"), content_type="text/html; charset=utf-8")
diff --git a/python/ql/test/library-tests/web/django/views_2x_3x.py b/python/ql/test/library-tests/web/django/views_2x_3x.py
deleted file mode 100644
index d61792004e9..00000000000
--- a/python/ql/test/library-tests/web/django/views_2x_3x.py
+++ /dev/null
@@ -1,128 +0,0 @@
-"""testing views for Django 2.x and 3.x"""
-from django.urls import path, re_path
-from django.http import HttpResponse, HttpResponseRedirect, JsonResponse, HttpResponseNotFound
-from django.views import View
-
-
-def url_match_xss(request, foo, bar, no_taint=None):
- return HttpResponse('url_match_xss: {} {}'.format(foo, bar))
-
-
-def get_params_xss(request):
- return HttpResponse(request.GET.get("untrusted"))
-
-
-def post_params_xss(request):
- return HttpResponse(request.POST.get("untrusted"))
-
-
-def http_resp_write(request):
- rsp = HttpResponse()
- rsp.write(request.GET.get("untrusted"))
- return rsp
-
-
-class Foo(object):
- # Note: since Foo is used as the super type in a class view, it will be able to handle requests.
-
-
- def post(self, request, untrusted):
- return HttpResponse('Foo post: {}'.format(untrusted))
-
-
-class ClassView(View, Foo):
-
- def get(self, request, untrusted):
- return HttpResponse('ClassView get: {}'.format(untrusted))
-
-
-def show_articles(request, page_number=1):
- page_number = int(page_number)
- return HttpResponse('articles page: {}'.format(page_number))
-
-
-def xxs_positional_arg(request, arg0, arg1, no_taint=None):
- return HttpResponse('xxs_positional_arg: {} {}'.format(arg0, arg1))
-
-
-urlpatterns = [
- re_path(r'^url_match/(?P[^/]+)/(?P[^/]+)$', url_match_xss),
- re_path(r'^get_params$', get_params_xss),
- re_path(r'^post_params$', post_params_xss),
- re_path(r'^http_resp_write$', http_resp_write),
- re_path(r'^class_view/(?P.+)$', ClassView.as_view()),
-
- # one pattern to support `articles/page-` and ensuring that articles/ goes to page-1
- re_path(r'articles/^(?:page-(?P\d+)/)?$', show_articles),
- # passing as positional argument is not the recommended way of doing things, but it is certainly
- # possible
- re_path(r'^([^/]+)/(?:foo|bar)/([^/]+)$', xxs_positional_arg, name='xxs_positional_arg'),
-]
-
-
-# Show we understand the keyword arguments to from django.urls.re_path
-
-def re_path_kwargs(request):
- return HttpResponse('re_path_kwargs')
-
-
-urlpatterns = [
- re_path(view=re_path_kwargs, route=r'^specifying-as-kwargs-is-not-a-problem$')
-]
-
-################################################################################
-# Using path
-################################################################################
-
-# saying page_number is an externally controlled *string* is a bit strange, when we have an int converter :O
-def page_number(request, page_number=1):
- return HttpResponse('page_number: {}'.format(page_number))
-
-def foo_bar_baz(request, foo, bar, baz):
- return HttpResponse('foo_bar_baz: {} {} {}'.format(foo, bar, baz))
-
-def path_kwargs(request, foo, bar):
- return HttpResponse('path_kwargs: {} {} {}'.format(foo, bar))
-
-def not_valid_identifier(request):
- return HttpResponse('')
-
-urlpatterns = [
- path('articles/', page_number),
- path('articles/page-', page_number),
- path('//', foo_bar_baz, name='foo-bar-baz'),
-
- path(view=path_kwargs, route='/'),
-
- # We should not report there is a request parameter called `not_valid!`
- path('not_valid/', not_valid_identifier),
-]
-
-
-# Not an XSS sink, since the Content-Type is not "text/html"
-# FP reported in https://github.com/github/codeql-python-team/issues/38
-def fp_json_response(request):
- # implicitly sets Content-Type to "application/json"
- return JsonResponse({"foo": request.GET.get("foo")})
-
-# Not an XSS sink, since the Content-Type is not "text/html"
-def fp_manual_json_response(request):
- json_data = '{"json": "{}"}'.format(request.GET.get("foo"))
- return HttpResponse(json_data, content_type="application/json")
-
-# Not an XSS sink, since the Content-Type is not "text/html"
-def fp_manual_content_type(reuqest):
- return HttpResponse('
', content_type="text/plain")
-
-# XSS FP reported in https://github.com/github/codeql/issues/3466
-# Note: This should be a open-redirect sink, but not a XSS sink.
-def fp_redirect(request):
- return HttpResponseRedirect(request.GET.get("next"))
-
-# Ensure that simple subclasses are still vuln to XSS
-def tp_not_found(request):
- return HttpResponseNotFound(request.GET.get("name"))
-
-# Ensure we still have a XSS sink when manually setting the content_type to HTML
-def tp_manual_response_type(request):
- return HttpResponse(request.GET.get("name"), content_type="text/html; charset=utf-8")
diff --git a/python/ql/test/library-tests/web/falcon/HttpResponseSinks.expected b/python/ql/test/library-tests/web/falcon/HttpResponseSinks.expected
deleted file mode 100644
index 76fe8773866..00000000000
--- a/python/ql/test/library-tests/web/falcon/HttpResponseSinks.expected
+++ /dev/null
@@ -1 +0,0 @@
-| FIXME: temporarily disabled since it's not working |
diff --git a/python/ql/test/library-tests/web/falcon/HttpResponseSinks.ql b/python/ql/test/library-tests/web/falcon/HttpResponseSinks.ql
deleted file mode 100644
index eec9b1ef3cf..00000000000
--- a/python/ql/test/library-tests/web/falcon/HttpResponseSinks.ql
+++ /dev/null
@@ -1,8 +0,0 @@
-import python
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-// from HttpResponseTaintSink sink, TaintKind kind
-// where sink.sinks(kind)
-// select sink, kind
-select "FIXME: temporarily disabled since it's not working"
diff --git a/python/ql/test/library-tests/web/falcon/HttpSources.expected b/python/ql/test/library-tests/web/falcon/HttpSources.expected
deleted file mode 100644
index 3cc29f418ab..00000000000
--- a/python/ql/test/library-tests/web/falcon/HttpSources.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28)
-| test.py:9:22:9:24 | req | falcon.request |
-| test.py:19:23:19:25 | req | falcon.request |
-| test.py:22:25:22:27 | req | falcon.request |
diff --git a/python/ql/test/library-tests/web/falcon/HttpSources.ql b/python/ql/test/library-tests/web/falcon/HttpSources.ql
deleted file mode 100644
index 6fa1a7d2a6b..00000000000
--- a/python/ql/test/library-tests/web/falcon/HttpSources.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.security.strings.Untrusted
-
-from HttpRequestTaintSource source, TaintKind kind
-where source.isSourceOf(kind)
-select source.(ControlFlowNode).getNode(), kind
diff --git a/python/ql/test/library-tests/web/falcon/Routing.expected b/python/ql/test/library-tests/web/falcon/Routing.expected
deleted file mode 100644
index 47bcb473273..00000000000
--- a/python/ql/test/library-tests/web/falcon/Routing.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-WARNING: Type FalconRoute has been deprecated and may be removed in future (Routing.ql:4,6-17)
-| /hello | delete | test.py:22:5:22:35 | Function on_delete |
-| /hello | get | test.py:9:5:9:32 | Function on_get |
-| /hello | post | test.py:19:5:19:33 | Function on_post |
diff --git a/python/ql/test/library-tests/web/falcon/Routing.ql b/python/ql/test/library-tests/web/falcon/Routing.ql
deleted file mode 100644
index fde6c933b65..00000000000
--- a/python/ql/test/library-tests/web/falcon/Routing.ql
+++ /dev/null
@@ -1,5 +0,0 @@
-import python
-import semmle.python.web.falcon.General
-
-from FalconRoute route, string method
-select route.getUrl(), method, route.getHandlerFunction(method)
diff --git a/python/ql/test/library-tests/web/falcon/Sinks.expected b/python/ql/test/library-tests/web/falcon/Sinks.expected
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/python/ql/test/library-tests/web/falcon/Sinks.ql b/python/ql/test/library-tests/web/falcon/Sinks.ql
deleted file mode 100644
index efaafe17f02..00000000000
--- a/python/ql/test/library-tests/web/falcon/Sinks.ql
+++ /dev/null
@@ -1,8 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from TaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink.getLocation().toString(), sink.(ControlFlowNode).getNode().toString(), kind
diff --git a/python/ql/test/library-tests/web/falcon/Taint.expected b/python/ql/test/library-tests/web/falcon/Taint.expected
deleted file mode 100644
index f1e7abb4f0d..00000000000
--- a/python/ql/test/library-tests/web/falcon/Taint.expected
+++ /dev/null
@@ -1,20 +0,0 @@
-| test.py:9 | req | falcon.request |
-| test.py:9 | resp | falcon.response |
-| test.py:10 | Attribute | file[externally controlled string] |
-| test.py:10 | Attribute() | externally controlled string |
-| test.py:10 | req | falcon.request |
-| test.py:11 | Attribute() | json[externally controlled string] |
-| test.py:11 | raw_json | externally controlled string |
-| test.py:12 | resp | falcon.response |
-| test.py:13 | Dict | {json[externally controlled string]} |
-| test.py:15 | result | json[externally controlled string] |
-| test.py:17 | result | {json[externally controlled string]} |
-| test.py:19 | req | falcon.request |
-| test.py:19 | resp | falcon.response |
-| test.py:22 | req | falcon.request |
-| test.py:22 | resp | falcon.response |
-| test.py:23 | Attribute | wsgi.environment |
-| test.py:23 | req | falcon.request |
-| test.py:24 | Subscript | externally controlled string |
-| test.py:24 | env | wsgi.environment |
-| test.py:25 | qs | externally controlled string |
diff --git a/python/ql/test/library-tests/web/falcon/Taint.ql b/python/ql/test/library-tests/web/falcon/Taint.ql
deleted file mode 100644
index d68b12079b8..00000000000
--- a/python/ql/test/library-tests/web/falcon/Taint.ql
+++ /dev/null
@@ -1,8 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from TaintedNode node
-where node.getLocation().getFile().getShortName() = "test.py"
-select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind()
diff --git a/python/ql/test/library-tests/web/falcon/options b/python/ql/test/library-tests/web/falcon/options
deleted file mode 100644
index 7fb713d5924..00000000000
--- a/python/ql/test/library-tests/web/falcon/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: --max-import-depth=3 -p ../../../query-tests/Security/lib/
diff --git a/python/ql/test/library-tests/web/falcon/test.py b/python/ql/test/library-tests/web/falcon/test.py
deleted file mode 100644
index 72853c94ad0..00000000000
--- a/python/ql/test/library-tests/web/falcon/test.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import json
-
-from falcon import API
-
-app = API()
-
-class Handler(object):
-
- def on_get(self, req, resp):
- raw_json = req.stream.read()
- result = json.loads(raw_json)
- resp.status = 200
- result = {
- 'status': 'success',
- 'data': result
- }
- resp.body = json.dumps(result)
-
- def on_post(self, req, resp):
- pass
-
- def on_delete(self, req, resp):
- env = req.env
- qs = env["QUERY_STRING"]
- return qs
-
-app.add_route('/hello', Handler())
-
diff --git a/python/ql/test/library-tests/web/flask/HttpResponseSinks.expected b/python/ql/test/library-tests/web/flask/HttpResponseSinks.expected
deleted file mode 100644
index e860c6f2f87..00000000000
--- a/python/ql/test/library-tests/web/flask/HttpResponseSinks.expected
+++ /dev/null
@@ -1,17 +0,0 @@
-WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27)
-| test.py:8:12:8:25 | flask.routed.response | externally controlled string |
-| test.py:29:12:29:38 | flask.routed.response | externally controlled string |
-| test.py:35:16:35:37 | flask.routed.response | externally controlled string |
-| test.py:36:12:36:15 | flask.routed.response | externally controlled string |
-| test.py:41:12:41:54 | flask.routed.response | externally controlled string |
-| test.py:41:26:41:53 | flask.response.argument | externally controlled string |
-| test.py:46:12:46:62 | flask.routed.response | externally controlled string |
-| test.py:46:26:46:61 | flask.response.argument | externally controlled string |
-| test.py:50:12:50:48 | flask.routed.response | externally controlled string |
-| test.py:50:26:50:47 | flask.response.argument | externally controlled string |
-| test.py:54:12:54:53 | flask.routed.response | externally controlled string |
-| test.py:54:26:54:52 | flask.response.argument | externally controlled string |
-| test.py:60:12:60:62 | flask.routed.response | externally controlled string |
-| test.py:60:26:60:61 | flask.response.argument | externally controlled string |
-| test.py:64:12:64:58 | flask.routed.response | externally controlled string |
-| test.py:64:26:64:57 | flask.response.argument | externally controlled string |
diff --git a/python/ql/test/library-tests/web/flask/HttpResponseSinks.ql b/python/ql/test/library-tests/web/flask/HttpResponseSinks.ql
deleted file mode 100644
index e62ec486da6..00000000000
--- a/python/ql/test/library-tests/web/flask/HttpResponseSinks.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from HttpResponseTaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/flask/HttpSources.expected b/python/ql/test/library-tests/web/flask/HttpSources.expected
deleted file mode 100644
index e313f9bf1c2..00000000000
--- a/python/ql/test/library-tests/web/flask/HttpSources.expected
+++ /dev/null
@@ -1,10 +0,0 @@
-WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28)
-| test.py:29:12:29:23 | Attribute | {externally controlled string} |
-| test.py:33:9:33:20 | Attribute | {externally controlled string} |
-| test.py:35:16:35:27 | Attribute | {externally controlled string} |
-| test.py:40:18:40:29 | Attribute | {externally controlled string} |
-| test.py:45:18:45:29 | Attribute | {externally controlled string} |
-| test.py:49:11:49:14 | name | externally controlled string |
-| test.py:53:9:53:15 | subpath | externally controlled string |
-| test.py:59:24:59:26 | bar | externally controlled string |
-| test.py:63:13:63:21 | lang_code | externally controlled string |
diff --git a/python/ql/test/library-tests/web/flask/HttpSources.ql b/python/ql/test/library-tests/web/flask/HttpSources.ql
deleted file mode 100644
index 6fa1a7d2a6b..00000000000
--- a/python/ql/test/library-tests/web/flask/HttpSources.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.security.strings.Untrusted
-
-from HttpRequestTaintSource source, TaintKind kind
-where source.isSourceOf(kind)
-select source.(ControlFlowNode).getNode(), kind
diff --git a/python/ql/test/library-tests/web/flask/Routing.expected b/python/ql/test/library-tests/web/flask/Routing.expected
deleted file mode 100644
index 90e70bcee8a..00000000000
--- a/python/ql/test/library-tests/web/flask/Routing.expected
+++ /dev/null
@@ -1,11 +0,0 @@
-WARNING: Predicate flask_routing has been deprecated and may be removed in future (Routing.ql:5,7-20)
-| / | Function hello_world |
-| /complex/ | Function complex |
-| /dangerous | Function dangerous |
-| /dangerous-with-cfg-split | Function dangerous2 |
-| /foo/ | Function foo |
-| /hello/ | Function hello |
-| /multiple/bar/ | Function multiple |
-| /safe | Function safe |
-| /the/ | Function get |
-| /unsafe | Function unsafe |
diff --git a/python/ql/test/library-tests/web/flask/Routing.ql b/python/ql/test/library-tests/web/flask/Routing.ql
deleted file mode 100644
index 92ae6740f0d..00000000000
--- a/python/ql/test/library-tests/web/flask/Routing.ql
+++ /dev/null
@@ -1,6 +0,0 @@
-import python
-import semmle.python.web.flask.General
-
-from ControlFlowNode regex, Function func
-where flask_routing(regex, func)
-select regex.getNode().(StrConst).getText(), func.toString()
diff --git a/python/ql/test/library-tests/web/flask/Taint.expected b/python/ql/test/library-tests/web/flask/Taint.expected
deleted file mode 100644
index 48562648096..00000000000
--- a/python/ql/test/library-tests/web/flask/Taint.expected
+++ /dev/null
@@ -1,33 +0,0 @@
-| test.py:22 | Attribute() | flask/MyView.as.view |
-| test.py:25 | the_view | flask/MyView.as.view |
-| test.py:29 | Attribute | {externally controlled string} |
-| test.py:29 | Attribute() | externally controlled string |
-| test.py:33 | Attribute | {externally controlled string} |
-| test.py:33 | Subscript | externally controlled string |
-| test.py:35 | Attribute | {externally controlled string} |
-| test.py:35 | Subscript | externally controlled string |
-| test.py:40 | Attribute | {externally controlled string} |
-| test.py:40 | Attribute() | externally controlled string |
-| test.py:41 | BinaryExpr | externally controlled string |
-| test.py:41 | first_name | externally controlled string |
-| test.py:41 | make_response() | flask.Response |
-| test.py:45 | Attribute | {externally controlled string} |
-| test.py:45 | Attribute() | externally controlled string |
-| test.py:46 | first_name | externally controlled string |
-| test.py:46 | make_response() | flask.Response |
-| test.py:49 | name | externally controlled string |
-| test.py:50 | BinaryExpr | externally controlled string |
-| test.py:50 | make_response() | flask.Response |
-| test.py:50 | name | externally controlled string |
-| test.py:53 | subpath | externally controlled string |
-| test.py:54 | BinaryExpr | externally controlled string |
-| test.py:54 | make_response() | flask.Response |
-| test.py:54 | subpath | externally controlled string |
-| test.py:59 | bar | externally controlled string |
-| test.py:60 | Attribute() | externally controlled string |
-| test.py:60 | bar | externally controlled string |
-| test.py:60 | make_response() | flask.Response |
-| test.py:63 | lang_code | externally controlled string |
-| test.py:64 | Attribute() | externally controlled string |
-| test.py:64 | lang_code | externally controlled string |
-| test.py:64 | make_response() | flask.Response |
diff --git a/python/ql/test/library-tests/web/flask/Taint.ql b/python/ql/test/library-tests/web/flask/Taint.ql
deleted file mode 100644
index d68b12079b8..00000000000
--- a/python/ql/test/library-tests/web/flask/Taint.ql
+++ /dev/null
@@ -1,8 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from TaintedNode node
-where node.getLocation().getFile().getShortName() = "test.py"
-select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind()
diff --git a/python/ql/test/library-tests/web/flask/options b/python/ql/test/library-tests/web/flask/options
deleted file mode 100644
index 7fb713d5924..00000000000
--- a/python/ql/test/library-tests/web/flask/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: --max-import-depth=3 -p ../../../query-tests/Security/lib/
diff --git a/python/ql/test/library-tests/web/flask/test.py b/python/ql/test/library-tests/web/flask/test.py
deleted file mode 100644
index bedeaa56423..00000000000
--- a/python/ql/test/library-tests/web/flask/test.py
+++ /dev/null
@@ -1,67 +0,0 @@
-import flask
-
-from flask import Flask, request, make_response
-app = Flask(__name__)
-
-@app.route("/")
-def hello_world():
- return "Hello World!"
-
-from flask.views import MethodView
-
-class MyView(MethodView):
-
- def get(self, user_id):
- if user_id is None:
- # return a list of users
- pass
- else:
- # expose a single user
- pass
-
-the_view = MyView.as_view('my_view')
-
-app.add_url_rule('/the/', defaults={'user_id': None},
- view_func=the_view, methods=['GET',])
-
-@app.route("/dangerous")
-def dangerous():
- return request.args.get('payload')
-
-@app.route("/dangerous-with-cfg-split")
-def dangerous2():
- x = request.form['param0']
- if request.method == "POST":
- return request.form['param1']
- return None
-
-@app.route('/unsafe')
-def unsafe():
- first_name = request.args.get('name', '')
- return make_response("Your name is " + first_name)
-
-@app.route('/safe')
-def safe():
- first_name = request.args.get('name', '')
- return make_response("Your name is " + escape(first_name))
-
-@app.route('/hello/')
-def hello(name):
- return make_response("Your name is " + name)
-
-@app.route('/foo/')
-def foo(subpath):
- return make_response("The subpath is " + subpath)
-
-@app.route('/multiple/') # TODO: not recognized as route
-@app.route('/multiple/foo/') # TODO: not recognized as route
-@app.route('/multiple/bar/')
-def multiple(foo=None, bar=None):
- return make_response("foo={!r} bar={!r}".format(foo, bar))
-
-@app.route('/complex/')
-def complex(lang_code):
- return make_response("lang_code {}".format(lang_code))
-
-if __name__ == "__main__":
- app.run(debug=True)
diff --git a/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.expected b/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.expected
deleted file mode 100644
index 959217e0acd..00000000000
--- a/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27)
-| test.py:8:12:8:31 | pyramid.routed.response | externally controlled string |
-| test.py:17:12:17:41 | pyramid.routed.response | externally controlled string |
-| test.py:25:12:25:43 | pyramid.routed.response | externally controlled string |
diff --git a/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.ql b/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.ql
deleted file mode 100644
index e62ec486da6..00000000000
--- a/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from HttpResponseTaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/pyramid/HttpSources.expected b/python/ql/test/library-tests/web/pyramid/HttpSources.expected
deleted file mode 100644
index 23f8ab8e3ab..00000000000
--- a/python/ql/test/library-tests/web/pyramid/HttpSources.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28)
-| test.py:7:10:7:16 | request | pyramid.request |
-| test.py:15:11:15:17 | request | pyramid.request |
-| test.py:24:11:24:17 | request | pyramid.request |
diff --git a/python/ql/test/library-tests/web/pyramid/HttpSources.ql b/python/ql/test/library-tests/web/pyramid/HttpSources.ql
deleted file mode 100644
index 6fa1a7d2a6b..00000000000
--- a/python/ql/test/library-tests/web/pyramid/HttpSources.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.security.strings.Untrusted
-
-from HttpRequestTaintSource source, TaintKind kind
-where source.isSourceOf(kind)
-select source.(ControlFlowNode).getNode(), kind
diff --git a/python/ql/test/library-tests/web/pyramid/Routing.expected b/python/ql/test/library-tests/web/pyramid/Routing.expected
deleted file mode 100644
index 41e66136a68..00000000000
--- a/python/ql/test/library-tests/web/pyramid/Routing.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-WARNING: Predicate is_pyramid_view_function has been deprecated and may be removed in future (Routing.ql:5,7-31)
-| test.py:7 | Function home |
-| test.py:15 | Function greet |
-| test.py:24 | Function stuff |
diff --git a/python/ql/test/library-tests/web/pyramid/Routing.ql b/python/ql/test/library-tests/web/pyramid/Routing.ql
deleted file mode 100644
index 4a442c1115e..00000000000
--- a/python/ql/test/library-tests/web/pyramid/Routing.ql
+++ /dev/null
@@ -1,6 +0,0 @@
-import python
-import semmle.python.web.pyramid.View
-
-from Function func
-where is_pyramid_view_function(func)
-select func.getLocation().toString(), func.toString()
diff --git a/python/ql/test/library-tests/web/pyramid/Taint.expected b/python/ql/test/library-tests/web/pyramid/Taint.expected
deleted file mode 100644
index 94b8f844efb..00000000000
--- a/python/ql/test/library-tests/web/pyramid/Taint.expected
+++ /dev/null
@@ -1,11 +0,0 @@
-| test.py:7 | request | pyramid.request |
-| test.py:15 | request | pyramid.request |
-| test.py:16 | Attribute | {externally controlled string} |
-| test.py:16 | Subscript | externally controlled string |
-| test.py:16 | request | pyramid.request |
-| test.py:17 | BinaryExpr | externally controlled string |
-| test.py:17 | name | externally controlled string |
-| test.py:24 | request | pyramid.request |
-| test.py:25 | Attribute | externally controlled string |
-| test.py:25 | Dict | {externally controlled string} |
-| test.py:25 | request | pyramid.request |
diff --git a/python/ql/test/library-tests/web/pyramid/Taint.ql b/python/ql/test/library-tests/web/pyramid/Taint.ql
deleted file mode 100644
index d68b12079b8..00000000000
--- a/python/ql/test/library-tests/web/pyramid/Taint.ql
+++ /dev/null
@@ -1,8 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from TaintedNode node
-where node.getLocation().getFile().getShortName() = "test.py"
-select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind()
diff --git a/python/ql/test/library-tests/web/pyramid/options b/python/ql/test/library-tests/web/pyramid/options
deleted file mode 100644
index 1d132442a3b..00000000000
--- a/python/ql/test/library-tests/web/pyramid/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: --max-import-depth=2 -p ../../../query-tests/Security/lib/
diff --git a/python/ql/test/library-tests/web/pyramid/test.py b/python/ql/test/library-tests/web/pyramid/test.py
deleted file mode 100644
index 9fad8a7ba00..00000000000
--- a/python/ql/test/library-tests/web/pyramid/test.py
+++ /dev/null
@@ -1,25 +0,0 @@
-from pyramid.view import view_config
-from pyramid.response import Response
-
-@view_config(
- route_name='home'
-)
-def home(request):
- return Response('Welcome!')
-
-
-@view_config(
- route_name='greet',
- request_method='POST'
-)
-def greet(request):
- name = request.POST['arg']
- return Response('Welcome %s!' % name)
-
-
-@view_config(
- route_name='stuff',
- renderer='json'
-)
-def stuff(request):
- return {"err": 0, "body": request.body}
diff --git a/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.expected b/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.expected
deleted file mode 100644
index c4344d158b7..00000000000
--- a/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.expected
+++ /dev/null
@@ -1,3 +0,0 @@
-WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27)
-| test.py:72:26:72:58 | Taint sink | externally controlled string |
-| test.py:73:31:73:54 | Taint sink | [externally controlled string] |
diff --git a/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.ql b/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.ql
deleted file mode 100644
index e62ec486da6..00000000000
--- a/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from HttpResponseTaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/stdlib/HttpSources.expected b/python/ql/test/library-tests/web/stdlib/HttpSources.expected
deleted file mode 100644
index e979c63fd84..00000000000
--- a/python/ql/test/library-tests/web/stdlib/HttpSources.expected
+++ /dev/null
@@ -1,35 +0,0 @@
-WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28)
-| test.py:18:13:18:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:20:13:20:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:22:13:22:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:24:13:24:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:25:13:25:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:26:13:26:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:27:13:27:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:28:13:28:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:29:13:29:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:30:13:30:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:31:13:31:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:32:13:32:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:33:17:33:20 | self | BaseHTTPRequestHandlerKind |
-| test.py:34:19:34:22 | self | BaseHTTPRequestHandlerKind |
-| test.py:36:13:36:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:37:13:37:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:40:16:44:9 | Attribute() | CgiFieldStorageFormKind |
-| test.py:41:13:41:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:42:13:42:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:43:64:43:67 | self | BaseHTTPRequestHandlerKind |
-| test.py:69:9:69:12 | self | BaseHTTPRequestHandlerKind |
-| test.py:70:9:70:12 | self | BaseHTTPRequestHandlerKind |
-| test.py:71:9:71:12 | self | BaseHTTPRequestHandlerKind |
-| test.py:72:9:72:12 | self | BaseHTTPRequestHandlerKind |
-| test.py:73:9:73:12 | self | BaseHTTPRequestHandlerKind |
-| test.py:74:15:74:18 | self | BaseHTTPRequestHandlerKind |
-| test.py:78:16:82:9 | Attribute() | CgiFieldStorageFormKind |
-| test.py:79:13:79:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:80:13:80:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:81:64:81:67 | self | BaseHTTPRequestHandlerKind |
-| test.py:85:13:85:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:86:13:86:16 | self | BaseHTTPRequestHandlerKind |
-| test.py:96:9:96:12 | self | BaseHTTPRequestHandlerKind |
-| test.py:97:9:97:12 | self | BaseHTTPRequestHandlerKind |
diff --git a/python/ql/test/library-tests/web/stdlib/HttpSources.ql b/python/ql/test/library-tests/web/stdlib/HttpSources.ql
deleted file mode 100644
index f4e9a1b48d3..00000000000
--- a/python/ql/test/library-tests/web/stdlib/HttpSources.ql
+++ /dev/null
@@ -1,9 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.security.strings.Untrusted
-
-from HttpRequestTaintSource source, TaintKind kind
-where
- source.isSourceOf(kind) and
- source.getLocation().getFile().getShortName() != "cgi.py"
-select source.(ControlFlowNode).getNode(), kind
diff --git a/python/ql/test/library-tests/web/stdlib/TestTaint.expected b/python/ql/test/library-tests/web/stdlib/TestTaint.expected
deleted file mode 100644
index eba1bff195a..00000000000
--- a/python/ql/test/library-tests/web/stdlib/TestTaint.expected
+++ /dev/null
@@ -1,32 +0,0 @@
-| test.py:18 | ok | taint_sources | self | BaseHTTPRequestHandlerKind |
-| test.py:20 | ok | taint_sources | Attribute | externally controlled string |
-| test.py:22 | ok | taint_sources | Attribute | externally controlled string |
-| test.py:24 | ok | taint_sources | Attribute | {externally controlled string} |
-| test.py:25 | ok | taint_sources | Subscript | externally controlled string |
-| test.py:26 | ok | taint_sources | Attribute() | externally controlled string |
-| test.py:27 | ok | taint_sources | Attribute() | [externally controlled string] |
-| test.py:28 | fail | taint_sources | Attribute() | |
-| test.py:29 | ok | taint_sources | Attribute() | [externally controlled string] |
-| test.py:30 | fail | taint_sources | Attribute() | |
-| test.py:31 | ok | taint_sources | Attribute() | externally controlled string |
-| test.py:32 | ok | taint_sources | Attribute() | externally controlled string |
-| test.py:33 | ok | taint_sources | str() | externally controlled string |
-| test.py:34 | ok | taint_sources | bytes() | externally controlled string |
-| test.py:36 | ok | taint_sources | Attribute | file[externally controlled string] |
-| test.py:37 | ok | taint_sources | Attribute() | externally controlled string |
-| test.py:47 | ok | taint_sources | form | CgiFieldStorageFormKind |
-| test.py:49 | ok | taint_sources | Subscript | CgiFieldStorageFieldKind |
-| test.py:49 | ok | taint_sources | Subscript | [CgiFieldStorageFieldKind] |
-| test.py:50 | ok | taint_sources | Attribute | externally controlled string |
-| test.py:51 | ok | taint_sources | Attribute | file[externally controlled string] |
-| test.py:52 | ok | taint_sources | Attribute | externally controlled string |
-| test.py:53 | ok | taint_sources | Subscript | CgiFieldStorageFieldKind |
-| test.py:54 | ok | taint_sources | Attribute | externally controlled string |
-| test.py:55 | ok | taint_sources | Attribute | file[externally controlled string] |
-| test.py:56 | ok | taint_sources | Attribute | externally controlled string |
-| test.py:58 | ok | taint_sources | Attribute() | [externally controlled string] |
-| test.py:58 | ok | taint_sources | Attribute() | externally controlled string |
-| test.py:59 | ok | taint_sources | Subscript | externally controlled string |
-| test.py:61 | ok | taint_sources | Attribute() | externally controlled string |
-| test.py:63 | ok | taint_sources | Attribute() | [externally controlled string] |
-| test.py:64 | ok | taint_sources | Subscript | externally controlled string |
diff --git a/python/ql/test/library-tests/web/stdlib/TestTaint.ql b/python/ql/test/library-tests/web/stdlib/TestTaint.ql
deleted file mode 100644
index cd2b08ef235..00000000000
--- a/python/ql/test/library-tests/web/stdlib/TestTaint.ql
+++ /dev/null
@@ -1,32 +0,0 @@
-import python
-import semmle.python.dataflow.TaintTracking
-import semmle.python.web.HttpRequest
-import semmle.python.security.strings.Untrusted
-
-from
- Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res,
- string taint_string
-where
- call.getLocation().getFile().getShortName() = "test.py" and
- (
- call.getFunc().(Name).getId() = "ensure_tainted" and
- expected_taint = true
- or
- call.getFunc().(Name).getId() = "ensure_not_tainted" and
- expected_taint = false
- ) and
- arg = call.getAnArg() and
- (
- not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
- taint_string = "" and
- has_taint = false
- or
- exists(TaintedNode tainted | tainted.getAstNode() = arg |
- taint_string = tainted.getTaintKind().toString()
- ) and
- has_taint = true
- ) and
- if expected_taint = has_taint then test_res = "ok " else test_res = "fail"
-// if expected_taint = has_taint then test_res = "✓" else test_res = "✕"
-select arg.getLocation().toString(), test_res, call.getScope().(Function).getName(), arg.toString(),
- taint_string
diff --git a/python/ql/test/library-tests/web/stdlib/test.py b/python/ql/test/library-tests/web/stdlib/test.py
deleted file mode 100644
index 1c239f776bb..00000000000
--- a/python/ql/test/library-tests/web/stdlib/test.py
+++ /dev/null
@@ -1,108 +0,0 @@
-import sys
-import os
-import cgi
-
-if sys.version_info[0] == 2:
- from BaseHTTPServer import BaseHTTPRequestHandler
- from BaseHTTPServer import HTTPServer
-
-if sys.version_info[0] == 3:
- from http.server import HTTPServer, BaseHTTPRequestHandler
-
-
-class MyHandler(BaseHTTPRequestHandler):
-
- def taint_sources(self):
-
- ensure_tainted(
- self,
-
- self.requestline,
-
- self.path,
-
- self.headers,
- self.headers['Foo'],
- self.headers.get('Foo'),
- self.headers.get_all('Foo'),
- self.headers.keys(),
- self.headers.values(),
- self.headers.items(),
- self.headers.as_bytes(),
- self.headers.as_string(),
- str(self.headers),
- bytes(self.headers),
-
- self.rfile,
- self.rfile.read(),
- )
-
- form = cgi.FieldStorage(
- self.rfile,
- self.headers,
- environ={'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': self.headers.get('content-type')},
- )
-
- ensure_tainted(
- form,
-
- form['key'],
- form['key'].value,
- form['key'].file,
- form['key'].filename,
- form['key'][0], # will be a list, if multiple fields named "key" are provided
- form['key'][0].value,
- form['key'][0].file,
- form['key'][0].filename,
-
- form.getvalue('key'),
- form.getvalue('key')[0], # will be a list, if multiple fields named "key" are provided
-
- form.getfirst('key'),
-
- form.getlist('key'),
- form.getlist('key')[0],
- )
-
- def do_GET(self):
- # send_response will log a line to stderr
- self.send_response(200)
- self.send_header("Content-type", "text/plain; charset=utf-8")
- self.end_headers()
- self.wfile.write(b"Hello BaseHTTPRequestHandler\n")
- self.wfile.writelines([b"1\n", b"2\n", b"3\n"])
- print(self.headers)
-
-
- def do_POST(self):
- form = cgi.FieldStorage(
- self.rfile,
- self.headers,
- environ={'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': self.headers.get('content-type')},
- )
-
- if 'myfile' not in form:
- self.send_response(422)
- self.end_headers()
- return
-
- field = form['myfile']
-
- field.file.seek(0, os.SEEK_END)
- filesize = field.file.tell()
-
- print("Uploaded {!r} with {} bytes".format(field.filename, filesize))
-
- self.send_response(200)
- self.end_headers()
-
-
-if __name__ == "__main__":
- server = HTTPServer(("127.0.0.1", 8080), MyHandler)
- server.serve_forever()
-
- # Headers works case insensitvely, so self.headers['foo'] == self.headers['FOO']
- # curl localhost:8080 --header "Foo: 1" --header "foo: 2"
-
- # To test file submission through forms, use
- # curl -F myfile=@ localhost:8080
diff --git a/python/ql/test/library-tests/web/tornado/Classes.expected b/python/ql/test/library-tests/web/tornado/Classes.expected
deleted file mode 100644
index 693976a2480..00000000000
--- a/python/ql/test/library-tests/web/tornado/Classes.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-WARNING: Predicate aTornadoRequestHandlerClass has been deprecated and may be removed in future (Classes.ql:6,13-40)
-| test.py:4 | class Handler1 |
-| test.py:8 | class Handler2 |
-| test.py:14 | class Handler3 |
-| test.py:23 | class DeepInheritance |
diff --git a/python/ql/test/library-tests/web/tornado/Classes.ql b/python/ql/test/library-tests/web/tornado/Classes.ql
deleted file mode 100644
index fda9b6eb00a..00000000000
--- a/python/ql/test/library-tests/web/tornado/Classes.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.TestUtils
-import semmle.python.web.tornado.Tornado
-
-from ClassValue cls
-where cls = aTornadoRequestHandlerClass()
-select remove_library_prefix(cls.getScope().getLocation()), cls.toString()
diff --git a/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.expected b/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.expected
deleted file mode 100644
index aced656734c..00000000000
--- a/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.expected
+++ /dev/null
@@ -1,2 +0,0 @@
-WARNING: Type HttpRedirectTaintSink has been deprecated and may be removed in future (HttpRedirectSinks.ql:5,6-27)
-| test.py:20:23:20:25 | tornado.HttpRequestHandler.redirect | externally controlled string |
diff --git a/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.ql b/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.ql
deleted file mode 100644
index 157ef2d4430..00000000000
--- a/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRedirect
-import semmle.python.security.strings.Untrusted
-
-from HttpRedirectTaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/tornado/HttpResponseSinks.expected b/python/ql/test/library-tests/web/tornado/HttpResponseSinks.expected
deleted file mode 100644
index 0681e121664..00000000000
--- a/python/ql/test/library-tests/web/tornado/HttpResponseSinks.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27)
-| test.py:6:20:6:43 | tornado.HttpRequestHandler.write | externally controlled string |
-| test.py:12:20:12:23 | tornado.HttpRequestHandler.write | externally controlled string |
-| test.py:26:20:26:48 | tornado.HttpRequestHandler.write | externally controlled string |
diff --git a/python/ql/test/library-tests/web/tornado/HttpResponseSinks.ql b/python/ql/test/library-tests/web/tornado/HttpResponseSinks.ql
deleted file mode 100644
index e62ec486da6..00000000000
--- a/python/ql/test/library-tests/web/tornado/HttpResponseSinks.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from HttpResponseTaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/tornado/HttpSources.expected b/python/ql/test/library-tests/web/tornado/HttpSources.expected
deleted file mode 100644
index 7e882de7791..00000000000
--- a/python/ql/test/library-tests/web/tornado/HttpSources.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28)
-| test.py:6:20:6:43 | Attribute() | externally controlled string |
-| test.py:10:16:10:40 | Attribute() | [externally controlled string] |
-| test.py:17:15:17:26 | Attribute | tornado.request.HttpRequest |
-| test.py:26:20:26:48 | Attribute() | externally controlled string |
diff --git a/python/ql/test/library-tests/web/tornado/HttpSources.ql b/python/ql/test/library-tests/web/tornado/HttpSources.ql
deleted file mode 100644
index 6fa1a7d2a6b..00000000000
--- a/python/ql/test/library-tests/web/tornado/HttpSources.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.security.strings.Untrusted
-
-from HttpRequestTaintSource source, TaintKind kind
-where source.isSourceOf(kind)
-select source.(ControlFlowNode).getNode(), kind
diff --git a/python/ql/test/library-tests/web/tornado/Taint.expected b/python/ql/test/library-tests/web/tornado/Taint.expected
deleted file mode 100644
index 6028c194b94..00000000000
--- a/python/ql/test/library-tests/web/tornado/Taint.expected
+++ /dev/null
@@ -1,12 +0,0 @@
-| test.py:6 | Attribute() | externally controlled string |
-| test.py:10 | Attribute() | [externally controlled string] |
-| test.py:11 | Subscript | externally controlled string |
-| test.py:11 | args | [externally controlled string] |
-| test.py:12 | name | externally controlled string |
-| test.py:17 | Attribute | tornado.request.HttpRequest |
-| test.py:18 | Attribute | {externally controlled string} |
-| test.py:18 | req | tornado.request.HttpRequest |
-| test.py:19 | Subscript | externally controlled string |
-| test.py:19 | h | {externally controlled string} |
-| test.py:20 | url | externally controlled string |
-| test.py:26 | Attribute() | externally controlled string |
diff --git a/python/ql/test/library-tests/web/tornado/Taint.ql b/python/ql/test/library-tests/web/tornado/Taint.ql
deleted file mode 100644
index d4fc34b643c..00000000000
--- a/python/ql/test/library-tests/web/tornado/Taint.ql
+++ /dev/null
@@ -1,10 +0,0 @@
-import python
-import semmle.python.TestUtils
-import semmle.python.web.HttpRequest
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from TaintedNode node
-// Add this restriction to keep Python2 and 3 results the same.
-where not exists(node.getContext().getCaller())
-select remove_library_prefix(node.getLocation()), node.getAstNode().toString(), node.getTaintKind()
diff --git a/python/ql/test/library-tests/web/tornado/options b/python/ql/test/library-tests/web/tornado/options
deleted file mode 100644
index 1d132442a3b..00000000000
--- a/python/ql/test/library-tests/web/tornado/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: --max-import-depth=2 -p ../../../query-tests/Security/lib/
diff --git a/python/ql/test/library-tests/web/tornado/test.py b/python/ql/test/library-tests/web/tornado/test.py
deleted file mode 100644
index a5a467a81ab..00000000000
--- a/python/ql/test/library-tests/web/tornado/test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-
-import tornado.web
-
-class Handler1(tornado.web.RequestHandler):
- def get(self):
- self.write(self.get_argument("xss"))
-
-class Handler2(tornado.web.RequestHandler):
- def get(self):
- args = self.get_body_arguments()
- name = args[0]
- self.write(name)
-
-class Handler3(tornado.web.RequestHandler):
-
- def get(self):
- req = self.request
- h = req.headers
- url = h["url"]
- self.redirect(url)
-
-
-class DeepInheritance(Handler3):
-
- def get(self):
- self.write(self.get_argument("also_xss"))
diff --git a/python/ql/test/library-tests/web/turbogears/Controller.expected b/python/ql/test/library-tests/web/turbogears/Controller.expected
deleted file mode 100644
index 1f47639b5a5..00000000000
--- a/python/ql/test/library-tests/web/turbogears/Controller.expected
+++ /dev/null
@@ -1,6 +0,0 @@
-WARNING: Type TurboGearsControllerMethod has been deprecated and may be removed in future (Controller.ql:4,6-32)
-| test.py:7:5:7:32 | Function onerror |
-| test.py:13:5:13:50 | Function ok_validated |
-| test.py:18:5:18:57 | Function partially_validated |
-| test.py:22:5:22:51 | Function not_validated |
-| test.py:26:5:26:28 | Function with_template |
diff --git a/python/ql/test/library-tests/web/turbogears/Controller.ql b/python/ql/test/library-tests/web/turbogears/Controller.ql
deleted file mode 100644
index 850e56ef453..00000000000
--- a/python/ql/test/library-tests/web/turbogears/Controller.ql
+++ /dev/null
@@ -1,5 +0,0 @@
-import python
-import semmle.python.web.turbogears.TurboGears
-
-from TurboGearsControllerMethod m
-select m
diff --git a/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.expected b/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.expected
deleted file mode 100644
index f2c1d0ee324..00000000000
--- a/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.expected
+++ /dev/null
@@ -1,6 +0,0 @@
-WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27)
-| test.py:8:16:8:69 | TurboGears ControllerMethodReturnValue | externally controlled string |
-| test.py:14:16:14:50 | TurboGears ControllerMethodReturnValue | externally controlled string |
-| test.py:19:16:19:50 | TurboGears ControllerMethodReturnValue | externally controlled string |
-| test.py:23:16:23:50 | TurboGears ControllerMethodReturnValue | externally controlled string |
-| test.py:27:16:27:38 | TurboGears ControllerMethodTemplatedReturnValue | {externally controlled string} |
diff --git a/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.ql b/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.ql
deleted file mode 100644
index e62ec486da6..00000000000
--- a/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from HttpResponseTaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/turbogears/HttpSources.expected b/python/ql/test/library-tests/web/turbogears/HttpSources.expected
deleted file mode 100644
index 0d0dc0f72fe..00000000000
--- a/python/ql/test/library-tests/web/turbogears/HttpSources.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28)
-| test.py:18:43:18:43 | b | externally controlled string |
-| test.py:22:29:22:29 | a | externally controlled string |
-| test.py:22:37:22:37 | b | externally controlled string |
diff --git a/python/ql/test/library-tests/web/turbogears/HttpSources.ql b/python/ql/test/library-tests/web/turbogears/HttpSources.ql
deleted file mode 100644
index 6fa1a7d2a6b..00000000000
--- a/python/ql/test/library-tests/web/turbogears/HttpSources.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.security.strings.Untrusted
-
-from HttpRequestTaintSource source, TaintKind kind
-where source.isSourceOf(kind)
-select source.(ControlFlowNode).getNode(), kind
diff --git a/python/ql/test/library-tests/web/turbogears/Taint.expected b/python/ql/test/library-tests/web/turbogears/Taint.expected
deleted file mode 100644
index 45b84df72c2..00000000000
--- a/python/ql/test/library-tests/web/turbogears/Taint.expected
+++ /dev/null
@@ -1,12 +0,0 @@
-| test.py:18 | b | externally controlled string |
-| test.py:19 | BinaryExpr | [externally controlled string] |
-| test.py:19 | BinaryExpr | externally controlled string |
-| test.py:19 | Tuple | [externally controlled string] |
-| test.py:19 | b | externally controlled string |
-| test.py:22 | a | externally controlled string |
-| test.py:22 | b | externally controlled string |
-| test.py:23 | BinaryExpr | [externally controlled string] |
-| test.py:23 | BinaryExpr | externally controlled string |
-| test.py:23 | Tuple | [externally controlled string] |
-| test.py:23 | a | externally controlled string |
-| test.py:23 | b | externally controlled string |
diff --git a/python/ql/test/library-tests/web/turbogears/Taint.ql b/python/ql/test/library-tests/web/turbogears/Taint.ql
deleted file mode 100644
index 09972af5f98..00000000000
--- a/python/ql/test/library-tests/web/turbogears/Taint.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from TaintedNode node
-select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind()
diff --git a/python/ql/test/library-tests/web/turbogears/options b/python/ql/test/library-tests/web/turbogears/options
deleted file mode 100644
index 7fb713d5924..00000000000
--- a/python/ql/test/library-tests/web/turbogears/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: --max-import-depth=3 -p ../../../query-tests/Security/lib/
diff --git a/python/ql/test/library-tests/web/turbogears/test.py b/python/ql/test/library-tests/web/turbogears/test.py
deleted file mode 100644
index bae3a460f43..00000000000
--- a/python/ql/test/library-tests/web/turbogears/test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-
-from tg import request, validate, expose, TGController
-from formencode import validators
-
-class RootController(TGController):
- @expose()
- def onerror(self, **kwargs):
- return 'An error occurred: %s' % request.validation['errors']
-
- @expose()
- @validate({"a": validators.Int(not_empty=True), "b": validators.Email},
- error_handler=onerror)
- def ok_validated(self, a=None, b=None, *args):
- return 'Values: %s, %s, %s' % (a, b, args)
-
- @expose()
- @validate({"a": validators.Int(not_empty=True)})
- def partially_validated(self, a=None, b=None, *args):
- return 'Values: %s, %s, %s' % (a, b, args)
-
- @expose()
- def not_validated(self, a=None, b=None, *args):
- return 'Values: %s, %s, %s' % (a, b, args)
-
- @expose("")
- def with_template(self):
- return {'template_var': 'foo'}
diff --git a/python/ql/test/library-tests/web/twisted/Classes.expected b/python/ql/test/library-tests/web/twisted/Classes.expected
deleted file mode 100644
index b818907e98f..00000000000
--- a/python/ql/test/library-tests/web/twisted/Classes.expected
+++ /dev/null
@@ -1,6 +0,0 @@
-WARNING: Predicate aTwistedRequestHandlerClass has been deprecated and may be removed in future (Classes.ql:6,13-40)
-| class MyRequestHandler1 | test.py:3 |
-| class MyRequestHandler2 | test.py:23 |
-| class MyRequestHandler3 | test.py:27 |
-| class MyRequestHandler4 | test.py:38 |
-| class MyRequestHandler5 | test.py:42 |
diff --git a/python/ql/test/library-tests/web/twisted/Classes.ql b/python/ql/test/library-tests/web/twisted/Classes.ql
deleted file mode 100644
index ccc3618b61e..00000000000
--- a/python/ql/test/library-tests/web/twisted/Classes.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.TestUtils
-import semmle.python.web.twisted.Twisted
-
-from ClassValue cls
-where cls = aTwistedRequestHandlerClass()
-select cls.toString(), remove_library_prefix(cls.getScope().getLocation())
diff --git a/python/ql/test/library-tests/web/twisted/HttpResponseSinks.expected b/python/ql/test/library-tests/web/twisted/HttpResponseSinks.expected
deleted file mode 100644
index 763655ffe37..00000000000
--- a/python/ql/test/library-tests/web/twisted/HttpResponseSinks.expected
+++ /dev/null
@@ -1,11 +0,0 @@
-WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27)
-| test.py:7:16:7:23 | Twisted response | externally controlled string |
-| test.py:14:16:14:23 | Twisted response | externally controlled string |
-| test.py:21:16:21:23 | Twisted response | externally controlled string |
-| test.py:36:16:36:37 | Twisted response | externally controlled string |
-| test.py:40:23:40:30 | Twisted request setter | externally controlled string |
-| test.py:44:27:44:31 | Twisted request setter | externally controlled string |
-| test.py:44:34:44:38 | Twisted request setter | externally controlled string |
-| test.py:45:27:45:31 | Twisted request setter | externally controlled string |
-| test.py:45:34:45:40 | Twisted request setter | externally controlled string |
-| test.py:46:16:46:37 | Twisted response | externally controlled string |
diff --git a/python/ql/test/library-tests/web/twisted/HttpResponseSinks.ql b/python/ql/test/library-tests/web/twisted/HttpResponseSinks.ql
deleted file mode 100644
index e62ec486da6..00000000000
--- a/python/ql/test/library-tests/web/twisted/HttpResponseSinks.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from HttpResponseTaintSink sink, TaintKind kind
-where sink.sinks(kind)
-select sink, kind
diff --git a/python/ql/test/library-tests/web/twisted/HttpSources.expected b/python/ql/test/library-tests/web/twisted/HttpSources.expected
deleted file mode 100644
index 4e7cb4c7abb..00000000000
--- a/python/ql/test/library-tests/web/twisted/HttpSources.expected
+++ /dev/null
@@ -1,9 +0,0 @@
-WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28)
-| test.py:4:22:4:28 | request | twisted.request.http.Request |
-| test.py:9:26:9:32 | request | twisted.request.http.Request |
-| test.py:16:27:16:33 | request | twisted.request.http.Request |
-| test.py:24:24:24:30 | request | twisted.request.http.Request |
-| test.py:28:22:28:30 | myrequest | twisted.request.http.Request |
-| test.py:31:27:31:37 | postrequest | twisted.request.http.Request |
-| test.py:39:22:39:28 | request | twisted.request.http.Request |
-| test.py:43:22:43:28 | request | twisted.request.http.Request |
diff --git a/python/ql/test/library-tests/web/twisted/HttpSources.ql b/python/ql/test/library-tests/web/twisted/HttpSources.ql
deleted file mode 100644
index 6fa1a7d2a6b..00000000000
--- a/python/ql/test/library-tests/web/twisted/HttpSources.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.web.HttpRequest
-import semmle.python.security.strings.Untrusted
-
-from HttpRequestTaintSource source, TaintKind kind
-where source.isSourceOf(kind)
-select source.(ControlFlowNode).getNode(), kind
diff --git a/python/ql/test/library-tests/web/twisted/Methods.expected b/python/ql/test/library-tests/web/twisted/Methods.expected
deleted file mode 100644
index 6578ef88da9..00000000000
--- a/python/ql/test/library-tests/web/twisted/Methods.expected
+++ /dev/null
@@ -1,9 +0,0 @@
-WARNING: Predicate getTwistedRequestHandlerMethod has been deprecated and may be removed in future (Methods.ql:6,14-44)
-| myrender | Function MyRequestHandler2.myrender | test.py:24 |
-| render | Function MyRequestHandler1.render | test.py:4 |
-| render | Function MyRequestHandler3.render | test.py:28 |
-| render | Function MyRequestHandler4.render | test.py:39 |
-| render | Function MyRequestHandler5.render | test.py:43 |
-| render_GET | Function MyRequestHandler1.render_GET | test.py:9 |
-| render_POST | Function MyRequestHandler1.render_POST | test.py:16 |
-| render_POST | Function MyRequestHandler3.render_POST | test.py:31 |
diff --git a/python/ql/test/library-tests/web/twisted/Methods.ql b/python/ql/test/library-tests/web/twisted/Methods.ql
deleted file mode 100644
index f997b7deef3..00000000000
--- a/python/ql/test/library-tests/web/twisted/Methods.ql
+++ /dev/null
@@ -1,7 +0,0 @@
-import python
-import semmle.python.TestUtils
-import semmle.python.web.twisted.Twisted
-
-from FunctionValue func, string name
-where func = getTwistedRequestHandlerMethod(name)
-select name, func.toString(), remove_library_prefix(func.getScope().getLocation())
diff --git a/python/ql/test/library-tests/web/twisted/Taint.expected b/python/ql/test/library-tests/web/twisted/Taint.expected
deleted file mode 100644
index 1c793c973bd..00000000000
--- a/python/ql/test/library-tests/web/twisted/Taint.expected
+++ /dev/null
@@ -1,41 +0,0 @@
-| test.py:4 | request | twisted.request.http.Request |
-| test.py:5 | Attribute | externally controlled string |
-| test.py:5 | request | twisted.request.http.Request |
-| test.py:6 | request | twisted.request.http.Request |
-| test.py:9 | request | twisted.request.http.Request |
-| test.py:10 | request | twisted.request.http.Request |
-| test.py:11 | Attribute | externally controlled string |
-| test.py:11 | x | twisted.request.http.Request |
-| test.py:12 | request | twisted.request.http.Request |
-| test.py:13 | request | twisted.request.http.Request |
-| test.py:16 | request | twisted.request.http.Request |
-| test.py:17 | Attribute | {[externally controlled string]} |
-| test.py:17 | request | twisted.request.http.Request |
-| test.py:18 | Attribute | {[externally controlled string]} |
-| test.py:18 | Attribute() | [externally controlled string] |
-| test.py:18 | request | twisted.request.http.Request |
-| test.py:19 | Subscript | externally controlled string |
-| test.py:19 | foo | [externally controlled string] |
-| test.py:20 | quux | externally controlled string |
-| test.py:24 | request | twisted.request.http.Request |
-| test.py:25 | request | twisted.request.http.Request |
-| test.py:28 | myrequest | twisted.request.http.Request |
-| test.py:29 | myrequest | twisted.request.http.Request |
-| test.py:31 | postrequest | twisted.request.http.Request |
-| test.py:32 | Attribute() | externally controlled string |
-| test.py:32 | postrequest | twisted.request.http.Request |
-| test.py:33 | Attribute() | externally controlled string |
-| test.py:33 | postrequest | twisted.request.http.Request |
-| test.py:34 | Attribute() | externally controlled string |
-| test.py:34 | postrequest | twisted.request.http.Request |
-| test.py:35 | Attribute() | externally controlled string |
-| test.py:35 | postrequest | twisted.request.http.Request |
-| test.py:36 | w | externally controlled string |
-| test.py:36 | x | externally controlled string |
-| test.py:36 | y | externally controlled string |
-| test.py:36 | z | externally controlled string |
-| test.py:39 | request | twisted.request.http.Request |
-| test.py:40 | request | twisted.request.http.Request |
-| test.py:43 | request | twisted.request.http.Request |
-| test.py:44 | request | twisted.request.http.Request |
-| test.py:45 | request | twisted.request.http.Request |
diff --git a/python/ql/test/library-tests/web/twisted/Taint.ql b/python/ql/test/library-tests/web/twisted/Taint.ql
deleted file mode 100644
index e92616b6b29..00000000000
--- a/python/ql/test/library-tests/web/twisted/Taint.ql
+++ /dev/null
@@ -1,8 +0,0 @@
-import python
-import semmle.python.TestUtils
-import semmle.python.web.HttpRequest
-import semmle.python.web.HttpResponse
-import semmle.python.security.strings.Untrusted
-
-from TaintedNode node
-select remove_library_prefix(node.getLocation()), node.getAstNode().toString(), node.getTaintKind()
diff --git a/python/ql/test/library-tests/web/twisted/options b/python/ql/test/library-tests/web/twisted/options
deleted file mode 100644
index 4084b102b55..00000000000
--- a/python/ql/test/library-tests/web/twisted/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: --max-import-depth=1 -p ../../../query-tests/Security/lib/
diff --git a/python/ql/test/library-tests/web/twisted/test.py b/python/ql/test/library-tests/web/twisted/test.py
deleted file mode 100644
index f6691b84d95..00000000000
--- a/python/ql/test/library-tests/web/twisted/test.py
+++ /dev/null
@@ -1,51 +0,0 @@
-from twisted.web import resource
-
-class MyRequestHandler1(resource.Resource):
- def render(self, request):
- foo(request.uri)
- response = do_stuff_with(request)
- return response
-
- def render_GET(self, request):
- x = request
- bar(x.uri)
- do_stuff_with(request)
- response = do_stuff_with(request)
- return response
-
- def render_POST(self, request):
- baz(request.args)
- foo = request.args.get("baz")
- quux = foo[5]
- response = do_stuff_with(quux)
- return response
-
-class MyRequestHandler2(resource.Resource):
- def myrender(self, request):
- do_stuff_with(request)
-
-class MyRequestHandler3(resource.Resource):
- def render(self, myrequest):
- do_stuff_with(myrequest)
-
- def render_POST(self, postrequest):
- x = postrequest.getHeader("someheader")
- y = postrequest.getCookie("somecookie")
- z = postrequest.getUser()
- w = postrequest.getPassword()
- return do_stuff_with(x,y,z,w)
-
-class MyRequestHandler4(resource.Resource):
- def render(self, request):
- request.write("Foobar")
-
-class MyRequestHandler5(resource.Resource):
- def render(self, request):
- request.setHeader("foo", "bar")
- request.addCookie("key", "value")
- return "This is my response."
-
-class NotATwistedRequestHandler(object):
- def render(self, request):
- return do_stuff_with(request)
-
diff --git a/python/tools/recorded-call-graph-metrics/ql/lib/BytecodeExpr.qll b/python/tools/recorded-call-graph-metrics/ql/lib/BytecodeExpr.qll
index 4d1bfeb3859..c8d1acff57a 100644
--- a/python/tools/recorded-call-graph-metrics/ql/lib/BytecodeExpr.qll
+++ b/python/tools/recorded-call-graph-metrics/ql/lib/BytecodeExpr.qll
@@ -2,27 +2,18 @@ import python
abstract class XmlBytecodeExpr extends XmlElement { }
-/** DEPRECATED: Alias for XmlBytecodeExpr */
-deprecated class XMLBytecodeExpr = XmlBytecodeExpr;
-
class XmlBytecodeConst extends XmlBytecodeExpr {
XmlBytecodeConst() { this.hasName("BytecodeConst") }
string get_value_data_raw() { result = this.getAChild("value").getTextValue() }
}
-/** DEPRECATED: Alias for XmlBytecodeConst */
-deprecated class XMLBytecodeConst = XmlBytecodeConst;
-
class XmlBytecodeVariableName extends XmlBytecodeExpr {
XmlBytecodeVariableName() { this.hasName("BytecodeVariableName") }
string get_name_data() { result = this.getAChild("name").getTextValue() }
}
-/** DEPRECATED: Alias for XmlBytecodeVariableName */
-deprecated class XMLBytecodeVariableName = XmlBytecodeVariableName;
-
class XmlBytecodeAttribute extends XmlBytecodeExpr {
XmlBytecodeAttribute() { this.hasName("BytecodeAttribute") }
@@ -31,9 +22,6 @@ class XmlBytecodeAttribute extends XmlBytecodeExpr {
XmlBytecodeExpr get_object_data() { result.getParent() = this.getAChild("object") }
}
-/** DEPRECATED: Alias for XmlBytecodeAttribute */
-deprecated class XMLBytecodeAttribute = XmlBytecodeAttribute;
-
class XmlBytecodeSubscript extends XmlBytecodeExpr {
XmlBytecodeSubscript() { this.hasName("BytecodeSubscript") }
@@ -42,9 +30,6 @@ class XmlBytecodeSubscript extends XmlBytecodeExpr {
XmlBytecodeExpr get_object_data() { result.getParent() = this.getAChild("object") }
}
-/** DEPRECATED: Alias for XmlBytecodeSubscript */
-deprecated class XMLBytecodeSubscript = XmlBytecodeSubscript;
-
class XmlBytecodeTuple extends XmlBytecodeExpr {
XmlBytecodeTuple() { this.hasName("BytecodeTuple") }
@@ -53,9 +38,6 @@ class XmlBytecodeTuple extends XmlBytecodeExpr {
}
}
-/** DEPRECATED: Alias for XmlBytecodeTuple */
-deprecated class XMLBytecodeTuple = XmlBytecodeTuple;
-
class XmlBytecodeList extends XmlBytecodeExpr {
XmlBytecodeList() { this.hasName("BytecodeList") }
@@ -64,27 +46,18 @@ class XmlBytecodeList extends XmlBytecodeExpr {
}
}
-/** DEPRECATED: Alias for XmlBytecodeList */
-deprecated class XMLBytecodeList = XmlBytecodeList;
-
class XmlBytecodeCall extends XmlBytecodeExpr {
XmlBytecodeCall() { this.hasName("BytecodeCall") }
XmlBytecodeExpr get_function_data() { result.getParent() = this.getAChild("function") }
}
-/** DEPRECATED: Alias for XmlBytecodeCall */
-deprecated class XMLBytecodeCall = XmlBytecodeCall;
-
class XmlBytecodeUnknown extends XmlBytecodeExpr {
XmlBytecodeUnknown() { this.hasName("BytecodeUnknown") }
string get_opname_data() { result = this.getAChild("opname").getTextValue() }
}
-/** DEPRECATED: Alias for XmlBytecodeUnknown */
-deprecated class XMLBytecodeUnknown = XmlBytecodeUnknown;
-
class XmlBytecodeMakeFunction extends XmlBytecodeExpr {
XmlBytecodeMakeFunction() { this.hasName("BytecodeMakeFunction") }
@@ -93,14 +66,8 @@ class XmlBytecodeMakeFunction extends XmlBytecodeExpr {
}
}
-/** DEPRECATED: Alias for XmlBytecodeMakeFunction */
-deprecated class XMLBytecodeMakeFunction = XmlBytecodeMakeFunction;
-
class XmlSomethingInvolvingScaryBytecodeJump extends XmlBytecodeExpr {
XmlSomethingInvolvingScaryBytecodeJump() { this.hasName("SomethingInvolvingScaryBytecodeJump") }
string get_opname_data() { result = this.getAChild("opname").getTextValue() }
}
-
-/** DEPRECATED: Alias for XmlSomethingInvolvingScaryBytecodeJump */
-deprecated class XMLSomethingInvolvingScaryBytecodeJump = XmlSomethingInvolvingScaryBytecodeJump;
diff --git a/python/tools/recorded-call-graph-metrics/ql/lib/RecordedCalls.qll b/python/tools/recorded-call-graph-metrics/ql/lib/RecordedCalls.qll
index d6ad84ae3a1..4d0c11fa3fd 100644
--- a/python/tools/recorded-call-graph-metrics/ql/lib/RecordedCalls.qll
+++ b/python/tools/recorded-call-graph-metrics/ql/lib/RecordedCalls.qll
@@ -57,9 +57,6 @@ class XmlRecordedCall extends XmlElement {
}
}
-/** DEPRECATED: Alias for XmlRecordedCall */
-deprecated class XMLRecordedCall = XmlRecordedCall;
-
/** The XML data for the call part a recorded call. */
class XmlCall extends XmlElement {
XmlCall() { this.hasName("Call") }
@@ -110,15 +107,9 @@ class XmlCall extends XmlElement {
}
}
-/** DEPRECATED: Alias for XmlCall */
-deprecated class XMLCall = XmlCall;
-
/** The XML data for the callee part a recorded call. */
abstract class XmlCallee extends XmlElement { }
-/** DEPRECATED: Alias for XmlCallee */
-deprecated class XMLCallee = XmlCallee;
-
/** The XML data for the callee part a recorded call, when the callee is a Python function. */
class XmlPythonCallee extends XmlCallee {
XmlPythonCallee() { this.hasName("PythonCallee") }
@@ -140,9 +131,6 @@ class XmlPythonCallee extends XmlCallee {
}
}
-/** DEPRECATED: Alias for XmlPythonCallee */
-deprecated class XMLPythonCallee = XmlPythonCallee;
-
/** The XML data for the callee part a recorded call, when the callee is a C function or builtin. */
class XmlExternalCallee extends XmlCallee {
XmlExternalCallee() { this.hasName("ExternalCallee") }
@@ -161,9 +149,6 @@ class XmlExternalCallee extends XmlCallee {
}
}
-/** DEPRECATED: Alias for XmlExternalCallee */
-deprecated class XMLExternalCallee = XmlExternalCallee;
-
/**
* Helper predicate. If parent = `builtins` and qualname = `list.append`, it will
* return the result of `builtins.list.append`.class
From 42d67d0137d806a63c48eec662a0df3fe3d20f7a Mon Sep 17 00:00:00 2001
From: erik-krogh
Date: Fri, 9 Jun 2023 15:24:12 +0200
Subject: [PATCH 20/21] add change-note
---
python/ql/lib/change-notes/2023-06-09-delete-deps.md | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 python/ql/lib/change-notes/2023-06-09-delete-deps.md
diff --git a/python/ql/lib/change-notes/2023-06-09-delete-deps.md b/python/ql/lib/change-notes/2023-06-09-delete-deps.md
new file mode 100644
index 00000000000..75753ea93b7
--- /dev/null
+++ b/python/ql/lib/change-notes/2023-06-09-delete-deps.md
@@ -0,0 +1,9 @@
+---
+category: minorAnalysis
+---
+* Deleted many deprecated predicates and classes with uppercase `API`, `HTTP`, `XSS`, `SQL`, etc. in their names. Use the PascalCased versions instead.
+* Deleted the deprecated `getName()` predicate from the `Container` class, use `getAbsolutePath()` instead.
+* Deleted many deprecated module names that started with a lowercase letter, use the versions that start with an uppercase letter instead.
+* Deleted many deprecated predicates in `PointsTo.qll`.
+* Deleted many deprecated files from the `semmle.python.security` package.
+* Deleted the deprecated `BottleRoutePointToExtension` class from `Extensions.qll`.
\ No newline at end of file
From a628384d836f02293507259e3f6a504529c605db Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 12 Jun 2023 00:18:38 +0000
Subject: [PATCH 21/21] Add changed framework coverage reports
---
java/documentation/library-coverage/coverage.csv | 2 +-
java/documentation/library-coverage/coverage.rst | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv
index acfd9b9224c..447797aff24 100644
--- a/java/documentation/library-coverage/coverage.csv
+++ b/java/documentation/library-coverage/coverage.csv
@@ -58,7 +58,7 @@ java.io,49,,45,,22,,,,,,,,,,,,,,27,,,,,,,,,,,,,,,,,,,43,2
java.lang,18,,92,,,,,,,,,,,,,8,,,5,,,4,,,1,,,,,,,,,,,,,56,36
java.net,13,3,20,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,20,
java.nio,47,,35,,3,,,,,,,,,,,,,,44,,,,,,,,,,,,,,,,,,,35,
-java.sql,13,,3,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2,1
+java.sql,13,,2,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2,
java.util,44,,484,,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,44,440
javafx.scene.web,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,
javax.faces.context,2,7,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,
diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst
index 3e2043369dc..8464e0ca23e 100644
--- a/java/documentation/library-coverage/coverage.rst
+++ b/java/documentation/library-coverage/coverage.rst
@@ -18,10 +18,10 @@ Java framework & library support
`Google Guava `_,``com.google.common.*``,,730,41,7,,,,,
JBoss Logging,``org.jboss.logging``,,,324,,,,,,
`JSON-java `_,``org.json``,,236,,,,,,,
- Java Standard Library,``java.*``,3,683,184,76,,9,,,17
+ Java Standard Library,``java.*``,3,682,184,76,,9,,,17
Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,2,4,,1,1,2
Kotlin Standard Library,``kotlin*``,,1847,16,14,,,,,2
`Spring `_,``org.springframework.*``,29,483,115,4,,28,14,,35
Others,"``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,899,528,66,,18,18,,195
- Totals,,255,9199,1997,263,10,122,33,1,385
+ Totals,,255,9198,1997,263,10,122,33,1,385