From 30cd447f69c1bacf0451394d42c54644931167b6 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 26 Oct 2022 11:55:16 -0400 Subject: [PATCH 01/93] Java: Add class to represent `android.webkit.WebView#addJavascriptInterface` --- .../lib/semmle/code/java/frameworks/android/WebView.qll | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/WebView.qll b/java/ql/lib/semmle/code/java/frameworks/android/WebView.qll index 8dd91f73f65..cb595e19f6f 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/WebView.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/WebView.qll @@ -39,6 +39,14 @@ class WebViewGetUrlMethod extends Method { } } +/** The method `addJavascriptInterface` of the class `android.webkit.WebView` */ +class WebViewAddJavascriptInterfaceMethod extends Method { + WebViewAddJavascriptInterfaceMethod() { + this.getDeclaringType() instanceof TypeWebView and + this.hasName("addJavascriptInterface") + } +} + /** * A method allowing any-local-file and cross-origin access in the class `android.webkit.WebSettings`. */ From e1ff04cd952225bd8a9cbd8074a210b0475694a5 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 26 Oct 2022 11:55:54 -0400 Subject: [PATCH 02/93] Java: Query for `android.webkit.WebView#addJavascriptInterface` --- .../AndroidWebViewAddJavascriptInterface.ql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql new file mode 100644 index 00000000000..59fd195d7d0 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql @@ -0,0 +1,17 @@ +/** + * @id java/android-webview-addjavascriptinterface + * @description Exposing a Javascript interface to a Java object in a WebView can lead to malicious JavaScript controlling the application. + * @kind problem + * @problem.severity warning + * @security-severity 6.1 + * @precision high + * @tags security + * external/cwe/cwe-079 + */ + +import java +import semmle.code.java.frameworks.android.WebView + +from MethodAccess ma +where ma.getMethod() instanceof WebViewAddJavascriptInterfaceMethod +select ma, "JavaScript interface to Java object added in Android WebView." From e09f0861f319e1e9acbcddebc9d137dda0a3ee1b Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Fri, 11 Nov 2022 23:00:55 -0500 Subject: [PATCH 03/93] Java: documentation for WebView#addJavascriptInterface query --- ...AndroidWebViewAddJavascriptInterface.qhelp | 40 +++++++++++++++++++ ...dWebViewAddJavascriptInterfaceExample.java | 11 +++++ 2 files changed, 51 insertions(+) create mode 100644 java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.qhelp create mode 100644 java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterfaceExample.java diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.qhelp b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.qhelp new file mode 100644 index 00000000000..5cadc31d810 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.qhelp @@ -0,0 +1,40 @@ + + + +

+ The addJavascriptInterface method of + the android.webkit.WebView class allows the web pages of a + WebView to access methods of a Java object via JavaScript. +

+ +

+ Objects exposed to Javascript are available in all frames of the + WebView. +

+
+ + +

+ If you need to expose Java objects with Javascript, you should guarantee + that no untrusted third party content is loaded into the WebView. +

+
+ + +

+ In the following (bad) example, a Java object is exposed to Javascript. +

+ + + +
+ + +
  • + Android DocumentationaddJavascriptInterface +
  • +
    + +
    diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterfaceExample.java b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterfaceExample.java new file mode 100644 index 00000000000..fdb1844d025 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterfaceExample.java @@ -0,0 +1,11 @@ +class ExposedObject { + @JavascriptInterface + public String example() { + return "String from Java"; + } +} + +webview.getSettings().setJavaScriptEnabled(true); +webview.addJavaScriptInterface(new ExposedObject(), "exposedObject"); +webview.loadData("", "text/html", null); +webview.loadUrl("javascript:alert(exposedObject.example())"); From 3b96fefc71b5bbbeb044f40be6385c54c7809108 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 15 Nov 2022 23:26:49 -0500 Subject: [PATCH 04/93] Java: Add Android stubs to options file for CWE-079 test cases --- java/ql/test/query-tests/security/CWE-079/semmle/tests/options | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/options b/java/ql/test/query-tests/security/CWE-079/semmle/tests/options index 22487fb2daf..62fc56e6792 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/options +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/:${testdir}/../../../../../stubs/springframework-5.3.8:${testdir}/../../../../../stubs/javax-faces-2.3/ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/:${testdir}/../../../../../stubs/springframework-5.3.8:${testdir}/../../../../../stubs/javax-faces-2.3/:${testdir}/../../../../../stubs/google-android-9.0.0 From eb8ef72e477371dbd62362757a937756ec4ee46e Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 15 Nov 2022 23:28:18 -0500 Subject: [PATCH 05/93] Java: addJavascriptInterface query test case --- .../tests/WebViewAddJavascriptInterface.expected | 1 + .../semmle/tests/WebViewAddJavascriptInterface.java | 12 ++++++++++++ .../semmle/tests/WebViewAddJavascriptInterface.qlref | 1 + 3 files changed, 14 insertions(+) create mode 100644 java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.expected create mode 100644 java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.java create mode 100644 java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.qlref diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.expected b/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.expected new file mode 100644 index 00000000000..6974a4a8511 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.expected @@ -0,0 +1 @@ +| WebViewAddJavascriptInterface.java:10:9:10:61 | addJavascriptInterface(...) | JavaScript interface to Java object added in Android WebView. | diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.java b/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.java new file mode 100644 index 00000000000..50fc3847705 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.java @@ -0,0 +1,12 @@ +package com.example.test; + +import android.webkit.WebView; + +class WebViewAddJavascriptInterface { + class Greeter { + } + + public void addGreeter(WebView view) { + view.addJavascriptInterface(new Greeter(), "greeter"); + } +} diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.qlref b/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.qlref new file mode 100644 index 00000000000..1161c47dda6 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewAddJavascriptInterface.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql From 38d47d63ec92906962e25c8334ad2590d205337c Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 15 Nov 2022 23:40:03 -0500 Subject: [PATCH 06/93] Java: Add change note for `addJavascriptInterface` query --- .../2022-11-15-android-webview-addjavascript-interface.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 java/ql/src/change-notes/2022-11-15-android-webview-addjavascript-interface.md diff --git a/java/ql/src/change-notes/2022-11-15-android-webview-addjavascript-interface.md b/java/ql/src/change-notes/2022-11-15-android-webview-addjavascript-interface.md new file mode 100644 index 00000000000..ad2c46585f2 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-15-android-webview-addjavascript-interface.md @@ -0,0 +1,5 @@ +--- +category: newQuery +--- +* Added a new query `java/android-webview-addjavascriptinterface` to detect the use of `addJavascriptInterface`, which can lead to cross-site scripting. + From d35321f40eb6676f3874bfd3b5531d3cec9fc1b1 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 30 Nov 2022 11:35:14 -0500 Subject: [PATCH 07/93] Java: change WebView addJavascriptInterface query precision to medium --- .../CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql index 59fd195d7d0..d481de249ca 100644 --- a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql @@ -4,7 +4,7 @@ * @kind problem * @problem.severity warning * @security-severity 6.1 - * @precision high + * @precision medium * @tags security * external/cwe/cwe-079 */ From 04829fc38e6de25474416cd013a64404693a657c Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 30 Nov 2022 13:32:28 -0500 Subject: [PATCH 08/93] Java: SQLInjection example for addJavaScriptInterface query --- ...dWebViewAddJavascriptInterfaceExample.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterfaceExample.java b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterfaceExample.java index fdb1844d025..fb4e1182a5a 100644 --- a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterfaceExample.java +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterfaceExample.java @@ -1,11 +1,23 @@ -class ExposedObject { +import android.webkit.JavascriptInterface; +import android.database.sqlite.SQLiteOpenHelper; + +class ExposedObject extends SQLiteOpenHelper { @JavascriptInterface - public String example() { - return "String from Java"; + public String studentEmail(String studentName) { + // SQL injection + String query = "SELECT email FROM students WHERE studentname = '" + studentName + "'"; + + Cursor cursor = db.rawQuery(query, null); + cursor.moveToFirst(); + String email = cursor.getString(0); + + return email; } } webview.getSettings().setJavaScriptEnabled(true); webview.addJavaScriptInterface(new ExposedObject(), "exposedObject"); webview.loadData("", "text/html", null); -webview.loadUrl("javascript:alert(exposedObject.example())"); + +String name = "Robert'; DROP TABLE students; --"; +webview.loadUrl("javascript:alert(exposedObject.studentEmail(\""+ name +"\"))"); From 66946ebf6a60cd0f948f4ad860d9a589cc18b108 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 5 Dec 2022 21:40:43 +0100 Subject: [PATCH 09/93] add Kernel methods as sinks to path-injection --- .../ql/lib/codeql/ruby/frameworks/core/Kernel.qll | 15 +++++++++++++++ .../security/cwe-022/PathInjection.expected | 11 +++++++++++ .../query-tests/security/cwe-022/tainted_path.rb | 7 +++++++ 3 files changed, 33 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll index 71013f43936..5fc9d6eef29 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll @@ -179,4 +179,19 @@ module Kernel { preservesValue = true } } + + /** A call to e.g. `Kernel.load` that accesses a file. */ + private class KernelFileAccess extends FileSystemAccess::Range instanceof KernelMethodCall { + KernelFileAccess() { + super.getMethodName() = ["load", "require", "require_relative", "autoload", "autoload?"] + } + + override DataFlow::Node getAPathArgument() { + result = super.getArgument(0) and + super.getMethodName() = ["load", "require", "require_relative"] + or + result = super.getArgument(1) and + super.getMethodName() = ["autoload", "autoload?"] + } + } } diff --git a/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected b/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected index ffb851c35ed..ee774315767 100644 --- a/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected @@ -43,6 +43,10 @@ edges | tainted_path.rb:77:12:77:53 | call to new : | tainted_path.rb:79:14:79:17 | path | | tainted_path.rb:77:40:77:45 | call to params : | tainted_path.rb:77:40:77:52 | ...[...] : | | tainted_path.rb:77:40:77:52 | ...[...] : | tainted_path.rb:77:12:77:53 | call to new : | +| tainted_path.rb:84:12:84:53 | call to new : | tainted_path.rb:85:10:85:13 | path | +| tainted_path.rb:84:12:84:53 | call to new : | tainted_path.rb:86:25:86:28 | path | +| tainted_path.rb:84:40:84:45 | call to params : | tainted_path.rb:84:40:84:52 | ...[...] : | +| tainted_path.rb:84:40:84:52 | ...[...] : | tainted_path.rb:84:12:84:53 | call to new : | nodes | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params : | semmle.label | call to params : | | ArchiveApiPathTraversal.rb:5:26:5:42 | ...[...] : | semmle.label | ...[...] : | @@ -102,6 +106,11 @@ nodes | tainted_path.rb:77:40:77:52 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:78:19:78:22 | path | semmle.label | path | | tainted_path.rb:79:14:79:17 | path | semmle.label | path | +| tainted_path.rb:84:12:84:53 | call to new : | semmle.label | call to new : | +| tainted_path.rb:84:40:84:45 | call to params : | semmle.label | call to params : | +| tainted_path.rb:84:40:84:52 | ...[...] : | semmle.label | ...[...] : | +| tainted_path.rb:85:10:85:13 | path | semmle.label | path | +| tainted_path.rb:86:25:86:28 | path | semmle.label | path | subpaths #select | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params : | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | This path depends on a $@. | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | user-provided value | @@ -119,3 +128,5 @@ subpaths | tainted_path.rb:72:15:72:18 | path | tainted_path.rb:71:40:71:45 | call to params : | tainted_path.rb:72:15:72:18 | path | This path depends on a $@. | tainted_path.rb:71:40:71:45 | call to params | user-provided value | | tainted_path.rb:78:19:78:22 | path | tainted_path.rb:77:40:77:45 | call to params : | tainted_path.rb:78:19:78:22 | path | This path depends on a $@. | tainted_path.rb:77:40:77:45 | call to params | user-provided value | | tainted_path.rb:79:14:79:17 | path | tainted_path.rb:77:40:77:45 | call to params : | tainted_path.rb:79:14:79:17 | path | This path depends on a $@. | tainted_path.rb:77:40:77:45 | call to params | user-provided value | +| tainted_path.rb:85:10:85:13 | path | tainted_path.rb:84:40:84:45 | call to params : | tainted_path.rb:85:10:85:13 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value | +| tainted_path.rb:86:25:86:28 | path | tainted_path.rb:84:40:84:45 | call to params : | tainted_path.rb:86:25:86:28 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-022/tainted_path.rb b/ruby/ql/test/query-tests/security/cwe-022/tainted_path.rb index a19532fb542..495b7324e37 100644 --- a/ruby/ql/test/query-tests/security/cwe-022/tainted_path.rb +++ b/ruby/ql/test/query-tests/security/cwe-022/tainted_path.rb @@ -78,4 +78,11 @@ class FooController < ActionController::Base bla (Dir.glob path) bla (Dir[path]) end + + # BAD + def route13 + path = ActiveStorage::Filename.new(params[:path]) + load(path) + autoload(:MyModule, path) + end end From 5849b2c98aa6326832be68409df7c5d60ea68d01 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 6 Dec 2022 14:09:39 +0100 Subject: [PATCH 10/93] drive-by: simplify the imports in PathInjection.ql --- ruby/ql/src/queries/security/cwe-022/PathInjection.ql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ruby/ql/src/queries/security/cwe-022/PathInjection.ql b/ruby/ql/src/queries/security/cwe-022/PathInjection.ql index 58dad87fae4..09e17a5ed01 100644 --- a/ruby/ql/src/queries/security/cwe-022/PathInjection.ql +++ b/ruby/ql/src/queries/security/cwe-022/PathInjection.ql @@ -15,9 +15,8 @@ * external/cwe/cwe-099 */ -import codeql.ruby.AST +import ruby import codeql.ruby.security.PathInjectionQuery -import codeql.ruby.DataFlow import DataFlow::PathGraph from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink From e24f041661dfb8a5e00ae00206f1560dd779fc40 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 6 Dec 2022 14:21:48 +0100 Subject: [PATCH 11/93] drive-by: use `instanceof KernelMethodCall` such that `override getAnArgument` cannot be mistaken for a method in `CallNode` --- .../lib/codeql/ruby/frameworks/core/Kernel.qll | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll index 5fc9d6eef29..d36b239fce4 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll @@ -92,14 +92,14 @@ module Kernel { * ``` * Ruby documentation: https://docs.ruby-lang.org/en/3.0.0/Kernel.html#method-i-system */ - class KernelSystemCall extends SystemCommandExecution::Range, KernelMethodCall { + class KernelSystemCall extends SystemCommandExecution::Range instanceof KernelMethodCall { KernelSystemCall() { this.getMethodName() = "system" } - override DataFlow::Node getAnArgument() { result = this.getArgument(_) } + override DataFlow::Node getAnArgument() { result = super.getArgument(_) } override predicate isShellInterpreted(DataFlow::Node arg) { // Kernel.system invokes a subshell if you provide a single string as argument - this.getNumberOfArguments() = 1 and arg = this.getAnArgument() + super.getNumberOfArguments() = 1 and arg = this.getAnArgument() } } @@ -108,14 +108,14 @@ module Kernel { * `Kernel.exec` takes the same argument forms as `Kernel.system`. See `KernelSystemCall` for details. * Ruby documentation: https://docs.ruby-lang.org/en/3.0.0/Kernel.html#method-i-exec */ - class KernelExecCall extends SystemCommandExecution::Range, KernelMethodCall { + class KernelExecCall extends SystemCommandExecution::Range instanceof KernelMethodCall { KernelExecCall() { this.getMethodName() = "exec" } - override DataFlow::Node getAnArgument() { result = this.getArgument(_) } + override DataFlow::Node getAnArgument() { result = super.getArgument(_) } override predicate isShellInterpreted(DataFlow::Node arg) { // Kernel.exec invokes a subshell if you provide a single string as argument - this.getNumberOfArguments() = 1 and arg = this.getAnArgument() + super.getNumberOfArguments() = 1 and arg = this.getAnArgument() } } @@ -129,14 +129,14 @@ module Kernel { * spawn([env,] command... [,options]) -> pid * ``` */ - class KernelSpawnCall extends SystemCommandExecution::Range, KernelMethodCall { + class KernelSpawnCall extends SystemCommandExecution::Range instanceof KernelMethodCall { KernelSpawnCall() { this.getMethodName() = "spawn" } - override DataFlow::Node getAnArgument() { result = this.getArgument(_) } + override DataFlow::Node getAnArgument() { result = super.getArgument(_) } override predicate isShellInterpreted(DataFlow::Node arg) { // Kernel.spawn invokes a subshell if you provide a single string as argument - this.getNumberOfArguments() = 1 and arg = this.getAnArgument() + super.getNumberOfArguments() = 1 and arg = this.getAnArgument() } } From 0e9cd1e4b544441f0da40758ebb5e2f46af7ccd6 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 6 Dec 2022 13:58:16 +0100 Subject: [PATCH 12/93] factor out methodName to a field in KernelMethodCall --- .../codeql/ruby/frameworks/core/Kernel.qll | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll index d36b239fce4..1b4573c9ffa 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll @@ -18,17 +18,26 @@ module Kernel { * providing a specific receiver as in `Kernel.exit`. */ class KernelMethodCall extends DataFlow::CallNode { + string methodName; + KernelMethodCall() { - this = API::getTopLevelMember("Kernel").getAMethodCall(_) + this = API::getTopLevelMember("Kernel").getAMethodCall(methodName) or this.asExpr().getExpr() instanceof UnknownMethodCall and + methodName = super.getMethodName() and ( this.getReceiver().asExpr().getExpr() instanceof SelfVariableAccess and - isPrivateKernelMethod(this.getMethodName()) + isPrivateKernelMethod(methodName) or - isPublicKernelMethod(this.getMethodName()) + isPublicKernelMethod(methodName) ) } + + /** + * Gets which method of `Kernel` is called. + * Works even when the call is a `super(...)` call. + */ + string getKernelMethod() { result = methodName } } /** @@ -93,7 +102,7 @@ module Kernel { * Ruby documentation: https://docs.ruby-lang.org/en/3.0.0/Kernel.html#method-i-system */ class KernelSystemCall extends SystemCommandExecution::Range instanceof KernelMethodCall { - KernelSystemCall() { this.getMethodName() = "system" } + KernelSystemCall() { this.getKernelMethod() = "system" } override DataFlow::Node getAnArgument() { result = super.getArgument(_) } @@ -109,7 +118,7 @@ module Kernel { * Ruby documentation: https://docs.ruby-lang.org/en/3.0.0/Kernel.html#method-i-exec */ class KernelExecCall extends SystemCommandExecution::Range instanceof KernelMethodCall { - KernelExecCall() { this.getMethodName() = "exec" } + KernelExecCall() { this.getKernelMethod() = "exec" } override DataFlow::Node getAnArgument() { result = super.getArgument(_) } @@ -130,7 +139,7 @@ module Kernel { * ``` */ class KernelSpawnCall extends SystemCommandExecution::Range instanceof KernelMethodCall { - KernelSpawnCall() { this.getMethodName() = "spawn" } + KernelSpawnCall() { this.getKernelMethod() = "spawn" } override DataFlow::Node getAnArgument() { result = super.getArgument(_) } @@ -149,7 +158,7 @@ module Kernel { * ``` */ class EvalCallCodeExecution extends CodeExecution::Range, KernelMethodCall { - EvalCallCodeExecution() { this.getMethodName() = "eval" } + EvalCallCodeExecution() { this.getKernelMethod() = "eval" } override DataFlow::Node getCode() { result = this.getArgument(0) } } @@ -163,7 +172,7 @@ module Kernel { * ``` */ class SendCallCodeExecution extends CodeExecution::Range, KernelMethodCall { - SendCallCodeExecution() { this.getMethodName() = "send" } + SendCallCodeExecution() { this.getKernelMethod() = "send" } override DataFlow::Node getCode() { result = this.getArgument(0) } @@ -183,15 +192,15 @@ module Kernel { /** A call to e.g. `Kernel.load` that accesses a file. */ private class KernelFileAccess extends FileSystemAccess::Range instanceof KernelMethodCall { KernelFileAccess() { - super.getMethodName() = ["load", "require", "require_relative", "autoload", "autoload?"] + super.getKernelMethod() = ["load", "require", "require_relative", "autoload", "autoload?"] } override DataFlow::Node getAPathArgument() { result = super.getArgument(0) and - super.getMethodName() = ["load", "require", "require_relative"] + super.getKernelMethod() = ["load", "require", "require_relative"] or result = super.getArgument(1) and - super.getMethodName() = ["autoload", "autoload?"] + super.getKernelMethod() = ["autoload", "autoload?"] } } } From 8f0c0f3c174dae34380b332c237da6a78a968d79 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 6 Dec 2022 14:08:04 +0100 Subject: [PATCH 13/93] add support for super calls to Kernel --- ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll | 10 +++++++++- .../security/cwe-022/PathInjection.expected | 8 ++++++++ .../test/query-tests/security/cwe-022/tainted_path.rb | 6 ++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll index 1b4573c9ffa..6f66c40f89a 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll @@ -24,11 +24,19 @@ module Kernel { this = API::getTopLevelMember("Kernel").getAMethodCall(methodName) or this.asExpr().getExpr() instanceof UnknownMethodCall and - methodName = super.getMethodName() and + ( + methodName = super.getMethodName() + or + this.asExpr().getExpr() instanceof SuperCall and + methodName = this.asExpr().getExpr().getEnclosingCallable().(MethodBase).getName() + ) and ( this.getReceiver().asExpr().getExpr() instanceof SelfVariableAccess and isPrivateKernelMethod(methodName) or + this.asExpr().getExpr() instanceof SuperCall and + isPrivateKernelMethod(methodName) + or isPublicKernelMethod(methodName) ) } diff --git a/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected b/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected index ee774315767..5e05271252e 100644 --- a/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected @@ -47,6 +47,9 @@ edges | tainted_path.rb:84:12:84:53 | call to new : | tainted_path.rb:86:25:86:28 | path | | tainted_path.rb:84:40:84:45 | call to params : | tainted_path.rb:84:40:84:52 | ...[...] : | | tainted_path.rb:84:40:84:52 | ...[...] : | tainted_path.rb:84:12:84:53 | call to new : | +| tainted_path.rb:90:12:90:53 | call to new : | tainted_path.rb:92:11:92:14 | path | +| tainted_path.rb:90:40:90:45 | call to params : | tainted_path.rb:90:40:90:52 | ...[...] : | +| tainted_path.rb:90:40:90:52 | ...[...] : | tainted_path.rb:90:12:90:53 | call to new : | nodes | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params : | semmle.label | call to params : | | ArchiveApiPathTraversal.rb:5:26:5:42 | ...[...] : | semmle.label | ...[...] : | @@ -111,6 +114,10 @@ nodes | tainted_path.rb:84:40:84:52 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:85:10:85:13 | path | semmle.label | path | | tainted_path.rb:86:25:86:28 | path | semmle.label | path | +| tainted_path.rb:90:12:90:53 | call to new : | semmle.label | call to new : | +| tainted_path.rb:90:40:90:45 | call to params : | semmle.label | call to params : | +| tainted_path.rb:90:40:90:52 | ...[...] : | semmle.label | ...[...] : | +| tainted_path.rb:92:11:92:14 | path | semmle.label | path | subpaths #select | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params : | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | This path depends on a $@. | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | user-provided value | @@ -130,3 +137,4 @@ subpaths | tainted_path.rb:79:14:79:17 | path | tainted_path.rb:77:40:77:45 | call to params : | tainted_path.rb:79:14:79:17 | path | This path depends on a $@. | tainted_path.rb:77:40:77:45 | call to params | user-provided value | | tainted_path.rb:85:10:85:13 | path | tainted_path.rb:84:40:84:45 | call to params : | tainted_path.rb:85:10:85:13 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value | | tainted_path.rb:86:25:86:28 | path | tainted_path.rb:84:40:84:45 | call to params : | tainted_path.rb:86:25:86:28 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value | +| tainted_path.rb:92:11:92:14 | path | tainted_path.rb:90:40:90:45 | call to params : | tainted_path.rb:92:11:92:14 | path | This path depends on a $@. | tainted_path.rb:90:40:90:45 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-022/tainted_path.rb b/ruby/ql/test/query-tests/security/cwe-022/tainted_path.rb index 495b7324e37..d47607e6734 100644 --- a/ruby/ql/test/query-tests/security/cwe-022/tainted_path.rb +++ b/ruby/ql/test/query-tests/security/cwe-022/tainted_path.rb @@ -85,4 +85,10 @@ class FooController < ActionController::Base load(path) autoload(:MyModule, path) end + + def require_relative() + path = ActiveStorage::Filename.new(params[:path]) + puts "Debug: require_relative(#{path})" + super(path) + end end From 52c0afa03fbf750a5828d8e06fd65c2d7ce8ee69 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 7 Dec 2022 10:27:35 +0100 Subject: [PATCH 14/93] change `getMethodName` to `getKernelMethod` in other files --- ruby/ql/lib/codeql/ruby/frameworks/core/internal/IOOrFile.qll | 2 +- ruby/ql/lib/codeql/ruby/security/KernelOpenQuery.qll | 2 +- .../codeql/ruby/security/StackTraceExposureCustomizations.qll | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/internal/IOOrFile.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/internal/IOOrFile.qll index 25bd4474ce6..d9201f1c8c5 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/internal/IOOrFile.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/internal/IOOrFile.qll @@ -29,7 +29,7 @@ DataFlow::Node fileInstanceInstantiation() { result = API::getTopLevelMember("File").getAMethodCall(["open", "try_convert"]) or // Calls to `Kernel.open` can yield `File` instances - result.(KernelMethodCall).getMethodName() = "open" and + result.(KernelMethodCall).getKernelMethod() = "open" and // Assume that calls that don't invoke shell commands will instead open // a file. not pathArgSpawnsSubprocess(result.(KernelMethodCall).getArgument(0).asExpr().getExpr()) diff --git a/ruby/ql/lib/codeql/ruby/security/KernelOpenQuery.qll b/ruby/ql/lib/codeql/ruby/security/KernelOpenQuery.qll index 309a26ac9df..260bb2a678d 100644 --- a/ruby/ql/lib/codeql/ruby/security/KernelOpenQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/KernelOpenQuery.qll @@ -13,7 +13,7 @@ class AmbiguousPathCall extends DataFlow::CallNode { string name; AmbiguousPathCall() { - this.(KernelMethodCall).getMethodName() = "open" and + this.(KernelMethodCall).getKernelMethod() = "open" and name = "Kernel.open" or this = API::getTopLevelMember("IO").getAMethodCall("read") and diff --git a/ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll index 9a25dda844d..789c568ea0c 100644 --- a/ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll @@ -41,8 +41,8 @@ module StackTraceExposure { /** * A call to `Kernel#caller`, considered as a flow source. */ - class KernelCallerCall extends Source, Kernel::KernelMethodCall { - KernelCallerCall() { this.getMethodName() = "caller" } + class KernelCallerCall extends Source instanceof Kernel::KernelMethodCall { + KernelCallerCall() { super.getKernelMethod() = "caller" } } /** From 360a99f026b48869b67a4a1d856f00820a762556 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 7 Dec 2022 13:14:48 +0100 Subject: [PATCH 15/93] delete `getKernelMethod` and don't special-case the methodName on super-calls in the `Kernel` model --- .../codeql/ruby/frameworks/core/Kernel.qll | 38 ++++++------------- .../frameworks/core/internal/IOOrFile.qll | 2 +- .../codeql/ruby/security/KernelOpenQuery.qll | 2 +- .../StackTraceExposureCustomizations.qll | 2 +- 4 files changed, 15 insertions(+), 29 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll index 6f66c40f89a..bf487904134 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/Kernel.qll @@ -18,34 +18,20 @@ module Kernel { * providing a specific receiver as in `Kernel.exit`. */ class KernelMethodCall extends DataFlow::CallNode { - string methodName; - KernelMethodCall() { - this = API::getTopLevelMember("Kernel").getAMethodCall(methodName) + this = API::getTopLevelMember("Kernel").getAMethodCall(_) or this.asExpr().getExpr() instanceof UnknownMethodCall and - ( - methodName = super.getMethodName() - or - this.asExpr().getExpr() instanceof SuperCall and - methodName = this.asExpr().getExpr().getEnclosingCallable().(MethodBase).getName() - ) and ( this.getReceiver().asExpr().getExpr() instanceof SelfVariableAccess and - isPrivateKernelMethod(methodName) + isPrivateKernelMethod(super.getMethodName()) or this.asExpr().getExpr() instanceof SuperCall and - isPrivateKernelMethod(methodName) + isPrivateKernelMethod(super.getMethodName()) or - isPublicKernelMethod(methodName) + isPublicKernelMethod(super.getMethodName()) ) } - - /** - * Gets which method of `Kernel` is called. - * Works even when the call is a `super(...)` call. - */ - string getKernelMethod() { result = methodName } } /** @@ -110,7 +96,7 @@ module Kernel { * Ruby documentation: https://docs.ruby-lang.org/en/3.0.0/Kernel.html#method-i-system */ class KernelSystemCall extends SystemCommandExecution::Range instanceof KernelMethodCall { - KernelSystemCall() { this.getKernelMethod() = "system" } + KernelSystemCall() { this.getMethodName() = "system" } override DataFlow::Node getAnArgument() { result = super.getArgument(_) } @@ -126,7 +112,7 @@ module Kernel { * Ruby documentation: https://docs.ruby-lang.org/en/3.0.0/Kernel.html#method-i-exec */ class KernelExecCall extends SystemCommandExecution::Range instanceof KernelMethodCall { - KernelExecCall() { this.getKernelMethod() = "exec" } + KernelExecCall() { this.getMethodName() = "exec" } override DataFlow::Node getAnArgument() { result = super.getArgument(_) } @@ -147,7 +133,7 @@ module Kernel { * ``` */ class KernelSpawnCall extends SystemCommandExecution::Range instanceof KernelMethodCall { - KernelSpawnCall() { this.getKernelMethod() = "spawn" } + KernelSpawnCall() { this.getMethodName() = "spawn" } override DataFlow::Node getAnArgument() { result = super.getArgument(_) } @@ -166,7 +152,7 @@ module Kernel { * ``` */ class EvalCallCodeExecution extends CodeExecution::Range, KernelMethodCall { - EvalCallCodeExecution() { this.getKernelMethod() = "eval" } + EvalCallCodeExecution() { this.getMethodName() = "eval" } override DataFlow::Node getCode() { result = this.getArgument(0) } } @@ -180,7 +166,7 @@ module Kernel { * ``` */ class SendCallCodeExecution extends CodeExecution::Range, KernelMethodCall { - SendCallCodeExecution() { this.getKernelMethod() = "send" } + SendCallCodeExecution() { this.getMethodName() = "send" } override DataFlow::Node getCode() { result = this.getArgument(0) } @@ -200,15 +186,15 @@ module Kernel { /** A call to e.g. `Kernel.load` that accesses a file. */ private class KernelFileAccess extends FileSystemAccess::Range instanceof KernelMethodCall { KernelFileAccess() { - super.getKernelMethod() = ["load", "require", "require_relative", "autoload", "autoload?"] + super.getMethodName() = ["load", "require", "require_relative", "autoload", "autoload?"] } override DataFlow::Node getAPathArgument() { result = super.getArgument(0) and - super.getKernelMethod() = ["load", "require", "require_relative"] + super.getMethodName() = ["load", "require", "require_relative"] or result = super.getArgument(1) and - super.getKernelMethod() = ["autoload", "autoload?"] + super.getMethodName() = ["autoload", "autoload?"] } } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/internal/IOOrFile.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/internal/IOOrFile.qll index d9201f1c8c5..25bd4474ce6 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/internal/IOOrFile.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/internal/IOOrFile.qll @@ -29,7 +29,7 @@ DataFlow::Node fileInstanceInstantiation() { result = API::getTopLevelMember("File").getAMethodCall(["open", "try_convert"]) or // Calls to `Kernel.open` can yield `File` instances - result.(KernelMethodCall).getKernelMethod() = "open" and + result.(KernelMethodCall).getMethodName() = "open" and // Assume that calls that don't invoke shell commands will instead open // a file. not pathArgSpawnsSubprocess(result.(KernelMethodCall).getArgument(0).asExpr().getExpr()) diff --git a/ruby/ql/lib/codeql/ruby/security/KernelOpenQuery.qll b/ruby/ql/lib/codeql/ruby/security/KernelOpenQuery.qll index 260bb2a678d..309a26ac9df 100644 --- a/ruby/ql/lib/codeql/ruby/security/KernelOpenQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/KernelOpenQuery.qll @@ -13,7 +13,7 @@ class AmbiguousPathCall extends DataFlow::CallNode { string name; AmbiguousPathCall() { - this.(KernelMethodCall).getKernelMethod() = "open" and + this.(KernelMethodCall).getMethodName() = "open" and name = "Kernel.open" or this = API::getTopLevelMember("IO").getAMethodCall("read") and diff --git a/ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll index 789c568ea0c..636a4ca5ac4 100644 --- a/ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll @@ -42,7 +42,7 @@ module StackTraceExposure { * A call to `Kernel#caller`, considered as a flow source. */ class KernelCallerCall extends Source instanceof Kernel::KernelMethodCall { - KernelCallerCall() { super.getKernelMethod() = "caller" } + KernelCallerCall() { super.getMethodName() = "caller" } } /** From ee8e0188a6c9a155aa936180ff6b272c0b052fd0 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 7 Dec 2022 13:23:18 +0100 Subject: [PATCH 16/93] remove redundant call, the charpred ensures it always holds --- ruby/ql/lib/codeql/ruby/ast/internal/Call.qll | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll index 9a1d41b097d..8ede4660152 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll @@ -78,12 +78,9 @@ class RegularMethodCall extends MethodCallImpl, TRegularMethodCall { } final override string getMethodNameImpl() { - isRegularMethodCall(g) and - ( - result = "call" and not exists(g.getMethod()) - or - result = g.getMethod().(Ruby::Token).getValue() - ) + result = "call" and not exists(g.getMethod()) + or + result = g.getMethod().(Ruby::Token).getValue() } final override Expr getArgumentImpl(int n) { toGenerated(result) = g.getArguments().getChild(n) } From 8ab31bbe1ce9904dee18c3f911e1289a544ec44e Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 7 Dec 2022 14:09:36 +0100 Subject: [PATCH 17/93] have `getMethodName` return the method being called for super-calls --- ruby/ql/lib/codeql/ruby/ast/Call.qll | 15 +++- ruby/ql/lib/codeql/ruby/ast/internal/Call.qll | 18 ++++- ruby/ql/test/library-tests/ast/Ast.expected | 22 ++--- .../library-tests/ast/calls/calls.expected | 80 +++++++++---------- .../controlflow/graph/Cfg.expected | 4 +- .../controlflow/graph/Nodes.expected | 2 +- .../library-tests/modules/callgraph.expected | 4 +- .../library-tests/modules/methods.expected | 4 +- .../library-tests/modules/modules.expected | 4 +- 9 files changed, 90 insertions(+), 63 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/Call.qll b/ruby/ql/lib/codeql/ruby/ast/Call.qll index 04ac15ededc..7f14dabc0a9 100644 --- a/ruby/ql/lib/codeql/ruby/ast/Call.qll +++ b/ruby/ql/lib/codeql/ruby/ast/Call.qll @@ -94,6 +94,15 @@ class MethodCall extends Call instanceof MethodCallImpl { * ``` * * the result is `"bar"`. + * + * Super calls call a method with the same name as the current method, so + * the result for a super call is the name of the current method. + * E.g: + * ```rb + * def foo + * super # the result for this super call is "foo" + * end + * ``` */ final string getMethodName() { result = super.getMethodNameImpl() } @@ -113,7 +122,11 @@ class MethodCall extends Call instanceof MethodCallImpl { */ final predicate isSafeNavigation() { super.isSafeNavigationImpl() } - override string toString() { result = "call to " + this.getMethodName() } + override string toString() { + if this instanceof SuperCall + then result = "super call to " + this.getMethodName() + else result = "call to " + this.getMethodName() + } override AstNode getAChild(string pred) { result = Call.super.getAChild(pred) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll index 8ede4660152..dfc553fb45d 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll @@ -112,12 +112,26 @@ class ElementReferenceImpl extends MethodCallImpl, TElementReference { abstract class SuperCallImpl extends MethodCallImpl, TSuperCall { } +private Ruby::AstNode getSuperParent(Ruby::Super sup) { + result = sup + or + result = getSuperParent(sup).getParent() and + not result instanceof Ruby::Method +} + +private string getSuperMethodName(Ruby::Super sup) { + exists(Ruby::Method meth | + meth = getSuperParent(sup).getParent().(Ruby::Method) and + result = any(Method c | toGenerated(c) = meth).getName() + ) +} + class TokenSuperCall extends SuperCallImpl, TTokenSuperCall { private Ruby::Super g; TokenSuperCall() { this = TTokenSuperCall(g) } - final override string getMethodNameImpl() { result = g.getValue() } + final override string getMethodNameImpl() { result = getSuperMethodName(g) } final override Expr getReceiverImpl() { none() } @@ -133,7 +147,7 @@ class RegularSuperCall extends SuperCallImpl, TRegularSuperCall { RegularSuperCall() { this = TRegularSuperCall(g) } - final override string getMethodNameImpl() { result = g.getMethod().(Ruby::Super).getValue() } + final override string getMethodNameImpl() { result = getSuperMethodName(g.getMethod()) } final override Expr getReceiverImpl() { none() } diff --git a/ruby/ql/test/library-tests/ast/Ast.expected b/ruby/ql/test/library-tests/ast/Ast.expected index 6701f5ce160..044c92b8ac3 100644 --- a/ruby/ql/test/library-tests/ast/Ast.expected +++ b/ruby/ql/test/library-tests/ast/Ast.expected @@ -496,30 +496,30 @@ calls/calls.rb: # 279| getReceiver: [ConstantReadAccess] X # 284| getStmt: [ClassDeclaration] MyClass # 285| getStmt: [Method] my_method -# 286| getStmt: [SuperCall] call to super -# 287| getStmt: [SuperCall] call to super -# 288| getStmt: [SuperCall] call to super +# 286| getStmt: [SuperCall] super call to my_method +# 287| getStmt: [SuperCall] super call to my_method +# 288| getStmt: [SuperCall] super call to my_method # 288| getArgument: [StringLiteral] "blah" # 288| getComponent: [StringTextComponent] blah -# 289| getStmt: [SuperCall] call to super +# 289| getStmt: [SuperCall] super call to my_method # 289| getArgument: [IntegerLiteral] 1 # 289| getArgument: [IntegerLiteral] 2 # 289| getArgument: [IntegerLiteral] 3 -# 290| getStmt: [SuperCall] call to super +# 290| getStmt: [SuperCall] super call to my_method # 290| getBlock: [BraceBlock] { ... } # 290| getParameter: [SimpleParameter] x # 290| getDefiningAccess: [LocalVariableAccess] x # 290| getStmt: [AddExpr] ... + ... # 290| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x # 290| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 -# 291| getStmt: [SuperCall] call to super +# 291| getStmt: [SuperCall] super call to my_method # 291| getBlock: [DoBlock] do ... end # 291| getParameter: [SimpleParameter] x # 291| getDefiningAccess: [LocalVariableAccess] x # 291| getStmt: [MulExpr] ... * ... # 291| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x # 291| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 2 -# 292| getStmt: [SuperCall] call to super +# 292| getStmt: [SuperCall] super call to my_method # 292| getArgument: [IntegerLiteral] 4 # 292| getArgument: [IntegerLiteral] 5 # 292| getBlock: [BraceBlock] { ... } @@ -528,7 +528,7 @@ calls/calls.rb: # 292| getStmt: [AddExpr] ... + ... # 292| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x # 292| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 100 -# 293| getStmt: [SuperCall] call to super +# 293| getStmt: [SuperCall] super call to my_method # 293| getArgument: [IntegerLiteral] 6 # 293| getArgument: [IntegerLiteral] 7 # 293| getBlock: [DoBlock] do ... end @@ -545,7 +545,7 @@ calls/calls.rb: # 304| getStmt: [MethodCall] call to super # 304| getReceiver: [SelfVariableAccess] self # 305| getStmt: [MethodCall] call to super -# 305| getReceiver: [SuperCall] call to super +# 305| getReceiver: [SuperCall] super call to another_method # 310| getStmt: [MethodCall] call to call # 310| getReceiver: [MethodCall] call to foo # 310| getReceiver: [SelfVariableAccess] self @@ -646,7 +646,7 @@ calls/calls.rb: # 328| getComponent: [StringTextComponent] error # 331| getStmt: [Method] foo # 331| getParameter: [ForwardParameter] ... -# 332| getStmt: [SuperCall] call to super +# 332| getStmt: [SuperCall] super call to foo # 332| getArgument: [ForwardedArguments] ... # 335| getStmt: [Method] foo # 335| getParameter: [SimpleParameter] a @@ -1293,7 +1293,7 @@ modules/classes.rb: # 42| getStmt: [Method] length # 43| getStmt: [MulExpr] ... * ... # 43| getAnOperand/getLeftOperand/getReceiver: [IntegerLiteral] 100 -# 43| getAnOperand/getArgument/getRightOperand: [SuperCall] call to super +# 43| getAnOperand/getArgument/getRightOperand: [SuperCall] super call to length # 46| getStmt: [Method] wibble # 47| getStmt: [MethodCall] call to puts # 47| getReceiver: [SelfVariableAccess] self diff --git a/ruby/ql/test/library-tests/ast/calls/calls.expected b/ruby/ql/test/library-tests/ast/calls/calls.expected index b56cbd61f37..048ebfcc280 100644 --- a/ruby/ql/test/library-tests/ast/calls/calls.expected +++ b/ruby/ql/test/library-tests/ast/calls/calls.expected @@ -1,8 +1,8 @@ callsWithNoReceiverArgumentsOrBlock | calls.rb:31:3:31:7 | yield ... | (none) | -| calls.rb:286:5:286:9 | call to super | super | -| calls.rb:287:5:287:11 | call to super | super | -| calls.rb:305:5:305:9 | call to super | super | +| calls.rb:286:5:286:9 | super call to my_method | my_method | +| calls.rb:287:5:287:11 | super call to my_method | my_method | +| calls.rb:305:5:305:9 | super call to another_method | another_method | | calls.rb:345:9:345:13 | call to novar | novar | callsWithArguments | calls.rb:14:1:14:11 | call to foo | foo | 0 | calls.rb:14:5:14:5 | 0 | @@ -34,17 +34,17 @@ callsWithArguments | calls.rb:275:1:275:13 | call to foo | foo | 0 | calls.rb:275:5:275:12 | ** ... | | calls.rb:278:1:278:14 | call to foo | foo | 0 | calls.rb:278:5:278:13 | Pair | | calls.rb:279:1:279:17 | call to foo | foo | 0 | calls.rb:279:5:279:16 | Pair | -| calls.rb:288:5:288:16 | call to super | super | 0 | calls.rb:288:11:288:16 | "blah" | -| calls.rb:289:5:289:17 | call to super | super | 0 | calls.rb:289:11:289:11 | 1 | -| calls.rb:289:5:289:17 | call to super | super | 1 | calls.rb:289:14:289:14 | 2 | -| calls.rb:289:5:289:17 | call to super | super | 2 | calls.rb:289:17:289:17 | 3 | +| calls.rb:288:5:288:16 | super call to my_method | my_method | 0 | calls.rb:288:11:288:16 | "blah" | +| calls.rb:289:5:289:17 | super call to my_method | my_method | 0 | calls.rb:289:11:289:11 | 1 | +| calls.rb:289:5:289:17 | super call to my_method | my_method | 1 | calls.rb:289:14:289:14 | 2 | +| calls.rb:289:5:289:17 | super call to my_method | my_method | 2 | calls.rb:289:17:289:17 | 3 | | calls.rb:290:17:290:21 | ... + ... | + | 0 | calls.rb:290:21:290:21 | 1 | | calls.rb:291:18:291:22 | ... * ... | * | 0 | calls.rb:291:22:291:22 | 2 | -| calls.rb:292:5:292:30 | call to super | super | 0 | calls.rb:292:11:292:11 | 4 | -| calls.rb:292:5:292:30 | call to super | super | 1 | calls.rb:292:14:292:14 | 5 | +| calls.rb:292:5:292:30 | super call to my_method | my_method | 0 | calls.rb:292:11:292:11 | 4 | +| calls.rb:292:5:292:30 | super call to my_method | my_method | 1 | calls.rb:292:14:292:14 | 5 | | calls.rb:292:22:292:28 | ... + ... | + | 0 | calls.rb:292:26:292:28 | 100 | -| calls.rb:293:5:293:33 | call to super | super | 0 | calls.rb:293:11:293:11 | 6 | -| calls.rb:293:5:293:33 | call to super | super | 1 | calls.rb:293:14:293:14 | 7 | +| calls.rb:293:5:293:33 | super call to my_method | my_method | 0 | calls.rb:293:11:293:11 | 6 | +| calls.rb:293:5:293:33 | super call to my_method | my_method | 1 | calls.rb:293:14:293:14 | 7 | | calls.rb:293:23:293:29 | ... + ... | + | 0 | calls.rb:293:27:293:29 | 200 | | calls.rb:311:1:311:7 | call to call | call | 0 | calls.rb:311:6:311:6 | 1 | | calls.rb:314:1:314:8 | call to foo= | foo= | 0 | calls.rb:314:12:314:13 | ... = ... | @@ -91,7 +91,7 @@ callsWithArguments | calls.rb:320:21:320:31 | ... + ... | + | 0 | calls.rb:320:31:320:31 | 1 | | calls.rb:320:34:320:35 | ... * ... | * | 0 | calls.rb:320:37:320:37 | 2 | | calls.rb:328:25:328:37 | call to print | print | 0 | calls.rb:328:31:328:37 | "error" | -| calls.rb:332:3:332:12 | call to super | super | 0 | calls.rb:332:9:332:11 | ... | +| calls.rb:332:3:332:12 | super call to foo | foo | 0 | calls.rb:332:9:332:11 | ... | | calls.rb:336:3:336:13 | call to bar | bar | 0 | calls.rb:336:7:336:7 | b | | calls.rb:336:3:336:13 | call to bar | bar | 1 | calls.rb:336:10:336:12 | ... | | calls.rb:340:5:340:5 | call to [] | [] | 0 | calls.rb:340:5:340:5 | 0 | @@ -305,7 +305,7 @@ callsWithReceiver | calls.rb:303:5:303:7 | call to foo | calls.rb:303:5:303:7 | self | | calls.rb:303:5:303:13 | call to super | calls.rb:303:5:303:7 | call to foo | | calls.rb:304:5:304:14 | call to super | calls.rb:304:5:304:8 | self | -| calls.rb:305:5:305:15 | call to super | calls.rb:305:5:305:9 | call to super | +| calls.rb:305:5:305:15 | call to super | calls.rb:305:5:305:9 | super call to another_method | | calls.rb:310:1:310:3 | call to foo | calls.rb:310:1:310:3 | self | | calls.rb:310:1:310:6 | call to call | calls.rb:310:1:310:3 | call to foo | | calls.rb:311:1:311:3 | call to foo | calls.rb:311:1:311:3 | self | @@ -398,10 +398,10 @@ callsWithBlock | calls.rb:95:1:98:3 | call to foo | calls.rb:95:7:98:3 | do ... end | | calls.rb:226:1:228:3 | call to each | calls.rb:226:1:228:3 | { ... } | | calls.rb:229:1:231:3 | call to each | calls.rb:229:1:231:3 | { ... } | -| calls.rb:290:5:290:23 | call to super | calls.rb:290:11:290:23 | { ... } | -| calls.rb:291:5:291:26 | call to super | calls.rb:291:11:291:26 | do ... end | -| calls.rb:292:5:292:30 | call to super | calls.rb:292:16:292:30 | { ... } | -| calls.rb:293:5:293:33 | call to super | calls.rb:293:16:293:33 | do ... end | +| calls.rb:290:5:290:23 | super call to my_method | calls.rb:290:11:290:23 | { ... } | +| calls.rb:291:5:291:26 | super call to my_method | calls.rb:291:11:291:26 | do ... end | +| calls.rb:292:5:292:30 | super call to my_method | calls.rb:292:16:292:30 | { ... } | +| calls.rb:293:5:293:33 | super call to my_method | calls.rb:293:16:293:33 | do ... end | | calls.rb:340:1:342:3 | call to each | calls.rb:340:1:342:3 | { ... } | | calls.rb:364:1:364:23 | call to bar | calls.rb:364:15:364:23 | { ... } | | calls.rb:364:1:364:23 | call to bar | calls.rb:364:15:364:23 | { ... } | @@ -409,31 +409,31 @@ yieldCalls | calls.rb:31:3:31:7 | yield ... | | calls.rb:36:3:36:16 | yield ... | superCalls -| calls.rb:286:5:286:9 | call to super | -| calls.rb:287:5:287:11 | call to super | -| calls.rb:288:5:288:16 | call to super | -| calls.rb:289:5:289:17 | call to super | -| calls.rb:290:5:290:23 | call to super | -| calls.rb:291:5:291:26 | call to super | -| calls.rb:292:5:292:30 | call to super | -| calls.rb:293:5:293:33 | call to super | -| calls.rb:305:5:305:9 | call to super | -| calls.rb:332:3:332:12 | call to super | +| calls.rb:286:5:286:9 | super call to my_method | +| calls.rb:287:5:287:11 | super call to my_method | +| calls.rb:288:5:288:16 | super call to my_method | +| calls.rb:289:5:289:17 | super call to my_method | +| calls.rb:290:5:290:23 | super call to my_method | +| calls.rb:291:5:291:26 | super call to my_method | +| calls.rb:292:5:292:30 | super call to my_method | +| calls.rb:293:5:293:33 | super call to my_method | +| calls.rb:305:5:305:9 | super call to another_method | +| calls.rb:332:3:332:12 | super call to foo | superCallsWithArguments -| calls.rb:288:5:288:16 | call to super | 0 | calls.rb:288:11:288:16 | "blah" | -| calls.rb:289:5:289:17 | call to super | 0 | calls.rb:289:11:289:11 | 1 | -| calls.rb:289:5:289:17 | call to super | 1 | calls.rb:289:14:289:14 | 2 | -| calls.rb:289:5:289:17 | call to super | 2 | calls.rb:289:17:289:17 | 3 | -| calls.rb:292:5:292:30 | call to super | 0 | calls.rb:292:11:292:11 | 4 | -| calls.rb:292:5:292:30 | call to super | 1 | calls.rb:292:14:292:14 | 5 | -| calls.rb:293:5:293:33 | call to super | 0 | calls.rb:293:11:293:11 | 6 | -| calls.rb:293:5:293:33 | call to super | 1 | calls.rb:293:14:293:14 | 7 | -| calls.rb:332:3:332:12 | call to super | 0 | calls.rb:332:9:332:11 | ... | +| calls.rb:288:5:288:16 | super call to my_method | 0 | calls.rb:288:11:288:16 | "blah" | +| calls.rb:289:5:289:17 | super call to my_method | 0 | calls.rb:289:11:289:11 | 1 | +| calls.rb:289:5:289:17 | super call to my_method | 1 | calls.rb:289:14:289:14 | 2 | +| calls.rb:289:5:289:17 | super call to my_method | 2 | calls.rb:289:17:289:17 | 3 | +| calls.rb:292:5:292:30 | super call to my_method | 0 | calls.rb:292:11:292:11 | 4 | +| calls.rb:292:5:292:30 | super call to my_method | 1 | calls.rb:292:14:292:14 | 5 | +| calls.rb:293:5:293:33 | super call to my_method | 0 | calls.rb:293:11:293:11 | 6 | +| calls.rb:293:5:293:33 | super call to my_method | 1 | calls.rb:293:14:293:14 | 7 | +| calls.rb:332:3:332:12 | super call to foo | 0 | calls.rb:332:9:332:11 | ... | superCallsWithBlock -| calls.rb:290:5:290:23 | call to super | calls.rb:290:11:290:23 | { ... } | -| calls.rb:291:5:291:26 | call to super | calls.rb:291:11:291:26 | do ... end | -| calls.rb:292:5:292:30 | call to super | calls.rb:292:16:292:30 | { ... } | -| calls.rb:293:5:293:33 | call to super | calls.rb:293:16:293:33 | do ... end | +| calls.rb:290:5:290:23 | super call to my_method | calls.rb:290:11:290:23 | { ... } | +| calls.rb:291:5:291:26 | super call to my_method | calls.rb:291:11:291:26 | do ... end | +| calls.rb:292:5:292:30 | super call to my_method | calls.rb:292:16:292:30 | { ... } | +| calls.rb:293:5:293:33 | super call to my_method | calls.rb:293:16:293:33 | do ... end | setterCalls | calls.rb:314:1:314:8 | call to foo= | | calls.rb:315:1:315:6 | call to []= | diff --git a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected index e683bccb8da..4ba190343a7 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -3049,9 +3049,9 @@ cfg.rb: #-----| -> exit print (normal) # 147| self -#-----| -> call to super +#-----| -> super call to print -# 147| call to super +# 147| super call to print #-----| -> call to print # 147| call to print diff --git a/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected b/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected index b17584ce259..f41b6e34a4d 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected @@ -31,7 +31,7 @@ callsWithNoArguments | cfg.rb:138:17:138:23 | * ... | | cfg.rb:141:1:141:8 | call to itself | | cfg.rb:143:10:143:21 | call to itself | -| cfg.rb:147:10:147:14 | call to super | +| cfg.rb:147:10:147:14 | super call to print | | cfg.rb:147:10:147:22 | call to print | | cfg.rb:151:9:151:17 | call to new | | cfg.rb:158:16:158:21 | * ... | diff --git a/ruby/ql/test/library-tests/modules/callgraph.expected b/ruby/ql/test/library-tests/modules/callgraph.expected index afb8b6da172..9a85628fcce 100644 --- a/ruby/ql/test/library-tests/modules/callgraph.expected +++ b/ruby/ql/test/library-tests/modules/callgraph.expected @@ -17,7 +17,7 @@ getTarget | calls.rb:60:5:60:9 | call to new | calls.rb:117:5:117:16 | new | | calls.rb:61:1:61:5 | call to baz | calls.rb:51:5:57:7 | baz | | calls.rb:63:1:63:12 | call to instance_m | calls.rb:22:5:24:7 | instance_m | -| calls.rb:67:9:67:13 | call to super | calls.rb:51:5:57:7 | baz | +| calls.rb:67:9:67:13 | super call to baz | calls.rb:51:5:57:7 | baz | | calls.rb:71:5:71:9 | call to new | calls.rb:117:5:117:16 | new | | calls.rb:72:1:72:5 | call to baz | calls.rb:66:5:68:7 | baz | | calls.rb:74:1:74:12 | call to instance_m | calls.rb:22:5:24:7 | instance_m | @@ -235,7 +235,7 @@ getTarget | calls.rb:616:1:616:31 | call to call_call_singleton1 | calls.rb:591:5:593:7 | call_call_singleton1 | | hello.rb:12:5:12:24 | call to include | calls.rb:108:5:110:7 | include | | hello.rb:14:16:14:20 | call to hello | hello.rb:2:5:4:7 | hello | -| hello.rb:20:16:20:20 | call to super | hello.rb:13:5:15:7 | message | +| hello.rb:20:16:20:20 | super call to message | hello.rb:13:5:15:7 | message | | hello.rb:20:30:20:34 | call to world | hello.rb:5:5:7:7 | world | | instance_fields.rb:4:22:4:35 | call to new | calls.rb:117:5:117:16 | new | | instance_fields.rb:7:13:7:25 | call to target | instance_fields.rb:12:5:13:7 | target | diff --git a/ruby/ql/test/library-tests/modules/methods.expected b/ruby/ql/test/library-tests/modules/methods.expected index 5319fc55377..3f1d52b8f3c 100644 --- a/ruby/ql/test/library-tests/modules/methods.expected +++ b/ruby/ql/test/library-tests/modules/methods.expected @@ -638,7 +638,7 @@ enclosingMethod | calls.rb:55:9:55:19 | self | calls.rb:51:5:57:7 | baz | | calls.rb:56:9:56:12 | self | calls.rb:51:5:57:7 | baz | | calls.rb:56:9:56:24 | call to singleton_m | calls.rb:51:5:57:7 | baz | -| calls.rb:67:9:67:13 | call to super | calls.rb:66:5:68:7 | baz | +| calls.rb:67:9:67:13 | super call to baz | calls.rb:66:5:68:7 | baz | | calls.rb:76:18:76:18 | a | calls.rb:76:1:79:3 | optional_arg | | calls.rb:76:18:76:18 | a | calls.rb:76:1:79:3 | optional_arg | | calls.rb:76:22:76:22 | 4 | calls.rb:76:1:79:3 | optional_arg | @@ -975,7 +975,7 @@ enclosingMethod | hello.rb:14:16:14:20 | call to hello | hello.rb:13:5:15:7 | message | | hello.rb:14:16:14:20 | self | hello.rb:13:5:15:7 | message | | hello.rb:20:9:20:40 | return | hello.rb:19:5:21:7 | message | -| hello.rb:20:16:20:20 | call to super | hello.rb:19:5:21:7 | message | +| hello.rb:20:16:20:20 | super call to message | hello.rb:19:5:21:7 | message | | hello.rb:20:16:20:26 | ... + ... | hello.rb:19:5:21:7 | message | | hello.rb:20:16:20:34 | ... + ... | hello.rb:19:5:21:7 | message | | hello.rb:20:16:20:40 | ... + ... | hello.rb:19:5:21:7 | message | diff --git a/ruby/ql/test/library-tests/modules/modules.expected b/ruby/ql/test/library-tests/modules/modules.expected index 01b81e01efe..45e7cc89d74 100644 --- a/ruby/ql/test/library-tests/modules/modules.expected +++ b/ruby/ql/test/library-tests/modules/modules.expected @@ -586,7 +586,7 @@ enclosingModule | calls.rb:65:1:69:3 | D | calls.rb:1:1:616:32 | calls.rb | | calls.rb:65:11:65:11 | C | calls.rb:1:1:616:32 | calls.rb | | calls.rb:66:5:68:7 | baz | calls.rb:65:1:69:3 | D | -| calls.rb:67:9:67:13 | call to super | calls.rb:65:1:69:3 | D | +| calls.rb:67:9:67:13 | super call to baz | calls.rb:65:1:69:3 | D | | calls.rb:71:1:71:1 | d | calls.rb:1:1:616:32 | calls.rb | | calls.rb:71:1:71:9 | ... = ... | calls.rb:1:1:616:32 | calls.rb | | calls.rb:71:5:71:5 | D | calls.rb:1:1:616:32 | calls.rb | @@ -1513,7 +1513,7 @@ enclosingModule | hello.rb:18:20:18:27 | Greeting | hello.rb:1:1:22:3 | hello.rb | | hello.rb:19:5:21:7 | message | hello.rb:18:1:22:3 | HelloWorld | | hello.rb:20:9:20:40 | return | hello.rb:18:1:22:3 | HelloWorld | -| hello.rb:20:16:20:20 | call to super | hello.rb:18:1:22:3 | HelloWorld | +| hello.rb:20:16:20:20 | super call to message | hello.rb:18:1:22:3 | HelloWorld | | hello.rb:20:16:20:26 | ... + ... | hello.rb:18:1:22:3 | HelloWorld | | hello.rb:20:16:20:34 | ... + ... | hello.rb:18:1:22:3 | HelloWorld | | hello.rb:20:16:20:40 | ... + ... | hello.rb:18:1:22:3 | HelloWorld | From 9ef4f122612fa3aaa2782eadb433ce7e72343670 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 7 Dec 2022 14:12:43 +0100 Subject: [PATCH 18/93] add change-note --- ruby/ql/lib/change-notes/2022-12-07-kernel-paths.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2022-12-07-kernel-paths.md diff --git a/ruby/ql/lib/change-notes/2022-12-07-kernel-paths.md b/ruby/ql/lib/change-notes/2022-12-07-kernel-paths.md new file mode 100644 index 00000000000..85761862684 --- /dev/null +++ b/ruby/ql/lib/change-notes/2022-12-07-kernel-paths.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Calls to `Kernel.load`, `Kernel.require`, `Kernel.autoload` are now modeled as sinks for path injection. From f09e10f61fdd15634cd25e3bbd1dca556d7e6df9 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 8 Dec 2022 15:34:26 +0100 Subject: [PATCH 19/93] delete redundant cast --- ruby/ql/lib/codeql/ruby/ast/internal/Call.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll index dfc553fb45d..b6ac243e891 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll @@ -121,7 +121,7 @@ private Ruby::AstNode getSuperParent(Ruby::Super sup) { private string getSuperMethodName(Ruby::Super sup) { exists(Ruby::Method meth | - meth = getSuperParent(sup).getParent().(Ruby::Method) and + meth = getSuperParent(sup).getParent() and result = any(Method c | toGenerated(c) = meth).getName() ) } From 17348fbd32315b839a145d066bf8e2fb1e5b1b17 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 19 Oct 2022 17:06:18 +0100 Subject: [PATCH 20/93] Add android certificate pinning query --- .../AndroidCertificatePinningQuery.qll | 56 +++++++++++++++++++ .../AndroidMissingCertificatePinning.ql | 17 ++++++ 2 files changed, 73 insertions(+) create mode 100644 java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll create mode 100644 java/ql/src/experimental/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll new file mode 100644 index 00000000000..e99bb8d9930 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -0,0 +1,56 @@ +import java +import semmle.code.xml.AndroidManifest +import semmle.code.java.dataflow.TaintTracking +import HttpsUrls + +class AndroidNetworkSecurityConfigFile extends XmlFile { + AndroidNetworkSecurityConfigFile() { + exists(AndroidApplicationXmlElement app, AndroidXmlAttribute confAttr, string confName | + confAttr.getElement() = app and + confAttr.getValue() = "@xml/" + confName and + this.getRelativePath() = "res/xml/" + confName + ".xml" and + this.getARootElement().getName() = "network-security-config" + ) + } +} + +predicate isAndroid() { exists(AndroidManifestXmlFile m) } + +predicate trustedDomain(string domainName) { + exists( + AndroidNetworkSecurityConfigFile confFile, XmlElement domConf, XmlElement domain, + XmlElement trust + | + domConf.getFile() = confFile and + domConf.getName() = "domain-config" and + domain.getParent() = domConf and + domain.getName() = "domain" and + domain.getACharactersSet().getCharacters() = domainName and + trust.getParent() = domConf and + trust.getName() = ["trust-anchors", "pin-set"] + ) +} + +private class UntrustedUrlConfig extends TaintTracking::Configuration { + UntrustedUrlConfig() { this = "UntrustedUrlConfig" } + + override predicate isSource(DataFlow::Node node) { + exists(string d | trustedDomain(d)) and + exists(string lit | lit = node.asExpr().(CompileTimeConstantExpr).getStringValue() | + lit.matches("%://%") and // it's a URL + not exists(string dom | trustedDomain(dom) and lit.matches("%" + dom + "%")) + ) + } + + override predicate isSink(DataFlow::Node node) { node instanceof UrlOpenSink } +} + +predicate missingPinning(DataFlow::Node node) { + isAndroid() and + node instanceof UrlOpenSink and + ( + not exists(string s | trustedDomain(s)) + or + exists(UntrustedUrlConfig conf | conf.hasFlow(_, node)) + ) +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql b/java/ql/src/experimental/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql new file mode 100644 index 00000000000..c94bd08fd87 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql @@ -0,0 +1,17 @@ +/** + * @name Android Missing Certificate Pinning + * @description Network communication should use certificate pinning. + * @kind problem + * @problem.severity warning + * @precision medium + * @id java/android/missingcertificate-pinning + * @tags security + * external/cwe/cwe-295 + */ + +import java +import semmle.code.java.security.AndroidCertificatePinningQuery + +from DataFlow::Node node +where missingPinning(node) +select node, "This network call does not implement certificate pinning." From c3da3a9aeff4af06b61287d1d501dbb1cabfc059 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 7 Nov 2022 13:21:45 +0000 Subject: [PATCH 21/93] Add a bit of additional context to the alert message; fix issue with finding the config file --- .../java/security/AndroidCertificatePinningQuery.qll | 4 +++- .../CWE/CWE-295/AndroidMissingCertificatePinning.ql | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index e99bb8d9930..645aa1169c4 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -1,3 +1,5 @@ +/** Definitiona for the Android Missing Certificate Pinning query. */ + import java import semmle.code.xml.AndroidManifest import semmle.code.java.dataflow.TaintTracking @@ -8,7 +10,7 @@ class AndroidNetworkSecurityConfigFile extends XmlFile { exists(AndroidApplicationXmlElement app, AndroidXmlAttribute confAttr, string confName | confAttr.getElement() = app and confAttr.getValue() = "@xml/" + confName and - this.getRelativePath() = "res/xml/" + confName + ".xml" and + this.getRelativePath().matches("%res/xml/" + confName + ".xml") and this.getARootElement().getName() = "network-security-config" ) } diff --git a/java/ql/src/experimental/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql b/java/ql/src/experimental/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql index c94bd08fd87..60328fac38e 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql @@ -4,7 +4,7 @@ * @kind problem * @problem.severity warning * @precision medium - * @id java/android/missingcertificate-pinning + * @id java/android/missing-certificate-pinning * @tags security * external/cwe/cwe-295 */ @@ -12,6 +12,10 @@ import java import semmle.code.java.security.AndroidCertificatePinningQuery -from DataFlow::Node node -where missingPinning(node) -select node, "This network call does not implement certificate pinning." +from DataFlow::Node node, string msg +where + missingPinning(node) and + if exists(string x | trustedDomain(x)) + then msg = "(untrusted domain)" + else msg = "(no trusted domains)" +select node, "This network call does not implement certificate pinning. " + msg From ea3db5d4294b10e2394391d6c7ee7ac32f64f070 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 7 Nov 2022 16:05:47 +0000 Subject: [PATCH 22/93] Add test cases --- .../Test1/AndroidManifest.xml | 10 ++++++++ .../Test1/Test.java | 12 ++++++++++ .../Test1/options | 1 + .../Test1/res/xml/NetworkSecurityConfig.xml | 9 ++++++++ .../Test1/test.expected | 0 .../Test1/test.ql | 23 +++++++++++++++++++ .../Test2/AndroidManifest.xml | 10 ++++++++ .../Test2/Test.java | 8 +++++++ .../Test2/options | 1 + .../Test2/res/xml/NetworkSecurityConfig.xml | 4 ++++ .../Test2/test.expected | 0 .../Test2/test.ql | 23 +++++++++++++++++++ 12 files changed, 101 insertions(+) create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/Test.java create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/options create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/res/xml/NetworkSecurityConfig.xml create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/test.expected create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/test.ql create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/Test.java create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/options create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/res/xml/NetworkSecurityConfig.xml create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/test.expected create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/test.ql diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/AndroidManifest.xml new file mode 100644 index 00000000000..da5cdabce67 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/Test.java b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/Test.java new file mode 100644 index 00000000000..ed141d80521 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/Test.java @@ -0,0 +1,12 @@ +import java.net.URL; +import java.net.URLConnection; + +class Test{ + URLConnection test1() throws Exception { + return new URL("https://good.example.com").openConnection(); + } + + URLConnection test2() throws Exception { + return new URL("https://bad.example.com").openConnection(); // $hasUntrustedResult + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/options b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/options new file mode 100644 index 00000000000..7d1644b057b --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/options @@ -0,0 +1 @@ +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/google-android-9.0.0 \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/res/xml/NetworkSecurityConfig.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/res/xml/NetworkSecurityConfig.xml new file mode 100644 index 00000000000..e2810ff7e1a --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/res/xml/NetworkSecurityConfig.xml @@ -0,0 +1,9 @@ + + + + good.example.com + + ... + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/test.ql new file mode 100644 index 00000000000..22238774af5 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/test.ql @@ -0,0 +1,23 @@ +import java +import TestUtilities.InlineExpectationsTest +import semmle.code.java.security.AndroidCertificatePinningQuery + +class Test extends InlineExpectationsTest { + Test() { this = "AndroidMissingCertificatePinningTest" } + + override string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } + + override predicate hasActualResult(Location loc, string el, string tag, string value) { + exists(DataFlow::Node node | + missingPinning(node) and + loc = node.getLocation() and + el = node.toString() and + value = "" and + ( + if exists(string x | trustedDomain(x)) + then tag = "hasUntrustedResult" + else tag = "hasNoTrustedResult" + ) + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/AndroidManifest.xml new file mode 100644 index 00000000000..da5cdabce67 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/Test.java b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/Test.java new file mode 100644 index 00000000000..9f68c503b46 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/Test.java @@ -0,0 +1,8 @@ +import java.net.URL; +import java.net.URLConnection; + +class Test{ + URLConnection test2() throws Exception { + return new URL("https://example.com").openConnection(); // $hasNoTrustedResult + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/options b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/options new file mode 100644 index 00000000000..7d1644b057b --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/options @@ -0,0 +1 @@ +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/google-android-9.0.0 \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/res/xml/NetworkSecurityConfig.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/res/xml/NetworkSecurityConfig.xml new file mode 100644 index 00000000000..3fd128a05a2 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/res/xml/NetworkSecurityConfig.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/test.ql new file mode 100644 index 00000000000..22238774af5 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/test.ql @@ -0,0 +1,23 @@ +import java +import TestUtilities.InlineExpectationsTest +import semmle.code.java.security.AndroidCertificatePinningQuery + +class Test extends InlineExpectationsTest { + Test() { this = "AndroidMissingCertificatePinningTest" } + + override string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } + + override predicate hasActualResult(Location loc, string el, string tag, string value) { + exists(DataFlow::Node node | + missingPinning(node) and + loc = node.getLocation() and + el = node.toString() and + value = "" and + ( + if exists(string x | trustedDomain(x)) + then tag = "hasUntrustedResult" + else tag = "hasNoTrustedResult" + ) + ) + } +} From da7032d3d62dd31be8eeeb41888333b2b71e8ca1 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 7 Nov 2022 16:50:34 +0000 Subject: [PATCH 23/93] Add qldoc --- .../code/java/security/AndroidCertificatePinningQuery.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index 645aa1169c4..afdf694a62b 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -1,10 +1,11 @@ -/** Definitiona for the Android Missing Certificate Pinning query. */ +/** Definitions for the Android Missing Certificate Pinning query. */ import java import semmle.code.xml.AndroidManifest import semmle.code.java.dataflow.TaintTracking import HttpsUrls +/** An Android Network Security Configuration XML file. */ class AndroidNetworkSecurityConfigFile extends XmlFile { AndroidNetworkSecurityConfigFile() { exists(AndroidApplicationXmlElement app, AndroidXmlAttribute confAttr, string confName | @@ -16,8 +17,10 @@ class AndroidNetworkSecurityConfigFile extends XmlFile { } } +/** Holds if this database is of an Android application. */ predicate isAndroid() { exists(AndroidManifestXmlFile m) } +/** Holds if the given domain name is trusted by the Network Security Configuration XML file. */ predicate trustedDomain(string domainName) { exists( AndroidNetworkSecurityConfigFile confFile, XmlElement domConf, XmlElement domain, @@ -33,6 +36,7 @@ predicate trustedDomain(string domainName) { ) } +/** Configuration for finding uses of non trusted URLs. */ private class UntrustedUrlConfig extends TaintTracking::Configuration { UntrustedUrlConfig() { this = "UntrustedUrlConfig" } @@ -47,6 +51,7 @@ private class UntrustedUrlConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node node) { node instanceof UrlOpenSink } } +/** Holds if `node` is a network communication call for which certificate pinning is not implemented. */ predicate missingPinning(DataFlow::Node node) { isAndroid() and node instanceof UrlOpenSink and From c32dc1e674ecbb712624fd85380ea6d1d2b9d2b7 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 14 Nov 2022 10:57:17 +0000 Subject: [PATCH 24/93] Implement okhttp support --- .../AndroidCertificatePinningQuery.qll | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index afdf694a62b..80549967090 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -21,7 +21,7 @@ class AndroidNetworkSecurityConfigFile extends XmlFile { predicate isAndroid() { exists(AndroidManifestXmlFile m) } /** Holds if the given domain name is trusted by the Network Security Configuration XML file. */ -predicate trustedDomain(string domainName) { +private predicate trustedDomainViaXml(string domainName) { exists( AndroidNetworkSecurityConfigFile confFile, XmlElement domConf, XmlElement domain, XmlElement trust @@ -36,6 +36,22 @@ predicate trustedDomain(string domainName) { ) } +/** Holds if the given domain name is trusted by an OkHttp `CertificatePinner`. */ +private predicate trustedDomainViaOkHttp(string domainName) { + exists(CompileTimeConstantExpr domainExpr, MethodAccess certPinnerAdd | + domainExpr.getStringValue().replaceAll("*.", "") = domainName and // strip wildcard patterns like *.example.com + certPinnerAdd.getMethod().hasQualifiedName("okhttp3", "CertificatePinner$Builder", "add") and + DataFlow::localExprFlow(domainExpr, certPinnerAdd.getArgument(0)) + ) +} + +/** Holds if the given domain name is trusted by some certifiacte pinning implementation. */ +predicate trustedDomain(string domainName) { + trustedDomainViaXml(domainName) + or + trustedDomainViaOkHttp(domainName) +} + /** Configuration for finding uses of non trusted URLs. */ private class UntrustedUrlConfig extends TaintTracking::Configuration { UntrustedUrlConfig() { this = "UntrustedUrlConfig" } From 53c4ada88304f92c814504221ad1294d944fb4fd Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 14 Nov 2022 10:57:32 +0000 Subject: [PATCH 25/93] Add okhttp tests --- .../Test3/AndroidManifest.xml | 10 ++++++++ .../Test3/Test.java | 17 ++++++++++++++ .../Test3/options | 1 + .../Test3/res/xml/NetworkSecurityConfig.xml | 4 ++++ .../Test3/test.expected | 0 .../Test3/test.ql | 23 +++++++++++++++++++ 6 files changed, 55 insertions(+) create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/Test.java create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/options create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/res/xml/NetworkSecurityConfig.xml create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/test.expected create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/test.ql diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/AndroidManifest.xml new file mode 100644 index 00000000000..da5cdabce67 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/Test.java b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/Test.java new file mode 100644 index 00000000000..c6fe9dd4f54 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/Test.java @@ -0,0 +1,17 @@ +import okhttp3.OkHttpClient; +import okhttp3.CertificatePinner; +import okhttp3.Request; + +class Test{ + void test1() throws Exception { + CertificatePinner certificatePinner = new CertificatePinner.Builder() + .add("good.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") + .build(); + OkHttpClient client = OkHttpClient.Builder() + .certificatePinner(certificatePinner) + .build(); + + client.newCall(new Request.Builder().url("https://good.example.com").build()).execute(); + client.newCall(new Request.Builder().url("https://bad.example.com").build()).execute(); // $hasUntrustedResult + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/options b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/options new file mode 100644 index 00000000000..1983e5973d9 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/options @@ -0,0 +1 @@ +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/google-android-9.0.0:${testdir}/../../../../../stubs/okhttp-4.9.3 \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/res/xml/NetworkSecurityConfig.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/res/xml/NetworkSecurityConfig.xml new file mode 100644 index 00000000000..3fd128a05a2 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/res/xml/NetworkSecurityConfig.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/test.ql new file mode 100644 index 00000000000..22238774af5 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/test.ql @@ -0,0 +1,23 @@ +import java +import TestUtilities.InlineExpectationsTest +import semmle.code.java.security.AndroidCertificatePinningQuery + +class Test extends InlineExpectationsTest { + Test() { this = "AndroidMissingCertificatePinningTest" } + + override string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } + + override predicate hasActualResult(Location loc, string el, string tag, string value) { + exists(DataFlow::Node node | + missingPinning(node) and + loc = node.getLocation() and + el = node.toString() and + value = "" and + ( + if exists(string x | trustedDomain(x)) + then tag = "hasUntrustedResult" + else tag = "hasNoTrustedResult" + ) + ) + } +} From bb402c497b66e9fa8ad330b907fba7e0f5ec0eb5 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 14 Nov 2022 14:39:42 +0000 Subject: [PATCH 26/93] Fix typo in dir name --- .../Test1/AndroidManifest.xml | 0 .../Test1/Test.java | 0 .../Test1/options | 0 .../Test1/res/xml/NetworkSecurityConfig.xml | 0 .../Test1/test.expected | 0 .../Test1/test.ql | 0 .../Test2/AndroidManifest.xml | 0 .../Test2/Test.java | 0 .../Test2/options | 0 .../Test2/res/xml/NetworkSecurityConfig.xml | 0 .../Test2/test.expected | 0 .../Test2/test.ql | 0 .../Test3/AndroidManifest.xml | 0 .../Test3/Test.java | 0 .../Test3/options | 0 .../Test3/res/xml/NetworkSecurityConfig.xml | 0 .../Test3/test.expected | 0 .../Test3/test.ql | 0 18 files changed, 0 insertions(+), 0 deletions(-) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test1/AndroidManifest.xml (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test1/Test.java (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test1/options (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test1/res/xml/NetworkSecurityConfig.xml (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test1/test.expected (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test1/test.ql (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test2/AndroidManifest.xml (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test2/Test.java (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test2/options (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test2/res/xml/NetworkSecurityConfig.xml (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test2/test.expected (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test2/test.ql (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test3/AndroidManifest.xml (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test3/Test.java (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test3/options (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test3/res/xml/NetworkSecurityConfig.xml (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test3/test.expected (100%) rename java/ql/test/query-tests/security/CWE-295/{AndroidMissingCertificatePinning_ => AndroidMissingCertificatePinning}/Test3/test.ql (100%) diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/AndroidManifest.xml similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/AndroidManifest.xml rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/AndroidManifest.xml diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/Test.java b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/Test.java similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/Test.java rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/Test.java diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/options b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/options similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/options rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/options diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/res/xml/NetworkSecurityConfig.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/res/xml/NetworkSecurityConfig.xml similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/res/xml/NetworkSecurityConfig.xml rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/res/xml/NetworkSecurityConfig.xml diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.expected similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/test.expected rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.expected diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.ql similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test1/test.ql rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.ql diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/AndroidManifest.xml similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/AndroidManifest.xml rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/AndroidManifest.xml diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/Test.java b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/Test.java similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/Test.java rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/Test.java diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/options b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/options similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/options rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/options diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/res/xml/NetworkSecurityConfig.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/res/xml/NetworkSecurityConfig.xml similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/res/xml/NetworkSecurityConfig.xml rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/res/xml/NetworkSecurityConfig.xml diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.expected similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/test.expected rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.expected diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.ql similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test2/test.ql rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.ql diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/AndroidManifest.xml similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/AndroidManifest.xml rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/AndroidManifest.xml diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/Test.java b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/Test.java similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/Test.java rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/Test.java diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/options b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/options similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/options rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/options diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/res/xml/NetworkSecurityConfig.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/res/xml/NetworkSecurityConfig.xml similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/res/xml/NetworkSecurityConfig.xml rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/res/xml/NetworkSecurityConfig.xml diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.expected similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/test.expected rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.expected diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.ql similarity index 100% rename from java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning_/Test3/test.ql rename to java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.ql From 4afecf575e389749949ec5a7c3d146ae824ded18 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 14 Nov 2022 17:38:12 +0000 Subject: [PATCH 27/93] Generate more stubs for okhttp and fix tests. Some generated stubs needed to be manually corrected. --- .../Test3/Test.java | 2 +- .../okhttp-4.9.3/javax/net/SocketFactory.java | 17 + .../net/ssl/HandshakeCompletedEvent.java | 24 + .../net/ssl/HandshakeCompletedListener.java | 11 + .../javax/net/ssl/HostnameVerifier.java | 10 + .../javax/net/ssl/SNIMatcher.java | 13 + .../javax/net/ssl/SNIServerName.java | 15 + .../javax/net/ssl/SSLParameters.java | 36 + .../javax/net/ssl/SSLSession.java | 33 + .../javax/net/ssl/SSLSessionContext.java | 16 + .../okhttp-4.9.3/javax/net/ssl/SSLSocket.java | 45 ++ .../javax/net/ssl/SSLSocketFactory.java | 17 + .../javax/net/ssl/TrustManager.java | 8 + .../javax/net/ssl/X509TrustManager.java | 13 + .../javax/security/cert/Certificate.java | 17 + .../javax/security/cert/X509Certificate.java | 27 + .../kotlin/collections/IntIterator.java | 14 + .../kotlin/jvm/functions/Function1.java | 10 + .../kotlin/ranges/ClosedRange.java | 12 + .../kotlin/ranges/IntProgression.java | 26 + .../okhttp-4.9.3/kotlin/ranges/IntRange.java | 25 + .../kotlin/sequences/Sequence.java | 10 + .../okhttp-4.9.3/kotlin/text/FlagEnum.java | 10 + .../okhttp-4.9.3/kotlin/text/MatchGroup.java | 19 + .../kotlin/text/MatchGroupCollection.java | 12 + .../okhttp-4.9.3/kotlin/text/MatchResult.java | 24 + .../stubs/okhttp-4.9.3/kotlin/text/Regex.java | 42 ++ .../okhttp-4.9.3/kotlin/text/RegexOption.java | 12 + .../stubs/okhttp-4.9.3/okhttp3/Address.java | 83 +-- .../stubs/okhttp-4.9.3/okhttp3/Cache.java | 152 ++--- .../okhttp-4.9.3/okhttp3/CacheControl.java | 84 +-- .../okhttp3/CertificatePinner.java | 7 + .../stubs/okhttp-4.9.3/okhttp3/Challenge.java | 49 +- .../okhttp-4.9.3/okhttp3/CipherSuite.java | 34 +- .../okhttp-4.9.3/okhttp3/ConnectionSpec.java | 54 +- .../stubs/okhttp-4.9.3/okhttp3/Cookie.java | 103 +-- .../okhttp-4.9.3/okhttp3/Dispatcher.java | 72 +- .../stubs/okhttp-4.9.3/okhttp3/Handshake.java | 79 +-- .../stubs/okhttp-4.9.3/okhttp3/HttpUrl.java | 460 +++---------- .../stubs/okhttp-4.9.3/okhttp3/MediaType.java | 68 +- .../okhttp-4.9.3/okhttp3/OkHttpClient.java | 633 ++++-------------- .../stubs/okhttp-4.9.3/okhttp3/Request.java | 216 ++---- .../stubs/okhttp-4.9.3/okhttp3/Response.java | 327 +++------ .../stubs/okhttp-4.9.3/okhttp3/Route.java | 41 +- .../okhttp-4.9.3/okhttp3/TlsVersion.java | 24 +- .../test/stubs/okhttp-4.9.3/okio/Buffer.java | 560 ++++------------ .../stubs/okhttp-4.9.3/okio/ByteString.java | 339 ++-------- 47 files changed, 1287 insertions(+), 2618 deletions(-) create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/SocketFactory.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HandshakeCompletedEvent.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HandshakeCompletedListener.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HostnameVerifier.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SNIMatcher.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SNIServerName.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLParameters.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSession.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSessionContext.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSocket.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSocketFactory.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/TrustManager.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/X509TrustManager.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/security/cert/Certificate.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/javax/security/cert/X509Certificate.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/collections/IntIterator.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/jvm/functions/Function1.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/ClosedRange.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/IntProgression.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/IntRange.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/sequences/Sequence.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/text/FlagEnum.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchGroup.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchGroupCollection.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchResult.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/text/Regex.java create mode 100644 java/ql/test/stubs/okhttp-4.9.3/kotlin/text/RegexOption.java diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/Test.java b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/Test.java index c6fe9dd4f54..6a8ff8ed9d8 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/Test.java +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/Test.java @@ -7,7 +7,7 @@ class Test{ CertificatePinner certificatePinner = new CertificatePinner.Builder() .add("good.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") .build(); - OkHttpClient client = OkHttpClient.Builder() + OkHttpClient client = new OkHttpClient.Builder() .certificatePinner(certificatePinner) .build(); diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/SocketFactory.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/SocketFactory.java new file mode 100644 index 00000000000..ddab28a7fc8 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/SocketFactory.java @@ -0,0 +1,17 @@ +// Generated automatically from javax.net.SocketFactory for testing purposes + +package javax.net; + +import java.net.InetAddress; +import java.net.Socket; + +abstract public class SocketFactory +{ + protected SocketFactory(){} + public Socket createSocket(){ return null; } + public abstract Socket createSocket(InetAddress p0, int p1); + public abstract Socket createSocket(InetAddress p0, int p1, InetAddress p2, int p3); + public abstract Socket createSocket(String p0, int p1); + public abstract Socket createSocket(String p0, int p1, InetAddress p2, int p3); + public static SocketFactory getDefault(){ return null; } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HandshakeCompletedEvent.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HandshakeCompletedEvent.java new file mode 100644 index 00000000000..c692761701e --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HandshakeCompletedEvent.java @@ -0,0 +1,24 @@ +// Generated automatically from javax.net.ssl.HandshakeCompletedEvent for testing purposes + +package javax.net.ssl; + +import java.security.Principal; +import java.security.cert.Certificate; +import java.util.EventObject; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; +import javax.security.cert.X509Certificate; + +public class HandshakeCompletedEvent extends EventObject +{ + protected HandshakeCompletedEvent() { super(null); } // manually corrected + public Certificate[] getLocalCertificates(){ return null; } + public Certificate[] getPeerCertificates(){ return null; } + public HandshakeCompletedEvent(SSLSocket p0, SSLSession p1){ super(null); } // manually corrected + public Principal getLocalPrincipal(){ return null; } + public Principal getPeerPrincipal(){ return null; } + public SSLSession getSession(){ return null; } + public SSLSocket getSocket(){ return null; } + public String getCipherSuite(){ return null; } + public X509Certificate[] getPeerCertificateChain(){ return null; } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HandshakeCompletedListener.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HandshakeCompletedListener.java new file mode 100644 index 00000000000..c920530baef --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HandshakeCompletedListener.java @@ -0,0 +1,11 @@ +// Generated automatically from javax.net.ssl.HandshakeCompletedListener for testing purposes + +package javax.net.ssl; + +import java.util.EventListener; +import javax.net.ssl.HandshakeCompletedEvent; + +public interface HandshakeCompletedListener extends EventListener +{ + void handshakeCompleted(HandshakeCompletedEvent p0); +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HostnameVerifier.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HostnameVerifier.java new file mode 100644 index 00000000000..891b2623061 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/HostnameVerifier.java @@ -0,0 +1,10 @@ +// Generated automatically from javax.net.ssl.HostnameVerifier for testing purposes + +package javax.net.ssl; + +import javax.net.ssl.SSLSession; + +public interface HostnameVerifier +{ + boolean verify(String p0, SSLSession p1); +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SNIMatcher.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SNIMatcher.java new file mode 100644 index 00000000000..4a346519f18 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SNIMatcher.java @@ -0,0 +1,13 @@ +// Generated automatically from javax.net.ssl.SNIMatcher for testing purposes + +package javax.net.ssl; + +import javax.net.ssl.SNIServerName; + +abstract public class SNIMatcher +{ + protected SNIMatcher() {} + protected SNIMatcher(int p0){} + public abstract boolean matches(SNIServerName p0); + public final int getType(){ return 0; } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SNIServerName.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SNIServerName.java new file mode 100644 index 00000000000..119f884b2e6 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SNIServerName.java @@ -0,0 +1,15 @@ +// Generated automatically from javax.net.ssl.SNIServerName for testing purposes + +package javax.net.ssl; + + +abstract public class SNIServerName +{ + protected SNIServerName() {} + protected SNIServerName(int p0, byte[] p1){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final byte[] getEncoded(){ return null; } + public final int getType(){ return 0; } + public int hashCode(){ return 0; } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLParameters.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLParameters.java new file mode 100644 index 00000000000..522fde0d61f --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLParameters.java @@ -0,0 +1,36 @@ +// Generated automatically from javax.net.ssl.SSLParameters for testing purposes + +package javax.net.ssl; + +import java.security.AlgorithmConstraints; +import java.util.Collection; +import java.util.List; +import javax.net.ssl.SNIMatcher; +import javax.net.ssl.SNIServerName; + +public class SSLParameters +{ + public AlgorithmConstraints getAlgorithmConstraints(){ return null; } + public SSLParameters(){} + public SSLParameters(String[] p0){} + public SSLParameters(String[] p0, String[] p1){} + public String getEndpointIdentificationAlgorithm(){ return null; } + public String[] getApplicationProtocols(){ return null; } + public String[] getCipherSuites(){ return null; } + public String[] getProtocols(){ return null; } + public boolean getNeedClientAuth(){ return false; } + public boolean getWantClientAuth(){ return false; } + public final Collection getSNIMatchers(){ return null; } + public final List getServerNames(){ return null; } + public final boolean getUseCipherSuitesOrder(){ return false; } + public final void setSNIMatchers(Collection p0){} + public final void setServerNames(List p0){} + public final void setUseCipherSuitesOrder(boolean p0){} + public void setAlgorithmConstraints(AlgorithmConstraints p0){} + public void setApplicationProtocols(String[] p0){} + public void setCipherSuites(String[] p0){} + public void setEndpointIdentificationAlgorithm(String p0){} + public void setNeedClientAuth(boolean p0){} + public void setProtocols(String[] p0){} + public void setWantClientAuth(boolean p0){} +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSession.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSession.java new file mode 100644 index 00000000000..9afb7abecb3 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSession.java @@ -0,0 +1,33 @@ +// Generated automatically from javax.net.ssl.SSLSession for testing purposes + +package javax.net.ssl; + +import java.security.Principal; +import java.security.cert.Certificate; +import javax.net.ssl.SSLSessionContext; +import javax.security.cert.X509Certificate; + +public interface SSLSession +{ + Certificate[] getLocalCertificates(); + Certificate[] getPeerCertificates(); + Object getValue(String p0); + Principal getLocalPrincipal(); + Principal getPeerPrincipal(); + SSLSessionContext getSessionContext(); + String getCipherSuite(); + String getPeerHost(); + String getProtocol(); + String[] getValueNames(); + X509Certificate[] getPeerCertificateChain(); + boolean isValid(); + byte[] getId(); + int getApplicationBufferSize(); + int getPacketBufferSize(); + int getPeerPort(); + long getCreationTime(); + long getLastAccessedTime(); + void invalidate(); + void putValue(String p0, Object p1); + void removeValue(String p0); +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSessionContext.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSessionContext.java new file mode 100644 index 00000000000..c0d9c6ef650 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSessionContext.java @@ -0,0 +1,16 @@ +// Generated automatically from javax.net.ssl.SSLSessionContext for testing purposes + +package javax.net.ssl; + +import java.util.Enumeration; +import javax.net.ssl.SSLSession; + +public interface SSLSessionContext +{ + Enumeration getIds(); + SSLSession getSession(byte[] p0); + int getSessionCacheSize(); + int getSessionTimeout(); + void setSessionCacheSize(int p0); + void setSessionTimeout(int p0); +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSocket.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSocket.java new file mode 100644 index 00000000000..2145c1b8c37 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSocket.java @@ -0,0 +1,45 @@ +// Generated automatically from javax.net.ssl.SSLSocket for testing purposes + +package javax.net.ssl; + +import java.net.InetAddress; +import java.net.Socket; +import java.util.List; +import java.util.function.BiFunction; +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSession; + +abstract public class SSLSocket extends Socket +{ + protected SSLSocket(){} + protected SSLSocket(InetAddress p0, int p1){} + protected SSLSocket(InetAddress p0, int p1, InetAddress p2, int p3){} + protected SSLSocket(String p0, int p1){} + protected SSLSocket(String p0, int p1, InetAddress p2, int p3){} + public BiFunction, String> getHandshakeApplicationProtocolSelector(){ return null; } + public SSLParameters getSSLParameters(){ return null; } + public SSLSession getHandshakeSession(){ return null; } + public String getApplicationProtocol(){ return null; } + public String getHandshakeApplicationProtocol(){ return null; } + public abstract SSLSession getSession(); + public abstract String[] getEnabledCipherSuites(); + public abstract String[] getEnabledProtocols(); + public abstract String[] getSupportedCipherSuites(); + public abstract String[] getSupportedProtocols(); + public abstract boolean getEnableSessionCreation(); + public abstract boolean getNeedClientAuth(); + public abstract boolean getUseClientMode(); + public abstract boolean getWantClientAuth(); + public abstract void addHandshakeCompletedListener(HandshakeCompletedListener p0); + public abstract void removeHandshakeCompletedListener(HandshakeCompletedListener p0); + public abstract void setEnableSessionCreation(boolean p0); + public abstract void setEnabledCipherSuites(String[] p0); + public abstract void setEnabledProtocols(String[] p0); + public abstract void setNeedClientAuth(boolean p0); + public abstract void setUseClientMode(boolean p0); + public abstract void setWantClientAuth(boolean p0); + public abstract void startHandshake(); + public void setHandshakeApplicationProtocolSelector(BiFunction, String> p0){} + public void setSSLParameters(SSLParameters p0){} +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSocketFactory.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSocketFactory.java new file mode 100644 index 00000000000..47c40526842 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/SSLSocketFactory.java @@ -0,0 +1,17 @@ +// Generated automatically from javax.net.ssl.SSLSocketFactory for testing purposes + +package javax.net.ssl; + +import java.io.InputStream; +import java.net.Socket; +import javax.net.SocketFactory; + +abstract public class SSLSocketFactory extends SocketFactory +{ + public SSLSocketFactory(){} + public Socket createSocket(Socket p0, InputStream p1, boolean p2){ return null; } + public abstract Socket createSocket(Socket p0, String p1, int p2, boolean p3); + public abstract String[] getDefaultCipherSuites(); + public abstract String[] getSupportedCipherSuites(); + public static SocketFactory getDefault(){ return null; } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/TrustManager.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/TrustManager.java new file mode 100644 index 00000000000..6698b99ac42 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/TrustManager.java @@ -0,0 +1,8 @@ +// Generated automatically from javax.net.ssl.TrustManager for testing purposes + +package javax.net.ssl; + + +public interface TrustManager +{ +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/X509TrustManager.java b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/X509TrustManager.java new file mode 100644 index 00000000000..45a0aa5867a --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/net/ssl/X509TrustManager.java @@ -0,0 +1,13 @@ +// Generated automatically from javax.net.ssl.X509TrustManager for testing purposes + +package javax.net.ssl; + +import java.security.cert.X509Certificate; +import javax.net.ssl.TrustManager; + +public interface X509TrustManager extends TrustManager +{ + X509Certificate[] getAcceptedIssuers(); + void checkClientTrusted(X509Certificate[] p0, String p1); + void checkServerTrusted(X509Certificate[] p0, String p1); +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/security/cert/Certificate.java b/java/ql/test/stubs/okhttp-4.9.3/javax/security/cert/Certificate.java new file mode 100644 index 00000000000..56545088a1b --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/security/cert/Certificate.java @@ -0,0 +1,17 @@ +// Generated automatically from javax.security.cert.Certificate for testing purposes + +package javax.security.cert; + +import java.security.PublicKey; + +abstract public class Certificate +{ + public Certificate(){} + public abstract PublicKey getPublicKey(); + public abstract String toString(); + public abstract byte[] getEncoded(); + public abstract void verify(PublicKey p0); + public abstract void verify(PublicKey p0, String p1); + public boolean equals(Object p0){ return false; } + public int hashCode(){ return 0; } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/javax/security/cert/X509Certificate.java b/java/ql/test/stubs/okhttp-4.9.3/javax/security/cert/X509Certificate.java new file mode 100644 index 00000000000..ab526d827a3 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/javax/security/cert/X509Certificate.java @@ -0,0 +1,27 @@ +// Generated automatically from javax.security.cert.X509Certificate for testing purposes + +package javax.security.cert; + +import java.io.InputStream; +import java.math.BigInteger; +import java.security.Principal; +import java.util.Date; +import javax.security.cert.Certificate; + +abstract public class X509Certificate extends Certificate +{ + public X509Certificate(){} + public abstract BigInteger getSerialNumber(); + public abstract Date getNotAfter(); + public abstract Date getNotBefore(); + public abstract Principal getIssuerDN(); + public abstract Principal getSubjectDN(); + public abstract String getSigAlgName(); + public abstract String getSigAlgOID(); + public abstract byte[] getSigAlgParams(); + public abstract int getVersion(); + public abstract void checkValidity(); + public abstract void checkValidity(Date p0); + public static X509Certificate getInstance(InputStream p0){ return null; } + public static X509Certificate getInstance(byte[] p0){ return null; } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/collections/IntIterator.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/collections/IntIterator.java new file mode 100644 index 00000000000..87ed291f07d --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/collections/IntIterator.java @@ -0,0 +1,14 @@ +// Generated automatically from kotlin.collections.IntIterator for testing purposes + +package kotlin.collections; + +import java.util.Iterator; +import kotlin.jvm.internal.markers.KMappedMarker; + +abstract public class IntIterator implements Iterator, KMappedMarker +{ + public IntIterator(){} + public abstract int nextInt(); + public final Integer next(){ return null; } + public void remove(){} +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/jvm/functions/Function1.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/jvm/functions/Function1.java new file mode 100644 index 00000000000..775d4d8369b --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/jvm/functions/Function1.java @@ -0,0 +1,10 @@ +// Generated automatically from kotlin.jvm.functions.Function1 for testing purposes + +package kotlin.jvm.functions; + +import kotlin.Function; + +public interface Function1 extends Function +{ + R invoke(P1 p0); +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/ClosedRange.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/ClosedRange.java new file mode 100644 index 00000000000..36880bd56db --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/ClosedRange.java @@ -0,0 +1,12 @@ +// Generated automatically from kotlin.ranges.ClosedRange for testing purposes + +package kotlin.ranges; + + +public interface ClosedRange> +{ + T getEndInclusive(); + T getStart(); + boolean contains(T p0); + boolean isEmpty(); +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/IntProgression.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/IntProgression.java new file mode 100644 index 00000000000..3cf69027397 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/IntProgression.java @@ -0,0 +1,26 @@ +// Generated automatically from kotlin.ranges.IntProgression for testing purposes + +package kotlin.ranges; + +import kotlin.collections.IntIterator; +import kotlin.jvm.internal.markers.KMappedMarker; + +public class IntProgression implements Iterable, KMappedMarker +{ + protected IntProgression() {} + public IntIterator iterator(){ return null; } + public IntProgression(int p0, int p1, int p2){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public final int getFirst(){ return 0; } + public final int getLast(){ return 0; } + public final int getStep(){ return 0; } + public int hashCode(){ return 0; } + public static IntProgression.Companion Companion = null; + static public class Companion + { + protected Companion() {} + public final IntProgression fromClosedRange(int p0, int p1, int p2){ return null; } + } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/IntRange.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/IntRange.java new file mode 100644 index 00000000000..eebf2a6fd34 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/ranges/IntRange.java @@ -0,0 +1,25 @@ +// Generated automatically from kotlin.ranges.IntRange for testing purposes + +package kotlin.ranges; + +import kotlin.ranges.ClosedRange; +import kotlin.ranges.IntProgression; + +public class IntRange extends IntProgression implements ClosedRange +{ + protected IntRange() {} + public IntRange(int p0, int p1){} + public Integer getEndInclusive(){ return null; } + public Integer getStart(){ return null; } + public String toString(){ return null; } + public boolean contains(Integer p0){ return false; } // manually corrected + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int hashCode(){ return 0; } + public static IntRange.Companion Companion = null; + static public class Companion + { + protected Companion() {} + public final IntRange getEMPTY(){ return null; } + } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/sequences/Sequence.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/sequences/Sequence.java new file mode 100644 index 00000000000..6f57a5a443a --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/sequences/Sequence.java @@ -0,0 +1,10 @@ +// Generated automatically from kotlin.sequences.Sequence for testing purposes + +package kotlin.sequences; + +import java.util.Iterator; + +public interface Sequence +{ + Iterator iterator(); +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/FlagEnum.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/FlagEnum.java new file mode 100644 index 00000000000..8ec20898544 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/FlagEnum.java @@ -0,0 +1,10 @@ +// Generated automatically from kotlin.text.FlagEnum for testing purposes + +package kotlin.text; + + +interface FlagEnum +{ + int getMask(); + int getValue(); +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchGroup.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchGroup.java new file mode 100644 index 00000000000..e90a0ea9264 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchGroup.java @@ -0,0 +1,19 @@ +// Generated automatically from kotlin.text.MatchGroup for testing purposes + +package kotlin.text; + +import kotlin.ranges.IntRange; + +public class MatchGroup +{ + protected MatchGroup() {} + public MatchGroup(String p0, IntRange p1){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final IntRange component2(){ return null; } + public final IntRange getRange(){ return null; } + public final MatchGroup copy(String p0, IntRange p1){ return null; } + public final String component1(){ return null; } + public final String getValue(){ return null; } + public int hashCode(){ return 0; } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchGroupCollection.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchGroupCollection.java new file mode 100644 index 00000000000..ca401ed1a98 --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchGroupCollection.java @@ -0,0 +1,12 @@ +// Generated automatically from kotlin.text.MatchGroupCollection for testing purposes + +package kotlin.text; + +import java.util.Collection; +import kotlin.jvm.internal.markers.KMappedMarker; +import kotlin.text.MatchGroup; + +public interface MatchGroupCollection extends Collection, KMappedMarker +{ + MatchGroup get(int p0); +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchResult.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchResult.java new file mode 100644 index 00000000000..888b629712c --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/MatchResult.java @@ -0,0 +1,24 @@ +// Generated automatically from kotlin.text.MatchResult for testing purposes + +package kotlin.text; + +import java.util.List; +import kotlin.ranges.IntRange; +import kotlin.text.MatchGroupCollection; + +public interface MatchResult +{ + IntRange getRange(); + List getGroupValues(); + MatchGroupCollection getGroups(); + MatchResult next(); + MatchResult.Destructured getDestructured(); + String getValue(); + static public class Destructured + { + protected Destructured() {} + public Destructured(MatchResult p0){} + public final List toList(){ return null; } + public final MatchResult getMatch(){ return null; } + } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/Regex.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/Regex.java new file mode 100644 index 00000000000..f587f461b2e --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/Regex.java @@ -0,0 +1,42 @@ +// Generated automatically from kotlin.text.Regex for testing purposes + +package kotlin.text; + +import java.io.Serializable; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; +import kotlin.jvm.functions.Function1; +import kotlin.sequences.Sequence; +import kotlin.text.MatchResult; +import kotlin.text.RegexOption; + +public class Regex implements Serializable +{ + protected Regex() {} + public Regex(Pattern p0){} + public Regex(String p0){} + public Regex(String p0, RegexOption p1){} + public Regex(String p0, Set p1){} + public String toString(){ return null; } + public final List split(CharSequence p0, int p1){ return null; } + public final MatchResult find(CharSequence p0, int p1){ return null; } + public final MatchResult matchEntire(CharSequence p0){ return null; } + public final Pattern toPattern(){ return null; } + public final Sequence findAll(CharSequence p0, int p1){ return null; } + public final Set getOptions(){ return null; } + public final String getPattern(){ return null; } + public final String replace(CharSequence p0, Function1 p1){ return null; } + public final String replace(CharSequence p0, String p1){ return null; } + public final String replaceFirst(CharSequence p0, String p1){ return null; } + public final boolean containsMatchIn(CharSequence p0){ return false; } + public final boolean matches(CharSequence p0){ return false; } + public static Regex.Companion Companion = null; + static public class Companion + { + protected Companion() {} + public final Regex fromLiteral(String p0){ return null; } + public final String escape(String p0){ return null; } + public final String escapeReplacement(String p0){ return null; } + } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/RegexOption.java b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/RegexOption.java new file mode 100644 index 00000000000..7cc222eb40a --- /dev/null +++ b/java/ql/test/stubs/okhttp-4.9.3/kotlin/text/RegexOption.java @@ -0,0 +1,12 @@ +// Generated automatically from kotlin.text.RegexOption for testing purposes + +package kotlin.text; + + +public enum RegexOption +{ + CANON_EQ, COMMENTS, DOT_MATCHES_ALL, IGNORE_CASE, LITERAL, MULTILINE, UNIX_LINES; + private RegexOption() {} + public int getMask(){ return 0; } + public int getValue(){ return 0; } +} diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Address.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Address.java index aa50e384773..b28b7349323 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Address.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Address.java @@ -15,70 +15,23 @@ import okhttp3.Dns; import okhttp3.HttpUrl; import okhttp3.Protocol; -public class Address { +public class Address +{ protected Address() {} - - public Address(String p0, int p1, Dns p2, SocketFactory p3, SSLSocketFactory p4, - HostnameVerifier p5, CertificatePinner p6, Authenticator p7, Proxy p8, - List p9, List p10, ProxySelector p11) {} - - public String toString() { - return null; - } - - public boolean equals(Object p0) { - return false; - } - - public final Authenticator proxyAuthenticator() { - return null; - } - - public final CertificatePinner certificatePinner() { - return null; - } - - public final Dns dns() { - return null; - } - - public final HostnameVerifier hostnameVerifier() { - return null; - } - - public final HttpUrl url() { - return null; - } - - public final List connectionSpecs() { - return null; - } - - public final List protocols() { - return null; - } - - public final Proxy proxy() { - return null; - } - - public final ProxySelector proxySelector() { - return null; - } - - public final SSLSocketFactory sslSocketFactory() { - return null; - } - - public final SocketFactory socketFactory() { - return null; - } - - public final boolean equalsNonHost$okhttp(Address p0) { - return false; - } - - public int hashCode() { - return 0; - } + public Address(String p0, int p1, Dns p2, SocketFactory p3, SSLSocketFactory p4, HostnameVerifier p5, CertificatePinner p6, Authenticator p7, Proxy p8, List p9, List p10, ProxySelector p11){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final Authenticator proxyAuthenticator(){ return null; } + public final CertificatePinner certificatePinner(){ return null; } + public final Dns dns(){ return null; } + public final HostnameVerifier hostnameVerifier(){ return null; } + public final HttpUrl url(){ return null; } + public final List connectionSpecs(){ return null; } + public final List protocols(){ return null; } + public final Proxy proxy(){ return null; } + public final ProxySelector proxySelector(){ return null; } + public final SSLSocketFactory sslSocketFactory(){ return null; } + public final SocketFactory socketFactory(){ return null; } + public final boolean equalsNonHost$okhttp(Address p0){ return false; } + public int hashCode(){ return 0; } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Cache.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Cache.java index 789ff82e4f8..51980a27f0e 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Cache.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Cache.java @@ -16,122 +16,46 @@ import okhttp3.internal.cache.DiskLruCache; import okhttp3.internal.io.FileSystem; import okio.BufferedSource; -public class Cache implements Closeable, Flushable { +public class Cache implements Closeable, Flushable +{ protected Cache() {} - - public Cache(File p0, long p1) {} - - public Cache(File p0, long p1, FileSystem p2) {} - - public final CacheRequest put$okhttp(Response p0) { - return null; - } - - public final DiskLruCache getCache$okhttp() { - return null; - } - - public final File directory() { - return null; - } - - public final Iterator urls() { - return null; - } - - public final Response get$okhttp(Request p0) { - return null; - } - - public final boolean isClosed() { - return false; - } - - public final int getWriteAbortCount$okhttp() { - return 0; - } - - public final int getWriteSuccessCount$okhttp() { - return 0; - } - - public final int hitCount() { - return 0; - } - - public final int networkCount() { - return 0; - } - - public final int requestCount() { - return 0; - } - - public final int writeAbortCount() { - return 0; - } - - public final int writeSuccessCount() { - return 0; - } - - public final long maxSize() { - return 0; - } - - public final long size() { - return 0; - } - - public final void delete() {} - - public final void evictAll() {} - - public final void initialize() {} - - public final void remove$okhttp(Request p0) {} - - public final void setWriteAbortCount$okhttp(int p0) {} - - public final void setWriteSuccessCount$okhttp(int p0) {} - - public final void trackConditionalCacheHit$okhttp() {} - - public final void trackResponse$okhttp(CacheStrategy p0) {} - - public final void update$okhttp(Response p0, Response p1) {} - + public Cache(File p0, long p1){} + public Cache(File p0, long p1, FileSystem p2){} + public final CacheRequest put$okhttp(Response p0){ return null; } + public final DiskLruCache getCache$okhttp(){ return null; } + public final File directory(){ return null; } + public final Iterator urls(){ return null; } + public final Response get$okhttp(Request p0){ return null; } + public final boolean isClosed(){ return false; } + public final int getWriteAbortCount$okhttp(){ return 0; } + public final int getWriteSuccessCount$okhttp(){ return 0; } + public final int hitCount(){ return 0; } + public final int networkCount(){ return 0; } + public final int requestCount(){ return 0; } + public final int writeAbortCount(){ return 0; } + public final int writeSuccessCount(){ return 0; } + public final long maxSize(){ return 0; } + public final long size(){ return 0; } + public final void delete(){} + public final void evictAll(){} + public final void initialize(){} + public final void remove$okhttp(Request p0){} + public final void setWriteAbortCount$okhttp(int p0){} + public final void setWriteSuccessCount$okhttp(int p0){} + public final void trackConditionalCacheHit$okhttp(){} + public final void trackResponse$okhttp(CacheStrategy p0){} + public final void update$okhttp(Response p0, Response p1){} public static Cache.Companion Companion = null; - - public static String key(HttpUrl p0) { - return null; - } - - public void close() {} - - public void flush() {} - - static public class Companion { + public static String key(HttpUrl p0){ return null; } + public void close(){} + public void flush(){} + static public class Companion + { protected Companion() {} - - public final Headers varyHeaders(Response p0) { - return null; - } - - public final String key(HttpUrl p0) { - return null; - } - - public final boolean hasVaryAll(Response p0) { - return false; - } - - public final boolean varyMatches(Response p0, Headers p1, Request p2) { - return false; - } - - public final int readInt$okhttp(BufferedSource p0) { - return 0; - } + public final Headers varyHeaders(Response p0){ return null; } + public final String key(HttpUrl p0){ return null; } + public final boolean hasVaryAll(Response p0){ return false; } + public final boolean varyMatches(Response p0, Headers p1, Request p2){ return false; } + public final int readInt$okhttp(BufferedSource p0){ return 0; } } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CacheControl.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CacheControl.java index 564f1cad733..80282b01ec3 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CacheControl.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CacheControl.java @@ -4,75 +4,29 @@ package okhttp3; import okhttp3.Headers; -public class CacheControl { +public class CacheControl +{ protected CacheControl() {} - - public String toString() { - return null; - } - - public final boolean immutable() { - return false; - } - - public final boolean isPrivate() { - return false; - } - - public final boolean isPublic() { - return false; - } - - public final boolean mustRevalidate() { - return false; - } - - public final boolean noCache() { - return false; - } - - public final boolean noStore() { - return false; - } - - public final boolean noTransform() { - return false; - } - - public final boolean onlyIfCached() { - return false; - } - - public final int maxAgeSeconds() { - return 0; - } - - public final int maxStaleSeconds() { - return 0; - } - - public final int minFreshSeconds() { - return 0; - } - - public final int sMaxAgeSeconds() { - return 0; - } - + public String toString(){ return null; } + public final boolean immutable(){ return false; } + public final boolean isPrivate(){ return false; } + public final boolean isPublic(){ return false; } + public final boolean mustRevalidate(){ return false; } + public final boolean noCache(){ return false; } + public final boolean noStore(){ return false; } + public final boolean noTransform(){ return false; } + public final boolean onlyIfCached(){ return false; } + public final int maxAgeSeconds(){ return 0; } + public final int maxStaleSeconds(){ return 0; } + public final int minFreshSeconds(){ return 0; } + public final int sMaxAgeSeconds(){ return 0; } public static CacheControl FORCE_CACHE = null; public static CacheControl FORCE_NETWORK = null; - - public static CacheControl parse(Headers p0) { - return null; - } - + public static CacheControl parse(Headers p0){ return null; } public static CacheControl.Companion Companion = null; - - static public class Companion { + static public class Companion + { protected Companion() {} - - public final CacheControl parse(Headers p0) { - return null; - } + public final CacheControl parse(Headers p0){ return null; } } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CertificatePinner.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CertificatePinner.java index 15e83d72f46..09e607247f4 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CertificatePinner.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CertificatePinner.java @@ -28,6 +28,13 @@ public class CertificatePinner public static CertificatePinner DEFAULT = null; public static CertificatePinner.Companion Companion = null; public static String pin(Certificate p0){ return null; } + static public class Builder + { + public Builder(){} + public final CertificatePinner build(){ return null; } + public final CertificatePinner.Builder add(String p0, String... p1){ return null; } + public final List getPins(){ return null; } + } static public class Companion { protected Companion() {} diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Challenge.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Challenge.java index f64fe1436b4..1d9ea8eff1c 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Challenge.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Challenge.java @@ -5,42 +5,17 @@ package okhttp3; import java.nio.charset.Charset; import java.util.Map; -public class Challenge { +public class Challenge +{ protected Challenge() {} - - public Challenge(String p0, Map p1) {} - - public Challenge(String p0, String p1) {} - - public String toString() { - return null; - } - - public boolean equals(Object p0) { - return false; - } - - public final Challenge withCharset(Charset p0) { - return null; - } - - public final Charset charset() { - return null; - } - - public final Map authParams() { - return null; - } - - public final String realm() { - return null; - } - - public final String scheme() { - return null; - } - - public int hashCode() { - return 0; - } + public Challenge(String p0, Map p1){} + public Challenge(String p0, String p1){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final Challenge withCharset(Charset p0){ return null; } + public final Charset charset(){ return null; } + public final Map authParams(){ return null; } + public final String realm(){ return null; } + public final String scheme(){ return null; } + public int hashCode(){ return 0; } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CipherSuite.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CipherSuite.java index 24d10e5da04..656be7117c4 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CipherSuite.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/CipherSuite.java @@ -4,17 +4,11 @@ package okhttp3; import java.util.Comparator; -public class CipherSuite { +public class CipherSuite +{ protected CipherSuite() {} - - public String toString() { - return null; - } - - public final String javaName() { - return null; - } - + public String toString(){ return null; } + public final String javaName(){ return null; } public static CipherSuite TLS_AES_128_CCM_8_SHA256 = null; public static CipherSuite TLS_AES_128_CCM_SHA256 = null; public static CipherSuite TLS_AES_128_GCM_SHA256 = null; @@ -134,22 +128,12 @@ public class CipherSuite { public static CipherSuite TLS_RSA_WITH_RC4_128_MD5 = null; public static CipherSuite TLS_RSA_WITH_RC4_128_SHA = null; public static CipherSuite TLS_RSA_WITH_SEED_CBC_SHA = null; - - public static CipherSuite forJavaName(String p0) { - return null; - } - + public static CipherSuite forJavaName(String p0){ return null; } public static CipherSuite.Companion Companion = null; - - static public class Companion { + static public class Companion + { protected Companion() {} - - public final CipherSuite forJavaName(String p0) { - return null; - } - - public final Comparator getORDER_BY_NAME$okhttp() { - return null; - } + public final CipherSuite forJavaName(String p0){ return null; } + public final Comparator getORDER_BY_NAME$okhttp(){ return null; } } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/ConnectionSpec.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/ConnectionSpec.java index 9f8d14b4714..59c04bc0910 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/ConnectionSpec.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/ConnectionSpec.java @@ -7,52 +7,26 @@ import javax.net.ssl.SSLSocket; import okhttp3.CipherSuite; import okhttp3.TlsVersion; -public class ConnectionSpec { +public class ConnectionSpec +{ protected ConnectionSpec() {} - - public ConnectionSpec(boolean p0, boolean p1, String[] p2, String[] p3) {} - - public String toString() { - return null; - } - - public boolean equals(Object p0) { - return false; - } - - public final List cipherSuites() { - return null; - } - - public final List tlsVersions() { - return null; - } - - public final boolean isCompatible(SSLSocket p0) { - return false; - } - - public final boolean isTls() { - return false; - } - - public final boolean supportsTlsExtensions() { - return false; - } - - public final void apply$okhttp(SSLSocket p0, boolean p1) {} - - public int hashCode() { - return 0; - } - + public ConnectionSpec(boolean p0, boolean p1, String[] p2, String[] p3){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final List cipherSuites(){ return null; } + public final List tlsVersions(){ return null; } + public final boolean isCompatible(SSLSocket p0){ return false; } + public final boolean isTls(){ return false; } + public final boolean supportsTlsExtensions(){ return false; } + public final void apply$okhttp(SSLSocket p0, boolean p1){} + public int hashCode(){ return 0; } public static ConnectionSpec CLEARTEXT = null; public static ConnectionSpec COMPATIBLE_TLS = null; public static ConnectionSpec MODERN_TLS = null; public static ConnectionSpec RESTRICTED_TLS = null; public static ConnectionSpec.Companion Companion = null; - - static public class Companion { + static public class Companion + { protected Companion() {} } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Cookie.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Cookie.java index 3ffd4a2a270..f9e8c481a77 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Cookie.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Cookie.java @@ -6,88 +6,31 @@ import java.util.List; import okhttp3.Headers; import okhttp3.HttpUrl; -public class Cookie { +public class Cookie +{ protected Cookie() {} - - public String toString() { - return null; - } - - public boolean equals(Object p0) { - return false; - } - - public final String domain() { - return null; - } - - public final String name() { - return null; - } - - public final String path() { - return null; - } - - public final String toString$okhttp(boolean p0) { - return null; - } - - public final String value() { - return null; - } - - public final boolean hostOnly() { - return false; - } - - public final boolean httpOnly() { - return false; - } - - public final boolean matches(HttpUrl p0) { - return false; - } - - public final boolean persistent() { - return false; - } - - public final boolean secure() { - return false; - } - - public final long expiresAt() { - return 0; - } - - public int hashCode() { - return 0; - } - - public static Cookie parse(HttpUrl p0, String p1) { - return null; - } - + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final String domain(){ return null; } + public final String name(){ return null; } + public final String path(){ return null; } + public final String toString$okhttp(boolean p0){ return null; } + public final String value(){ return null; } + public final boolean hostOnly(){ return false; } + public final boolean httpOnly(){ return false; } + public final boolean matches(HttpUrl p0){ return false; } + public final boolean persistent(){ return false; } + public final boolean secure(){ return false; } + public final long expiresAt(){ return 0; } + public int hashCode(){ return 0; } + public static Cookie parse(HttpUrl p0, String p1){ return null; } public static Cookie.Companion Companion = null; - - public static List parseAll(HttpUrl p0, Headers p1) { - return null; - } - - static public class Companion { + public static List parseAll(HttpUrl p0, Headers p1){ return null; } + static public class Companion + { protected Companion() {} - - public final Cookie parse$okhttp(long p0, HttpUrl p1, String p2) { - return null; - } - - public final Cookie parse(HttpUrl p0, String p1) { - return null; - } - - public final List parseAll(HttpUrl p0, Headers p1) { - return null; - } + public final Cookie parse$okhttp(long p0, HttpUrl p1, String p2){ return null; } + public final Cookie parse(HttpUrl p0, String p1){ return null; } + public final List parseAll(HttpUrl p0, Headers p1){ return null; } } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Dispatcher.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Dispatcher.java index ca74ca9e775..9e2acffb284 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Dispatcher.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Dispatcher.java @@ -7,56 +7,24 @@ import java.util.concurrent.ExecutorService; import okhttp3.Call; import okhttp3.internal.connection.RealCall; -public class Dispatcher { - public Dispatcher() {} - - public Dispatcher(ExecutorService p0) {} - - public final ExecutorService executorService() { - return null; - } - - public final List queuedCalls() { - return null; - } - - public final List runningCalls() { - return null; - } - - public final Runnable getIdleCallback() { - return null; - } - - public final int getMaxRequests() { - return 0; - } - - public final int getMaxRequestsPerHost() { - return 0; - } - - public final int queuedCallsCount() { - return 0; - } - - public final int runningCallsCount() { - return 0; - } - - public final void cancelAll() {} - - public final void enqueue$okhttp(RealCall.AsyncCall p0) {} - - public final void executed$okhttp(RealCall p0) {} - - public final void finished$okhttp(RealCall p0) {} - - public final void finished$okhttp(RealCall.AsyncCall p0) {} - - public final void setIdleCallback(Runnable p0) {} - - public final void setMaxRequests(int p0) {} - - public final void setMaxRequestsPerHost(int p0) {} +public class Dispatcher +{ + public Dispatcher(){} + public Dispatcher(ExecutorService p0){} + public final ExecutorService executorService(){ return null; } + public final List queuedCalls(){ return null; } + public final List runningCalls(){ return null; } + public final Runnable getIdleCallback(){ return null; } + public final int getMaxRequests(){ return 0; } + public final int getMaxRequestsPerHost(){ return 0; } + public final int queuedCallsCount(){ return 0; } + public final int runningCallsCount(){ return 0; } + public final void cancelAll(){} + public final void enqueue$okhttp(RealCall.AsyncCall p0){} + public final void executed$okhttp(RealCall p0){} + public final void finished$okhttp(RealCall p0){} + public final void finished$okhttp(RealCall.AsyncCall p0){} + public final void setIdleCallback(Runnable p0){} + public final void setMaxRequests(int p0){} + public final void setMaxRequestsPerHost(int p0){} } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Handshake.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Handshake.java index 2f97dee0c4c..b0ef923700c 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Handshake.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Handshake.java @@ -10,69 +10,26 @@ import kotlin.jvm.functions.Function0; import okhttp3.CipherSuite; import okhttp3.TlsVersion; -public class Handshake { +public class Handshake +{ protected Handshake() {} - - public Handshake(TlsVersion p0, CipherSuite p1, List p2, - Function0> p3) {} - - public String toString() { - return null; - } - - public boolean equals(Object p0) { - return false; - } - - public final CipherSuite cipherSuite() { - return null; - } - - public final List localCertificates() { - return null; - } - - public final List peerCertificates() { - return null; - } - - public final Principal localPrincipal() { - return null; - } - - public final Principal peerPrincipal() { - return null; - } - - public final TlsVersion tlsVersion() { - return null; - } - - public int hashCode() { - return 0; - } - - public static Handshake get(SSLSession p0) { - return null; - } - - public static Handshake get(TlsVersion p0, CipherSuite p1, List p2, - List p3) { - return null; - } - + public Handshake(TlsVersion p0, CipherSuite p1, List p2, Function0> p3){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final CipherSuite cipherSuite(){ return null; } + public final List localCertificates(){ return null; } + public final List peerCertificates(){ return null; } + public final Principal localPrincipal(){ return null; } + public final Principal peerPrincipal(){ return null; } + public final TlsVersion tlsVersion(){ return null; } + public int hashCode(){ return 0; } + public static Handshake get(SSLSession p0){ return null; } + public static Handshake get(TlsVersion p0, CipherSuite p1, List p2, List p3){ return null; } public static Handshake.Companion Companion = null; - - static public class Companion { + static public class Companion + { protected Companion() {} - - public final Handshake get(SSLSession p0) { - return null; - } - - public final Handshake get(TlsVersion p0, CipherSuite p1, List p2, - List p3) { - return null; - } + public final Handshake get(SSLSession p0){ return null; } + public final Handshake get(TlsVersion p0, CipherSuite p1, List p2, List p3){ return null; } } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/HttpUrl.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/HttpUrl.java index 5fef4d9606d..d33e5834d4e 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/HttpUrl.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/HttpUrl.java @@ -8,156 +8,46 @@ import java.nio.charset.Charset; import java.util.List; import java.util.Set; -public class HttpUrl { +public class HttpUrl +{ protected HttpUrl() {} - - public HttpUrl(String p0, String p1, String p2, String p3, int p4, List p5, - List p6, String p7, String p8) {} - - public String toString() { - return null; - } - - public boolean equals(Object p0) { - return false; - } - - public final HttpUrl resolve(String p0) { - return null; - } - - public final HttpUrl.Builder newBuilder() { - return null; - } - - public final HttpUrl.Builder newBuilder(String p0) { - return null; - } - - public final List encodedPathSegments() { - return null; - } - - public final List pathSegments() { - return null; - } - - public final List queryParameterValues(String p0) { - return null; - } - - public final Set queryParameterNames() { - return null; - } - - public final String encodedFragment() { - return null; - } - - public final String encodedPassword() { - return null; - } - - public final String encodedPath() { - return null; - } - - public final String encodedQuery() { - return null; - } - - public final String encodedUsername() { - return null; - } - - public final String fragment() { - return null; - } - - public final String host() { - return null; - } - - public final String password() { - return null; - } - - public final String query() { - return null; - } - - public final String queryParameter(String p0) { - return null; - } - - public final String queryParameterName(int p0) { - return null; - } - - public final String queryParameterValue(int p0) { - return null; - } - - public final String redact() { - return null; - } - - public final String scheme() { - return null; - } - - public final String topPrivateDomain() { - return null; - } - - public final String username() { - return null; - } - - public final URI uri() { - return null; - } - - public final URL url() { - return null; - } - - public final boolean isHttps() { - return false; - } - - public final int pathSize() { - return 0; - } - - public final int port() { - return 0; - } - - public final int querySize() { - return 0; - } - - public int hashCode() { - return 0; - } - - public static HttpUrl get(String p0) { - return null; - } - - public static HttpUrl get(URI p0) { - return null; - } - - public static HttpUrl get(URL p0) { - return null; - } - - public static HttpUrl parse(String p0) { - return null; - } - + public HttpUrl(String p0, String p1, String p2, String p3, int p4, List p5, List p6, String p7, String p8){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final HttpUrl resolve(String p0){ return null; } + public final HttpUrl.Builder newBuilder(){ return null; } + public final HttpUrl.Builder newBuilder(String p0){ return null; } + public final List encodedPathSegments(){ return null; } + public final List pathSegments(){ return null; } + public final List queryParameterValues(String p0){ return null; } + public final Set queryParameterNames(){ return null; } + public final String encodedFragment(){ return null; } + public final String encodedPassword(){ return null; } + public final String encodedPath(){ return null; } + public final String encodedQuery(){ return null; } + public final String encodedUsername(){ return null; } + public final String fragment(){ return null; } + public final String host(){ return null; } + public final String password(){ return null; } + public final String query(){ return null; } + public final String queryParameter(String p0){ return null; } + public final String queryParameterName(int p0){ return null; } + public final String queryParameterValue(int p0){ return null; } + public final String redact(){ return null; } + public final String scheme(){ return null; } + public final String topPrivateDomain(){ return null; } + public final String username(){ return null; } + public final URI uri(){ return null; } + public final URL url(){ return null; } + public final boolean isHttps(){ return false; } + public final int pathSize(){ return 0; } + public final int port(){ return 0; } + public final int querySize(){ return 0; } + public int hashCode(){ return 0; } + public static HttpUrl get(String p0){ return null; } + public static HttpUrl get(URI p0){ return null; } + public static HttpUrl get(URL p0){ return null; } + public static HttpUrl parse(String p0){ return null; } public static HttpUrl.Companion Companion = null; public static String FORM_ENCODE_SET = null; public static String FRAGMENT_ENCODE_SET = null; @@ -170,221 +60,73 @@ public class HttpUrl { public static String QUERY_COMPONENT_REENCODE_SET = null; public static String QUERY_ENCODE_SET = null; public static String USERNAME_ENCODE_SET = null; - - public static int defaultPort(String p0) { - return 0; - } - - static public class Builder { - public Builder() {} - - public String toString() { - return null; - } - - public final HttpUrl build() { - return null; - } - - public final HttpUrl.Builder addEncodedPathSegment(String p0) { - return null; - } - - public final HttpUrl.Builder addEncodedPathSegments(String p0) { - return null; - } - - public final HttpUrl.Builder addEncodedQueryParameter(String p0, String p1) { - return null; - } - - public final HttpUrl.Builder addPathSegment(String p0) { - return null; - } - - public final HttpUrl.Builder addPathSegments(String p0) { - return null; - } - - public final HttpUrl.Builder addQueryParameter(String p0, String p1) { - return null; - } - - public final HttpUrl.Builder encodedFragment(String p0) { - return null; - } - - public final HttpUrl.Builder encodedPassword(String p0) { - return null; - } - - public final HttpUrl.Builder encodedPath(String p0) { - return null; - } - - public final HttpUrl.Builder encodedQuery(String p0) { - return null; - } - - public final HttpUrl.Builder encodedUsername(String p0) { - return null; - } - - public final HttpUrl.Builder fragment(String p0) { - return null; - } - - public final HttpUrl.Builder host(String p0) { - return null; - } - - public final HttpUrl.Builder parse$okhttp(HttpUrl p0, String p1) { - return null; - } - - public final HttpUrl.Builder password(String p0) { - return null; - } - - public final HttpUrl.Builder port(int p0) { - return null; - } - - public final HttpUrl.Builder query(String p0) { - return null; - } - - public final HttpUrl.Builder reencodeForUri$okhttp() { - return null; - } - - public final HttpUrl.Builder removeAllEncodedQueryParameters(String p0) { - return null; - } - - public final HttpUrl.Builder removeAllQueryParameters(String p0) { - return null; - } - - public final HttpUrl.Builder removePathSegment(int p0) { - return null; - } - - public final HttpUrl.Builder scheme(String p0) { - return null; - } - - public final HttpUrl.Builder setEncodedPathSegment(int p0, String p1) { - return null; - } - - public final HttpUrl.Builder setEncodedQueryParameter(String p0, String p1) { - return null; - } - - public final HttpUrl.Builder setPathSegment(int p0, String p1) { - return null; - } - - public final HttpUrl.Builder setQueryParameter(String p0, String p1) { - return null; - } - - public final HttpUrl.Builder username(String p0) { - return null; - } - - public final List getEncodedPathSegments$okhttp() { - return null; - } - - public final List getEncodedQueryNamesAndValues$okhttp() { - return null; - } - - public final String getEncodedFragment$okhttp() { - return null; - } - - public final String getEncodedPassword$okhttp() { - return null; - } - - public final String getEncodedUsername$okhttp() { - return null; - } - - public final String getHost$okhttp() { - return null; - } - - public final String getScheme$okhttp() { - return null; - } - - public final int getPort$okhttp() { - return 0; - } - - public final void setEncodedFragment$okhttp(String p0) {} - - public final void setEncodedPassword$okhttp(String p0) {} - - public final void setEncodedQueryNamesAndValues$okhttp(List p0) {} - - public final void setEncodedUsername$okhttp(String p0) {} - - public final void setHost$okhttp(String p0) {} - - public final void setPort$okhttp(int p0) {} - - public final void setScheme$okhttp(String p0) {} - + public static int defaultPort(String p0){ return 0; } + static public class Builder + { + public Builder(){} + public String toString(){ return null; } + public final HttpUrl build(){ return null; } + public final HttpUrl.Builder addEncodedPathSegment(String p0){ return null; } + public final HttpUrl.Builder addEncodedPathSegments(String p0){ return null; } + public final HttpUrl.Builder addEncodedQueryParameter(String p0, String p1){ return null; } + public final HttpUrl.Builder addPathSegment(String p0){ return null; } + public final HttpUrl.Builder addPathSegments(String p0){ return null; } + public final HttpUrl.Builder addQueryParameter(String p0, String p1){ return null; } + public final HttpUrl.Builder encodedFragment(String p0){ return null; } + public final HttpUrl.Builder encodedPassword(String p0){ return null; } + public final HttpUrl.Builder encodedPath(String p0){ return null; } + public final HttpUrl.Builder encodedQuery(String p0){ return null; } + public final HttpUrl.Builder encodedUsername(String p0){ return null; } + public final HttpUrl.Builder fragment(String p0){ return null; } + public final HttpUrl.Builder host(String p0){ return null; } + public final HttpUrl.Builder parse$okhttp(HttpUrl p0, String p1){ return null; } + public final HttpUrl.Builder password(String p0){ return null; } + public final HttpUrl.Builder port(int p0){ return null; } + public final HttpUrl.Builder query(String p0){ return null; } + public final HttpUrl.Builder reencodeForUri$okhttp(){ return null; } + public final HttpUrl.Builder removeAllEncodedQueryParameters(String p0){ return null; } + public final HttpUrl.Builder removeAllQueryParameters(String p0){ return null; } + public final HttpUrl.Builder removePathSegment(int p0){ return null; } + public final HttpUrl.Builder scheme(String p0){ return null; } + public final HttpUrl.Builder setEncodedPathSegment(int p0, String p1){ return null; } + public final HttpUrl.Builder setEncodedQueryParameter(String p0, String p1){ return null; } + public final HttpUrl.Builder setPathSegment(int p0, String p1){ return null; } + public final HttpUrl.Builder setQueryParameter(String p0, String p1){ return null; } + public final HttpUrl.Builder username(String p0){ return null; } + public final List getEncodedPathSegments$okhttp(){ return null; } + public final List getEncodedQueryNamesAndValues$okhttp(){ return null; } + public final String getEncodedFragment$okhttp(){ return null; } + public final String getEncodedPassword$okhttp(){ return null; } + public final String getEncodedUsername$okhttp(){ return null; } + public final String getHost$okhttp(){ return null; } + public final String getScheme$okhttp(){ return null; } + public final int getPort$okhttp(){ return 0; } + public final void setEncodedFragment$okhttp(String p0){} + public final void setEncodedPassword$okhttp(String p0){} + public final void setEncodedQueryNamesAndValues$okhttp(List p0){} + public final void setEncodedUsername$okhttp(String p0){} + public final void setHost$okhttp(String p0){} + public final void setPort$okhttp(int p0){} + public final void setScheme$okhttp(String p0){} public static HttpUrl.Builder.Companion Companion = null; public static String INVALID_HOST = null; - - static public class Companion { + static public class Companion + { protected Companion() {} } } - static public class Companion { + static public class Companion + { protected Companion() {} - - public final HttpUrl get(String p0) { - return null; - } - - public final HttpUrl get(URI p0) { - return null; - } - - public final HttpUrl get(URL p0) { - return null; - } - - public final HttpUrl parse(String p0) { - return null; - } - - public final List toQueryNamesAndValues$okhttp(String p0) { - return null; - } - - public final String canonicalize$okhttp(String p0, int p1, int p2, String p3, boolean p4, - boolean p5, boolean p6, boolean p7, Charset p8) { - return null; - } - - public final String percentDecode$okhttp(String p0, int p1, int p2, boolean p3) { - return null; - } - - public final int defaultPort(String p0) { - return 0; - } - - public final void toPathString$okhttp(List p0, StringBuilder p1) {} - - public final void toQueryString$okhttp(List p0, StringBuilder p1) {} + public final HttpUrl get(String p0){ return null; } + public final HttpUrl get(URI p0){ return null; } + public final HttpUrl get(URL p0){ return null; } + public final HttpUrl parse(String p0){ return null; } + public final List toQueryNamesAndValues$okhttp(String p0){ return null; } + public final String canonicalize$okhttp(String p0, int p1, int p2, String p3, boolean p4, boolean p5, boolean p6, boolean p7, Charset p8){ return null; } + public final String percentDecode$okhttp(String p0, int p1, int p2, boolean p3){ return null; } + public final int defaultPort(String p0){ return 0; } + public final void toPathString$okhttp(List p0, StringBuilder p1){} + public final void toQueryString$okhttp(List p0, StringBuilder p1){} } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/MediaType.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/MediaType.java index 2b3a2f0117a..e16108d4253 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/MediaType.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/MediaType.java @@ -4,60 +4,24 @@ package okhttp3; import java.nio.charset.Charset; -public class MediaType { +public class MediaType +{ protected MediaType() {} - - public String toString() { - return null; - } - - public boolean equals(Object p0) { - return false; - } - - public final Charset charset() { - return null; - } - - public final Charset charset(Charset p0) { - return null; - } - - public final String parameter(String p0) { - return null; - } - - public final String subtype() { - return null; - } - - public final String type() { - return null; - } - - public int hashCode() { - return 0; - } - - public static MediaType get(String p0) { - return null; - } - - public static MediaType parse(String p0) { - return null; - } - + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final Charset charset(){ return null; } + public final Charset charset(Charset p0){ return null; } + public final String parameter(String p0){ return null; } + public final String subtype(){ return null; } + public final String type(){ return null; } + public int hashCode(){ return 0; } + public static MediaType get(String p0){ return null; } + public static MediaType parse(String p0){ return null; } public static MediaType.Companion Companion = null; - - static public class Companion { + static public class Companion + { protected Companion() {} - - public final MediaType get(String p0) { - return null; - } - - public final MediaType parse(String p0) { - return null; - } + public final MediaType get(String p0){ return null; } + public final MediaType parse(String p0){ return null; } } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/OkHttpClient.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/OkHttpClient.java index 2af0180eb36..35626e283e0 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/OkHttpClient.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/OkHttpClient.java @@ -11,7 +11,6 @@ import javax.net.SocketFactory; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509TrustManager; -import kotlin.jvm.functions.Function1; import okhttp3.Authenticator; import okhttp3.Cache; import okhttp3.Call; @@ -25,504 +24,154 @@ import okhttp3.EventListener; import okhttp3.Interceptor; import okhttp3.Protocol; import okhttp3.Request; -import okhttp3.Response; import okhttp3.WebSocket; import okhttp3.WebSocketListener; import okhttp3.internal.connection.RouteDatabase; import okhttp3.internal.tls.CertificateChainCleaner; -public class OkHttpClient implements Call.Factory, Cloneable, WebSocket.Factory { - public Call newCall(Request p0) { - return null; - } - - public Object clone() { - return null; - } - - public OkHttpClient() {} - - public OkHttpClient(OkHttpClient.Builder p0) {} - - public OkHttpClient.Builder newBuilder() { - return null; - } - - public WebSocket newWebSocket(Request p0, WebSocketListener p1) { - return null; - } - - public final Authenticator authenticator() { - return null; - } - - public final Authenticator proxyAuthenticator() { - return null; - } - - public final Cache cache() { - return null; - } - - public final CertificateChainCleaner certificateChainCleaner() { - return null; - } - - public final CertificatePinner certificatePinner() { - return null; - } - - public final ConnectionPool connectionPool() { - return null; - } - - public final CookieJar cookieJar() { - return null; - } - - public final Dispatcher dispatcher() { - return null; - } - - public final Dns dns() { - return null; - } - - public final EventListener.Factory eventListenerFactory() { - return null; - } - - public final HostnameVerifier hostnameVerifier() { - return null; - } - - public final List connectionSpecs() { - return null; - } - - public final List interceptors() { - return null; - } - - public final List networkInterceptors() { - return null; - } - - public final List protocols() { - return null; - } - - public final Proxy proxy() { - return null; - } - - public final ProxySelector proxySelector() { - return null; - } - - public final RouteDatabase getRouteDatabase() { - return null; - } - - public final SSLSocketFactory sslSocketFactory() { - return null; - } - - public final SocketFactory socketFactory() { - return null; - } - - public final X509TrustManager x509TrustManager() { - return null; - } - - public final boolean followRedirects() { - return false; - } - - public final boolean followSslRedirects() { - return false; - } - - public final boolean retryOnConnectionFailure() { - return false; - } - - public final int callTimeoutMillis() { - return 0; - } - - public final int connectTimeoutMillis() { - return 0; - } - - public final int pingIntervalMillis() { - return 0; - } - - public final int readTimeoutMillis() { - return 0; - } - - public final int writeTimeoutMillis() { - return 0; - } - - public final long minWebSocketMessageToCompress() { - return 0; - } - +public class OkHttpClient implements Call.Factory, Cloneable, WebSocket.Factory +{ + public Call newCall(Request p0){ return null; } + public Object clone(){ return null; } + public OkHttpClient(){} + public OkHttpClient(OkHttpClient.Builder p0){} + public OkHttpClient.Builder newBuilder(){ return null; } + public WebSocket newWebSocket(Request p0, WebSocketListener p1){ return null; } + public final Authenticator authenticator(){ return null; } + public final Authenticator proxyAuthenticator(){ return null; } + public final Cache cache(){ return null; } + public final CertificateChainCleaner certificateChainCleaner(){ return null; } + public final CertificatePinner certificatePinner(){ return null; } + public final ConnectionPool connectionPool(){ return null; } + public final CookieJar cookieJar(){ return null; } + public final Dispatcher dispatcher(){ return null; } + public final Dns dns(){ return null; } + public final EventListener.Factory eventListenerFactory(){ return null; } + public final HostnameVerifier hostnameVerifier(){ return null; } + public final List connectionSpecs(){ return null; } + public final List interceptors(){ return null; } + public final List networkInterceptors(){ return null; } + public final List protocols(){ return null; } + public final Proxy proxy(){ return null; } + public final ProxySelector proxySelector(){ return null; } + public final RouteDatabase getRouteDatabase(){ return null; } + public final SSLSocketFactory sslSocketFactory(){ return null; } + public final SocketFactory socketFactory(){ return null; } + public final X509TrustManager x509TrustManager(){ return null; } + public final boolean followRedirects(){ return false; } + public final boolean followSslRedirects(){ return false; } + public final boolean retryOnConnectionFailure(){ return false; } + public final int callTimeoutMillis(){ return 0; } + public final int connectTimeoutMillis(){ return 0; } + public final int pingIntervalMillis(){ return 0; } + public final int readTimeoutMillis(){ return 0; } + public final int writeTimeoutMillis(){ return 0; } + public final long minWebSocketMessageToCompress(){ return 0; } public static OkHttpClient.Companion Companion = null; - - static public class Builder { - public Builder() {} - - public Builder(OkHttpClient p0) {} - - public final Authenticator getAuthenticator$okhttp() { - return null; - } - - public final Authenticator getProxyAuthenticator$okhttp() { - return null; - } - - public final Cache getCache$okhttp() { - return null; - } - - public final CertificateChainCleaner getCertificateChainCleaner$okhttp() { - return null; - } - - public final CertificatePinner getCertificatePinner$okhttp() { - return null; - } - - public final ConnectionPool getConnectionPool$okhttp() { - return null; - } - - public final CookieJar getCookieJar$okhttp() { - return null; - } - - public final Dispatcher getDispatcher$okhttp() { - return null; - } - - public final Dns getDns$okhttp() { - return null; - } - - public final EventListener.Factory getEventListenerFactory$okhttp() { - return null; - } - - public final HostnameVerifier getHostnameVerifier$okhttp() { - return null; - } - - public final List getConnectionSpecs$okhttp() { - return null; - } - - public final List getInterceptors$okhttp() { - return null; - } - - public final List getNetworkInterceptors$okhttp() { - return null; - } - - public final List interceptors() { - return null; - } - - public final List networkInterceptors() { - return null; - } - - public final List getProtocols$okhttp() { - return null; - } - - public final OkHttpClient build() { - return null; - } - - public final OkHttpClient.Builder addInterceptor( - Function1 p0) { - return null; - } - - public final OkHttpClient.Builder addNetworkInterceptor( - Function1 p0) { - return null; - } - - public final OkHttpClient.Builder addInterceptor(Interceptor p0) { - return null; - } - - public final OkHttpClient.Builder addNetworkInterceptor(Interceptor p0) { - return null; - } - - public final OkHttpClient.Builder authenticator(Authenticator p0) { - return null; - } - - public final OkHttpClient.Builder cache(Cache p0) { - return null; - } - - public final OkHttpClient.Builder callTimeout(Duration p0) { - return null; - } - - public final OkHttpClient.Builder callTimeout(long p0, TimeUnit p1) { - return null; - } - - public final OkHttpClient.Builder certificatePinner(CertificatePinner p0) { - return null; - } - - public final OkHttpClient.Builder connectTimeout(Duration p0) { - return null; - } - - public final OkHttpClient.Builder connectTimeout(long p0, TimeUnit p1) { - return null; - } - - public final OkHttpClient.Builder connectionPool(ConnectionPool p0) { - return null; - } - - public final OkHttpClient.Builder connectionSpecs(List p0) { - return null; - } - - public final OkHttpClient.Builder cookieJar(CookieJar p0) { - return null; - } - - public final OkHttpClient.Builder dispatcher(Dispatcher p0) { - return null; - } - - public final OkHttpClient.Builder dns(Dns p0) { - return null; - } - - public final OkHttpClient.Builder eventListener(EventListener p0) { - return null; - } - - public final OkHttpClient.Builder eventListenerFactory(EventListener.Factory p0) { - return null; - } - - public final OkHttpClient.Builder followRedirects(boolean p0) { - return null; - } - - public final OkHttpClient.Builder followSslRedirects(boolean p0) { - return null; - } - - public final OkHttpClient.Builder hostnameVerifier(HostnameVerifier p0) { - return null; - } - - public final OkHttpClient.Builder minWebSocketMessageToCompress(long p0) { - return null; - } - - public final OkHttpClient.Builder pingInterval(Duration p0) { - return null; - } - - public final OkHttpClient.Builder pingInterval(long p0, TimeUnit p1) { - return null; - } - - public final OkHttpClient.Builder protocols(List p0) { - return null; - } - - public final OkHttpClient.Builder proxy(Proxy p0) { - return null; - } - - public final OkHttpClient.Builder proxyAuthenticator(Authenticator p0) { - return null; - } - - public final OkHttpClient.Builder proxySelector(ProxySelector p0) { - return null; - } - - public final OkHttpClient.Builder readTimeout(Duration p0) { - return null; - } - - public final OkHttpClient.Builder readTimeout(long p0, TimeUnit p1) { - return null; - } - - public final OkHttpClient.Builder retryOnConnectionFailure(boolean p0) { - return null; - } - - public final OkHttpClient.Builder socketFactory(SocketFactory p0) { - return null; - } - - public final OkHttpClient.Builder sslSocketFactory(SSLSocketFactory p0) { - return null; - } - - public final OkHttpClient.Builder sslSocketFactory(SSLSocketFactory p0, - X509TrustManager p1) { - return null; - } - - public final OkHttpClient.Builder writeTimeout(Duration p0) { - return null; - } - - public final OkHttpClient.Builder writeTimeout(long p0, TimeUnit p1) { - return null; - } - - public final Proxy getProxy$okhttp() { - return null; - } - - public final ProxySelector getProxySelector$okhttp() { - return null; - } - - public final RouteDatabase getRouteDatabase$okhttp() { - return null; - } - - public final SSLSocketFactory getSslSocketFactoryOrNull$okhttp() { - return null; - } - - public final SocketFactory getSocketFactory$okhttp() { - return null; - } - - public final X509TrustManager getX509TrustManagerOrNull$okhttp() { - return null; - } - - public final boolean getFollowRedirects$okhttp() { - return false; - } - - public final boolean getFollowSslRedirects$okhttp() { - return false; - } - - public final boolean getRetryOnConnectionFailure$okhttp() { - return false; - } - - public final int getCallTimeout$okhttp() { - return 0; - } - - public final int getConnectTimeout$okhttp() { - return 0; - } - - public final int getPingInterval$okhttp() { - return 0; - } - - public final int getReadTimeout$okhttp() { - return 0; - } - - public final int getWriteTimeout$okhttp() { - return 0; - } - - public final long getMinWebSocketMessageToCompress$okhttp() { - return 0; - } - - public final void setAuthenticator$okhttp(Authenticator p0) {} - - public final void setCache$okhttp(Cache p0) {} - - public final void setCallTimeout$okhttp(int p0) {} - - public final void setCertificateChainCleaner$okhttp(CertificateChainCleaner p0) {} - - public final void setCertificatePinner$okhttp(CertificatePinner p0) {} - - public final void setConnectTimeout$okhttp(int p0) {} - - public final void setConnectionPool$okhttp(ConnectionPool p0) {} - - public final void setConnectionSpecs$okhttp(List p0) {} - - public final void setCookieJar$okhttp(CookieJar p0) {} - - public final void setDispatcher$okhttp(Dispatcher p0) {} - - public final void setDns$okhttp(Dns p0) {} - - public final void setEventListenerFactory$okhttp(EventListener.Factory p0) {} - - public final void setFollowRedirects$okhttp(boolean p0) {} - - public final void setFollowSslRedirects$okhttp(boolean p0) {} - - public final void setHostnameVerifier$okhttp(HostnameVerifier p0) {} - - public final void setMinWebSocketMessageToCompress$okhttp(long p0) {} - - public final void setPingInterval$okhttp(int p0) {} - - public final void setProtocols$okhttp(List p0) {} - - public final void setProxy$okhttp(Proxy p0) {} - - public final void setProxyAuthenticator$okhttp(Authenticator p0) {} - - public final void setProxySelector$okhttp(ProxySelector p0) {} - - public final void setReadTimeout$okhttp(int p0) {} - - public final void setRetryOnConnectionFailure$okhttp(boolean p0) {} - - public final void setRouteDatabase$okhttp(RouteDatabase p0) {} - - public final void setSocketFactory$okhttp(SocketFactory p0) {} - - public final void setSslSocketFactoryOrNull$okhttp(SSLSocketFactory p0) {} - - public final void setWriteTimeout$okhttp(int p0) {} - - public final void setX509TrustManagerOrNull$okhttp(X509TrustManager p0) {} + static public class Builder + { + public Builder(){} + public Builder(OkHttpClient p0){} + public final Authenticator getAuthenticator$okhttp(){ return null; } + public final Authenticator getProxyAuthenticator$okhttp(){ return null; } + public final Cache getCache$okhttp(){ return null; } + public final CertificateChainCleaner getCertificateChainCleaner$okhttp(){ return null; } + public final CertificatePinner getCertificatePinner$okhttp(){ return null; } + public final ConnectionPool getConnectionPool$okhttp(){ return null; } + public final CookieJar getCookieJar$okhttp(){ return null; } + public final Dispatcher getDispatcher$okhttp(){ return null; } + public final Dns getDns$okhttp(){ return null; } + public final EventListener.Factory getEventListenerFactory$okhttp(){ return null; } + public final HostnameVerifier getHostnameVerifier$okhttp(){ return null; } + public final List getConnectionSpecs$okhttp(){ return null; } + public final List getInterceptors$okhttp(){ return null; } + public final List getNetworkInterceptors$okhttp(){ return null; } + public final List interceptors(){ return null; } + public final List networkInterceptors(){ return null; } + public final List getProtocols$okhttp(){ return null; } + public final OkHttpClient build(){ return null; } + public final OkHttpClient.Builder addInterceptor(Interceptor p0){ return null; } + public final OkHttpClient.Builder addNetworkInterceptor(Interceptor p0){ return null; } + public final OkHttpClient.Builder authenticator(Authenticator p0){ return null; } + public final OkHttpClient.Builder cache(Cache p0){ return null; } + public final OkHttpClient.Builder callTimeout(Duration p0){ return null; } + public final OkHttpClient.Builder callTimeout(long p0, TimeUnit p1){ return null; } + public final OkHttpClient.Builder certificatePinner(CertificatePinner p0){ return null; } + public final OkHttpClient.Builder connectTimeout(Duration p0){ return null; } + public final OkHttpClient.Builder connectTimeout(long p0, TimeUnit p1){ return null; } + public final OkHttpClient.Builder connectionPool(ConnectionPool p0){ return null; } + public final OkHttpClient.Builder connectionSpecs(List p0){ return null; } + public final OkHttpClient.Builder cookieJar(CookieJar p0){ return null; } + public final OkHttpClient.Builder dispatcher(Dispatcher p0){ return null; } + public final OkHttpClient.Builder dns(Dns p0){ return null; } + public final OkHttpClient.Builder eventListener(EventListener p0){ return null; } + public final OkHttpClient.Builder eventListenerFactory(EventListener.Factory p0){ return null; } + public final OkHttpClient.Builder followRedirects(boolean p0){ return null; } + public final OkHttpClient.Builder followSslRedirects(boolean p0){ return null; } + public final OkHttpClient.Builder hostnameVerifier(HostnameVerifier p0){ return null; } + public final OkHttpClient.Builder minWebSocketMessageToCompress(long p0){ return null; } + public final OkHttpClient.Builder pingInterval(Duration p0){ return null; } + public final OkHttpClient.Builder pingInterval(long p0, TimeUnit p1){ return null; } + public final OkHttpClient.Builder protocols(List p0){ return null; } + public final OkHttpClient.Builder proxy(Proxy p0){ return null; } + public final OkHttpClient.Builder proxyAuthenticator(Authenticator p0){ return null; } + public final OkHttpClient.Builder proxySelector(ProxySelector p0){ return null; } + public final OkHttpClient.Builder readTimeout(Duration p0){ return null; } + public final OkHttpClient.Builder readTimeout(long p0, TimeUnit p1){ return null; } + public final OkHttpClient.Builder retryOnConnectionFailure(boolean p0){ return null; } + public final OkHttpClient.Builder socketFactory(SocketFactory p0){ return null; } + public final OkHttpClient.Builder sslSocketFactory(SSLSocketFactory p0){ return null; } + public final OkHttpClient.Builder sslSocketFactory(SSLSocketFactory p0, X509TrustManager p1){ return null; } + public final OkHttpClient.Builder writeTimeout(Duration p0){ return null; } + public final OkHttpClient.Builder writeTimeout(long p0, TimeUnit p1){ return null; } + public final Proxy getProxy$okhttp(){ return null; } + public final ProxySelector getProxySelector$okhttp(){ return null; } + public final RouteDatabase getRouteDatabase$okhttp(){ return null; } + public final SSLSocketFactory getSslSocketFactoryOrNull$okhttp(){ return null; } + public final SocketFactory getSocketFactory$okhttp(){ return null; } + public final X509TrustManager getX509TrustManagerOrNull$okhttp(){ return null; } + public final boolean getFollowRedirects$okhttp(){ return false; } + public final boolean getFollowSslRedirects$okhttp(){ return false; } + public final boolean getRetryOnConnectionFailure$okhttp(){ return false; } + public final int getCallTimeout$okhttp(){ return 0; } + public final int getConnectTimeout$okhttp(){ return 0; } + public final int getPingInterval$okhttp(){ return 0; } + public final int getReadTimeout$okhttp(){ return 0; } + public final int getWriteTimeout$okhttp(){ return 0; } + public final long getMinWebSocketMessageToCompress$okhttp(){ return 0; } + public final void setAuthenticator$okhttp(Authenticator p0){} + public final void setCache$okhttp(Cache p0){} + public final void setCallTimeout$okhttp(int p0){} + public final void setCertificateChainCleaner$okhttp(CertificateChainCleaner p0){} + public final void setCertificatePinner$okhttp(CertificatePinner p0){} + public final void setConnectTimeout$okhttp(int p0){} + public final void setConnectionPool$okhttp(ConnectionPool p0){} + public final void setConnectionSpecs$okhttp(List p0){} + public final void setCookieJar$okhttp(CookieJar p0){} + public final void setDispatcher$okhttp(Dispatcher p0){} + public final void setDns$okhttp(Dns p0){} + public final void setEventListenerFactory$okhttp(EventListener.Factory p0){} + public final void setFollowRedirects$okhttp(boolean p0){} + public final void setFollowSslRedirects$okhttp(boolean p0){} + public final void setHostnameVerifier$okhttp(HostnameVerifier p0){} + public final void setMinWebSocketMessageToCompress$okhttp(long p0){} + public final void setPingInterval$okhttp(int p0){} + public final void setProtocols$okhttp(List p0){} + public final void setProxy$okhttp(Proxy p0){} + public final void setProxyAuthenticator$okhttp(Authenticator p0){} + public final void setProxySelector$okhttp(ProxySelector p0){} + public final void setReadTimeout$okhttp(int p0){} + public final void setRetryOnConnectionFailure$okhttp(boolean p0){} + public final void setRouteDatabase$okhttp(RouteDatabase p0){} + public final void setSocketFactory$okhttp(SocketFactory p0){} + public final void setSslSocketFactoryOrNull$okhttp(SSLSocketFactory p0){} + public final void setWriteTimeout$okhttp(int p0){} + public final void setX509TrustManagerOrNull$okhttp(X509TrustManager p0){} } - static public class Companion { + static public class Companion + { protected Companion() {} - - public final List getDEFAULT_CONNECTION_SPECS$okhttp() { - return null; - } - - public final List getDEFAULT_PROTOCOLS$okhttp() { - return null; - } + public final List getDEFAULT_CONNECTION_SPECS$okhttp(){ return null; } + public final List getDEFAULT_PROTOCOLS$okhttp(){ return null; } } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Request.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Request.java index f00e4c89c40..a43a1d4e852 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Request.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Request.java @@ -10,173 +10,55 @@ import okhttp3.Headers; import okhttp3.HttpUrl; import okhttp3.RequestBody; -public class Request { +public class Request +{ protected Request() {} - - public Request(HttpUrl p0, String p1, Headers p2, RequestBody p3, - Map, ? extends Object> p4) {} - - public String toString() { - return null; - } - - public final T tag(Class p0) { - return null; - } - - public final CacheControl cacheControl() { - return null; - } - - public final Headers headers() { - return null; - } - - public final HttpUrl url() { - return null; - } - - public final List headers(String p0) { - return null; - } - - public final Map, Object> getTags$okhttp() { - return null; - } - - public final Object tag() { - return null; - } - - public final Request.Builder newBuilder() { - return null; - } - - public final RequestBody body() { - return null; - } - - public final String header(String p0) { - return null; - } - - public final String method() { - return null; - } - - public final boolean isHttps() { - return false; - } - - static public class Builder { - public Request.Builder tag(Class p0, T p1) { - return null; - } - - public Builder() {} - - public Builder(Request p0) {} - - public Request build() { - return null; - } - - public Request.Builder addHeader(String p0, String p1) { - return null; - } - - public Request.Builder cacheControl(CacheControl p0) { - return null; - } - - public Request.Builder delete(RequestBody p0) { - return null; - } - - public Request.Builder get() { - return null; - } - - public Request.Builder head() { - return null; - } - - public Request.Builder header(String p0, String p1) { - return null; - } - - public Request.Builder headers(Headers p0) { - return null; - } - - public Request.Builder method(String p0, RequestBody p1) { - return null; - } - - public Request.Builder patch(RequestBody p0) { - return null; - } - - public Request.Builder post(RequestBody p0) { - return null; - } - - public Request.Builder put(RequestBody p0) { - return null; - } - - public Request.Builder removeHeader(String p0) { - return null; - } - - public Request.Builder tag(Object p0) { - return null; - } - - public Request.Builder url(HttpUrl p0) { - return null; - } - - public Request.Builder url(String p0) { - return null; - } - - public Request.Builder url(URL p0) { - return null; - } - - public final Headers.Builder getHeaders$okhttp() { - return null; - } - - public final HttpUrl getUrl$okhttp() { - return null; - } - - public final Map, Object> getTags$okhttp() { - return null; - } - - public final Request.Builder delete() { - return null; - } - - public final RequestBody getBody$okhttp() { - return null; - } - - public final String getMethod$okhttp() { - return null; - } - - public final void setBody$okhttp(RequestBody p0) {} - - public final void setHeaders$okhttp(Headers.Builder p0) {} - - public final void setMethod$okhttp(String p0) {} - - public final void setTags$okhttp(Map, Object> p0) {} - - public final void setUrl$okhttp(HttpUrl p0) {} + public Request(HttpUrl p0, String p1, Headers p2, RequestBody p3, Map, ? extends Object> p4){} + public String toString(){ return null; } + public final T tag(Class p0){ return null; } + public final CacheControl cacheControl(){ return null; } + public final Headers headers(){ return null; } + public final HttpUrl url(){ return null; } + public final List headers(String p0){ return null; } + public final Map, Object> getTags$okhttp(){ return null; } + public final Object tag(){ return null; } + public final Request.Builder newBuilder(){ return null; } + public final RequestBody body(){ return null; } + public final String header(String p0){ return null; } + public final String method(){ return null; } + public final boolean isHttps(){ return false; } + static public class Builder + { + public Request.Builder tag(Class p0, T p1){ return null; } + public Builder(){} + public Builder(Request p0){} + public Request build(){ return null; } + public Request.Builder addHeader(String p0, String p1){ return null; } + public Request.Builder cacheControl(CacheControl p0){ return null; } + public Request.Builder delete(RequestBody p0){ return null; } + public Request.Builder get(){ return null; } + public Request.Builder head(){ return null; } + public Request.Builder header(String p0, String p1){ return null; } + public Request.Builder headers(Headers p0){ return null; } + public Request.Builder method(String p0, RequestBody p1){ return null; } + public Request.Builder patch(RequestBody p0){ return null; } + public Request.Builder post(RequestBody p0){ return null; } + public Request.Builder put(RequestBody p0){ return null; } + public Request.Builder removeHeader(String p0){ return null; } + public Request.Builder tag(Object p0){ return null; } + public Request.Builder url(HttpUrl p0){ return null; } + public Request.Builder url(String p0){ return null; } + public Request.Builder url(URL p0){ return null; } + public final Headers.Builder getHeaders$okhttp(){ return null; } + public final HttpUrl getUrl$okhttp(){ return null; } + public final Map, Object> getTags$okhttp(){ return null; } + public final Request.Builder delete(){ return null; } + public final RequestBody getBody$okhttp(){ return null; } + public final String getMethod$okhttp(){ return null; } + public final void setBody$okhttp(RequestBody p0){} + public final void setHeaders$okhttp(Headers.Builder p0){} + public final void setMethod$okhttp(String p0){} + public final void setTags$okhttp(Map, Object> p0){} + public final void setUrl$okhttp(HttpUrl p0){} } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Response.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Response.java index a13ed203c53..56a8c3d085a 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Response.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Response.java @@ -13,258 +13,81 @@ import okhttp3.Request; import okhttp3.ResponseBody; import okhttp3.internal.connection.Exchange; -public class Response implements Closeable { +public class Response implements Closeable +{ protected Response() {} - - public Response(Request p0, Protocol p1, String p2, int p3, Handshake p4, Headers p5, - ResponseBody p6, Response p7, Response p8, Response p9, long p10, long p11, - Exchange p12) {} - - public String toString() { - return null; - } - - public final CacheControl cacheControl() { - return null; - } - - public final Exchange exchange() { - return null; - } - - public final Handshake handshake() { - return null; - } - - public final Headers headers() { - return null; - } - - public final Headers trailers() { - return null; - } - - public final List challenges() { - return null; - } - - public final List headers(String p0) { - return null; - } - - public final Protocol protocol() { - return null; - } - - public final Request request() { - return null; - } - - public final Response cacheResponse() { - return null; - } - - public final Response networkResponse() { - return null; - } - - public final Response priorResponse() { - return null; - } - - public final Response.Builder newBuilder() { - return null; - } - - public final ResponseBody body() { - return null; - } - - public final ResponseBody peekBody(long p0) { - return null; - } - - public final String header(String p0) { - return null; - } - - public final String header(String p0, String p1) { - return null; - } - - public final String message() { - return null; - } - - public final boolean isRedirect() { - return false; - } - - public final boolean isSuccessful() { - return false; - } - - public final int code() { - return 0; - } - - public final long receivedResponseAtMillis() { - return 0; - } - - public final long sentRequestAtMillis() { - return 0; - } - - public void close() {} - - static public class Builder { - public Builder() {} - - public Builder(Response p0) {} - - public Response build() { - return null; - } - - public Response.Builder addHeader(String p0, String p1) { - return null; - } - - public Response.Builder body(ResponseBody p0) { - return null; - } - - public Response.Builder cacheResponse(Response p0) { - return null; - } - - public Response.Builder code(int p0) { - return null; - } - - public Response.Builder handshake(Handshake p0) { - return null; - } - - public Response.Builder header(String p0, String p1) { - return null; - } - - public Response.Builder headers(Headers p0) { - return null; - } - - public Response.Builder message(String p0) { - return null; - } - - public Response.Builder networkResponse(Response p0) { - return null; - } - - public Response.Builder priorResponse(Response p0) { - return null; - } - - public Response.Builder protocol(Protocol p0) { - return null; - } - - public Response.Builder receivedResponseAtMillis(long p0) { - return null; - } - - public Response.Builder removeHeader(String p0) { - return null; - } - - public Response.Builder request(Request p0) { - return null; - } - - public Response.Builder sentRequestAtMillis(long p0) { - return null; - } - - public final Exchange getExchange$okhttp() { - return null; - } - - public final Handshake getHandshake$okhttp() { - return null; - } - - public final Headers.Builder getHeaders$okhttp() { - return null; - } - - public final Protocol getProtocol$okhttp() { - return null; - } - - public final Request getRequest$okhttp() { - return null; - } - - public final Response getCacheResponse$okhttp() { - return null; - } - - public final Response getNetworkResponse$okhttp() { - return null; - } - - public final Response getPriorResponse$okhttp() { - return null; - } - - public final ResponseBody getBody$okhttp() { - return null; - } - - public final String getMessage$okhttp() { - return null; - } - - public final int getCode$okhttp() { - return 0; - } - - public final long getReceivedResponseAtMillis$okhttp() { - return 0; - } - - public final long getSentRequestAtMillis$okhttp() { - return 0; - } - - public final void initExchange$okhttp(Exchange p0) {} - - public final void setBody$okhttp(ResponseBody p0) {} - - public final void setCacheResponse$okhttp(Response p0) {} - - public final void setCode$okhttp(int p0) {} - - public final void setExchange$okhttp(Exchange p0) {} - - public final void setHandshake$okhttp(Handshake p0) {} - - public final void setHeaders$okhttp(Headers.Builder p0) {} - - public final void setMessage$okhttp(String p0) {} - - public final void setNetworkResponse$okhttp(Response p0) {} - - public final void setPriorResponse$okhttp(Response p0) {} - - public final void setProtocol$okhttp(Protocol p0) {} - - public final void setReceivedResponseAtMillis$okhttp(long p0) {} - - public final void setRequest$okhttp(Request p0) {} - - public final void setSentRequestAtMillis$okhttp(long p0) {} + public Response(Request p0, Protocol p1, String p2, int p3, Handshake p4, Headers p5, ResponseBody p6, Response p7, Response p8, Response p9, long p10, long p11, Exchange p12){} + public String toString(){ return null; } + public final CacheControl cacheControl(){ return null; } + public final Exchange exchange(){ return null; } + public final Handshake handshake(){ return null; } + public final Headers headers(){ return null; } + public final Headers trailers(){ return null; } + public final List challenges(){ return null; } + public final List headers(String p0){ return null; } + public final Protocol protocol(){ return null; } + public final Request request(){ return null; } + public final Response cacheResponse(){ return null; } + public final Response networkResponse(){ return null; } + public final Response priorResponse(){ return null; } + public final Response.Builder newBuilder(){ return null; } + public final ResponseBody body(){ return null; } + public final ResponseBody peekBody(long p0){ return null; } + public final String header(String p0){ return null; } + public final String header(String p0, String p1){ return null; } + public final String message(){ return null; } + public final boolean isRedirect(){ return false; } + public final boolean isSuccessful(){ return false; } + public final int code(){ return 0; } + public final long receivedResponseAtMillis(){ return 0; } + public final long sentRequestAtMillis(){ return 0; } + public void close(){} + static public class Builder + { + public Builder(){} + public Builder(Response p0){} + public Response build(){ return null; } + public Response.Builder addHeader(String p0, String p1){ return null; } + public Response.Builder body(ResponseBody p0){ return null; } + public Response.Builder cacheResponse(Response p0){ return null; } + public Response.Builder code(int p0){ return null; } + public Response.Builder handshake(Handshake p0){ return null; } + public Response.Builder header(String p0, String p1){ return null; } + public Response.Builder headers(Headers p0){ return null; } + public Response.Builder message(String p0){ return null; } + public Response.Builder networkResponse(Response p0){ return null; } + public Response.Builder priorResponse(Response p0){ return null; } + public Response.Builder protocol(Protocol p0){ return null; } + public Response.Builder receivedResponseAtMillis(long p0){ return null; } + public Response.Builder removeHeader(String p0){ return null; } + public Response.Builder request(Request p0){ return null; } + public Response.Builder sentRequestAtMillis(long p0){ return null; } + public final Exchange getExchange$okhttp(){ return null; } + public final Handshake getHandshake$okhttp(){ return null; } + public final Headers.Builder getHeaders$okhttp(){ return null; } + public final Protocol getProtocol$okhttp(){ return null; } + public final Request getRequest$okhttp(){ return null; } + public final Response getCacheResponse$okhttp(){ return null; } + public final Response getNetworkResponse$okhttp(){ return null; } + public final Response getPriorResponse$okhttp(){ return null; } + public final ResponseBody getBody$okhttp(){ return null; } + public final String getMessage$okhttp(){ return null; } + public final int getCode$okhttp(){ return 0; } + public final long getReceivedResponseAtMillis$okhttp(){ return 0; } + public final long getSentRequestAtMillis$okhttp(){ return 0; } + public final void initExchange$okhttp(Exchange p0){} + public final void setBody$okhttp(ResponseBody p0){} + public final void setCacheResponse$okhttp(Response p0){} + public final void setCode$okhttp(int p0){} + public final void setExchange$okhttp(Exchange p0){} + public final void setHandshake$okhttp(Handshake p0){} + public final void setHeaders$okhttp(Headers.Builder p0){} + public final void setMessage$okhttp(String p0){} + public final void setNetworkResponse$okhttp(Response p0){} + public final void setPriorResponse$okhttp(Response p0){} + public final void setProtocol$okhttp(Protocol p0){} + public final void setReceivedResponseAtMillis$okhttp(long p0){} + public final void setRequest$okhttp(Request p0){} + public final void setSentRequestAtMillis$okhttp(long p0){} } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Route.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Route.java index bff177b55a0..c0d18dadece 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Route.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/Route.java @@ -6,36 +6,15 @@ import java.net.InetSocketAddress; import java.net.Proxy; import okhttp3.Address; -public class Route { +public class Route +{ protected Route() {} - - public Route(Address p0, Proxy p1, InetSocketAddress p2) {} - - public String toString() { - return null; - } - - public boolean equals(Object p0) { - return false; - } - - public final Address address() { - return null; - } - - public final InetSocketAddress socketAddress() { - return null; - } - - public final Proxy proxy() { - return null; - } - - public final boolean requiresTunnel() { - return false; - } - - public int hashCode() { - return 0; - } + public Route(Address p0, Proxy p1, InetSocketAddress p2){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final Address address(){ return null; } + public final InetSocketAddress socketAddress(){ return null; } + public final Proxy proxy(){ return null; } + public final boolean requiresTunnel(){ return false; } + public int hashCode(){ return 0; } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/TlsVersion.java b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/TlsVersion.java index fdcfdc9ab6d..33514eff350 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okhttp3/TlsVersion.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okhttp3/TlsVersion.java @@ -3,26 +3,16 @@ package okhttp3; -public enum TlsVersion { +public enum TlsVersion +{ SSL_3_0, TLS_1_0, TLS_1_1, TLS_1_2, TLS_1_3; - private TlsVersion() {} - - public final String javaName() { - return null; - } - - public static TlsVersion forJavaName(String p0) { - return null; - } - + public final String javaName(){ return null; } + public static TlsVersion forJavaName(String p0){ return null; } public static TlsVersion.Companion Companion = null; - - static public class Companion { + static public class Companion + { protected Companion() {} - - public final TlsVersion forJavaName(String p0) { - return null; - } + public final TlsVersion forJavaName(String p0){ return null; } } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okio/Buffer.java b/java/ql/test/stubs/okhttp-4.9.3/okio/Buffer.java index 3a270f5e9eb..1a9a2d0f66f 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okio/Buffer.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okio/Buffer.java @@ -17,453 +17,131 @@ import okio.Sink; import okio.Source; import okio.Timeout; -public class Buffer implements BufferedSink, BufferedSource, ByteChannel, Cloneable { - public Buffer buffer() { - return null; - } - - public Buffer clone() { - return null; - } - - public Buffer emit() { - return null; - } - - public Buffer emitCompleteSegments() { - return null; - } - - public Buffer getBuffer() { - return null; - } - - public Buffer write(ByteString p0) { - return null; - } - - public Buffer write(ByteString p0, int p1, int p2) { - return null; - } - - public Buffer write(Source p0, long p1) { - return null; - } - - public Buffer write(byte[] p0) { - return null; - } - - public Buffer write(byte[] p0, int p1, int p2) { - return null; - } - - public Buffer writeByte(int p0) { - return null; - } - - public Buffer writeDecimalLong(long p0) { - return null; - } - - public Buffer writeHexadecimalUnsignedLong(long p0) { - return null; - } - - public Buffer writeInt(int p0) { - return null; - } - - public Buffer writeIntLe(int p0) { - return null; - } - - public Buffer writeLong(long p0) { - return null; - } - - public Buffer writeLongLe(long p0) { - return null; - } - - public Buffer writeShort(int p0) { - return null; - } - - public Buffer writeShortLe(int p0) { - return null; - } - - public Buffer writeString(String p0, Charset p1) { - return null; - } - - public Buffer writeString(String p0, int p1, int p2, Charset p3) { - return null; - } - - public Buffer writeUtf8(String p0) { - return null; - } - - public Buffer writeUtf8(String p0, int p1, int p2) { - return null; - } - - public Buffer writeUtf8CodePoint(int p0) { - return null; - } - - public Buffer() {} - - public BufferedSource peek() { - return null; - } - - public ByteString readByteString() { - return null; - } - - public ByteString readByteString(long p0) { - return null; - } - - public InputStream inputStream() { - return null; - } - - public OutputStream outputStream() { - return null; - } - +public class Buffer implements BufferedSink, BufferedSource, ByteChannel, Cloneable +{ + public Buffer buffer(){ return null; } + public Buffer clone(){ return null; } + public Buffer emit(){ return null; } + public Buffer emitCompleteSegments(){ return null; } + public Buffer getBuffer(){ return null; } + public Buffer write(ByteString p0){ return null; } + public Buffer write(ByteString p0, int p1, int p2){ return null; } + public Buffer write(Source p0, long p1){ return null; } + public Buffer write(byte[] p0){ return null; } + public Buffer write(byte[] p0, int p1, int p2){ return null; } + public Buffer writeByte(int p0){ return null; } + public Buffer writeDecimalLong(long p0){ return null; } + public Buffer writeHexadecimalUnsignedLong(long p0){ return null; } + public Buffer writeInt(int p0){ return null; } + public Buffer writeIntLe(int p0){ return null; } + public Buffer writeLong(long p0){ return null; } + public Buffer writeLongLe(long p0){ return null; } + public Buffer writeShort(int p0){ return null; } + public Buffer writeShortLe(int p0){ return null; } + public Buffer writeString(String p0, Charset p1){ return null; } + public Buffer writeString(String p0, int p1, int p2, Charset p3){ return null; } + public Buffer writeUtf8(String p0){ return null; } + public Buffer writeUtf8(String p0, int p1, int p2){ return null; } + public Buffer writeUtf8CodePoint(int p0){ return null; } + public Buffer(){} + public BufferedSource peek(){ return null; } + public ByteString readByteString(){ return null; } + public ByteString readByteString(long p0){ return null; } + public InputStream inputStream(){ return null; } + public OutputStream outputStream(){ return null; } public Segment head = null; - - public String readString(Charset p0) { - return null; - } - - public String readString(long p0, Charset p1) { - return null; - } - - public String readUtf8() { - return null; - } - - public String readUtf8(long p0) { - return null; - } - - public String readUtf8Line() { - return null; - } - - public String readUtf8LineStrict() { - return null; - } - - public String readUtf8LineStrict(long p0) { - return null; - } - - public String toString() { - return null; - } - - public Timeout timeout() { - return null; - } - - public boolean equals(Object p0) { - return false; - } - - public boolean exhausted() { - return false; - } - - public boolean isOpen() { - return false; - } - - public boolean rangeEquals(long p0, ByteString p1) { - return false; - } - - public boolean rangeEquals(long p0, ByteString p1, int p2, int p3) { - return false; - } - - public boolean request(long p0) { - return false; - } - - public byte readByte() { - return 0; - } - - public byte[] readByteArray() { - return null; - } - - public byte[] readByteArray(long p0) { - return null; - } - - public final Buffer copy() { - return null; - } - - public final Buffer copyTo(Buffer p0, long p1) { - return null; - } - - public final Buffer copyTo(Buffer p0, long p1, long p2) { - return null; - } - - public final Buffer copyTo(OutputStream p0) { - return null; - } - - public final Buffer copyTo(OutputStream p0, long p1) { - return null; - } - - public final Buffer copyTo(OutputStream p0, long p1, long p2) { - return null; - } - - public final Buffer readFrom(InputStream p0) { - return null; - } - - public final Buffer readFrom(InputStream p0, long p1) { - return null; - } - - public final Buffer writeTo(OutputStream p0) { - return null; - } - - public final Buffer writeTo(OutputStream p0, long p1) { - return null; - } - - public final Buffer.UnsafeCursor readAndWriteUnsafe() { - return null; - } - - public final Buffer.UnsafeCursor readAndWriteUnsafe(Buffer.UnsafeCursor p0) { - return null; - } - - public final Buffer.UnsafeCursor readUnsafe() { - return null; - } - - public final Buffer.UnsafeCursor readUnsafe(Buffer.UnsafeCursor p0) { - return null; - } - - public final ByteString hmacSha1(ByteString p0) { - return null; - } - - public final ByteString hmacSha256(ByteString p0) { - return null; - } - - public final ByteString hmacSha512(ByteString p0) { - return null; - } - - public final ByteString md5() { - return null; - } - - public final ByteString sha1() { - return null; - } - - public final ByteString sha256() { - return null; - } - - public final ByteString sha512() { - return null; - } - - public final ByteString snapshot() { - return null; - } - - public final ByteString snapshot(int p0) { - return null; - } - - public final Segment writableSegment$okio(int p0) { - return null; - } - - public final byte getByte(long p0) { - return 0; - } - - public final long completeSegmentByteCount() { - return 0; - } - - public final long size() { - return 0; - } - - public final void clear() {} - - public final void setSize$okio(long p0) {} - - public int hashCode() { - return 0; - } - - public int read(ByteBuffer p0) { - return 0; - } - - public int read(byte[] p0) { - return 0; - } - - public int read(byte[] p0, int p1, int p2) { - return 0; - } - - public int readInt() { - return 0; - } - - public int readIntLe() { - return 0; - } - - public int readUtf8CodePoint() { - return 0; - } - - public int select(Options p0) { - return 0; - } - - public int write(ByteBuffer p0) { - return 0; - } - - public long indexOf(ByteString p0) { - return 0; - } - - public long indexOf(ByteString p0, long p1) { - return 0; - } - - public long indexOf(byte p0) { - return 0; - } - - public long indexOf(byte p0, long p1) { - return 0; - } - - public long indexOf(byte p0, long p1, long p2) { - return 0; - } - - public long indexOfElement(ByteString p0) { - return 0; - } - - public long indexOfElement(ByteString p0, long p1) { - return 0; - } - - public long read(Buffer p0, long p1) { - return 0; - } - - public long readAll(Sink p0) { - return 0; - } - - public long readDecimalLong() { - return 0; - } - - public long readHexadecimalUnsignedLong() { - return 0; - } - - public long readLong() { - return 0; - } - - public long readLongLe() { - return 0; - } - - public long writeAll(Source p0) { - return 0; - } - - public short readShort() { - return 0; - } - - public short readShortLe() { - return 0; - } - - public void close() {} - - public void flush() {} - - public void readFully(Buffer p0, long p1) {} - - public void readFully(byte[] p0) {} - - public void require(long p0) {} - - public void skip(long p0) {} - - public void write(Buffer p0, long p1) {} - - static public class UnsafeCursor implements Closeable { + public String readString(Charset p0){ return null; } + public String readString(long p0, Charset p1){ return null; } + public String readUtf8(){ return null; } + public String readUtf8(long p0){ return null; } + public String readUtf8Line(){ return null; } + public String readUtf8LineStrict(){ return null; } + public String readUtf8LineStrict(long p0){ return null; } + public String toString(){ return null; } + public Timeout timeout(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean exhausted(){ return false; } + public boolean isOpen(){ return false; } + public boolean rangeEquals(long p0, ByteString p1){ return false; } + public boolean rangeEquals(long p0, ByteString p1, int p2, int p3){ return false; } + public boolean request(long p0){ return false; } + public byte readByte(){ return 0; } + public byte[] readByteArray(){ return null; } + public byte[] readByteArray(long p0){ return null; } + public final Buffer copy(){ return null; } + public final Buffer copyTo(Buffer p0, long p1){ return null; } + public final Buffer copyTo(Buffer p0, long p1, long p2){ return null; } + public final Buffer copyTo(OutputStream p0){ return null; } + public final Buffer copyTo(OutputStream p0, long p1){ return null; } + public final Buffer copyTo(OutputStream p0, long p1, long p2){ return null; } + public final Buffer readFrom(InputStream p0){ return null; } + public final Buffer readFrom(InputStream p0, long p1){ return null; } + public final Buffer writeTo(OutputStream p0){ return null; } + public final Buffer writeTo(OutputStream p0, long p1){ return null; } + public final Buffer.UnsafeCursor readAndWriteUnsafe(){ return null; } + public final Buffer.UnsafeCursor readAndWriteUnsafe(Buffer.UnsafeCursor p0){ return null; } + public final Buffer.UnsafeCursor readUnsafe(){ return null; } + public final Buffer.UnsafeCursor readUnsafe(Buffer.UnsafeCursor p0){ return null; } + public final ByteString hmacSha1(ByteString p0){ return null; } + public final ByteString hmacSha256(ByteString p0){ return null; } + public final ByteString hmacSha512(ByteString p0){ return null; } + public final ByteString md5(){ return null; } + public final ByteString sha1(){ return null; } + public final ByteString sha256(){ return null; } + public final ByteString sha512(){ return null; } + public final ByteString snapshot(){ return null; } + public final ByteString snapshot(int p0){ return null; } + public final Segment writableSegment$okio(int p0){ return null; } + public final byte getByte(long p0){ return 0; } + public final long completeSegmentByteCount(){ return 0; } + public final long size(){ return 0; } + public final void clear(){} + public final void setSize$okio(long p0){} + public int hashCode(){ return 0; } + public int read(ByteBuffer p0){ return 0; } + public int read(byte[] p0){ return 0; } + public int read(byte[] p0, int p1, int p2){ return 0; } + public int readInt(){ return 0; } + public int readIntLe(){ return 0; } + public int readUtf8CodePoint(){ return 0; } + public int select(Options p0){ return 0; } + public int write(ByteBuffer p0){ return 0; } + public long indexOf(ByteString p0){ return 0; } + public long indexOf(ByteString p0, long p1){ return 0; } + public long indexOf(byte p0){ return 0; } + public long indexOf(byte p0, long p1){ return 0; } + public long indexOf(byte p0, long p1, long p2){ return 0; } + public long indexOfElement(ByteString p0){ return 0; } + public long indexOfElement(ByteString p0, long p1){ return 0; } + public long read(Buffer p0, long p1){ return 0; } + public long readAll(Sink p0){ return 0; } + public long readDecimalLong(){ return 0; } + public long readHexadecimalUnsignedLong(){ return 0; } + public long readLong(){ return 0; } + public long readLongLe(){ return 0; } + public long writeAll(Source p0){ return 0; } + public short readShort(){ return 0; } + public short readShortLe(){ return 0; } + public void close(){} + public void flush(){} + public void readFully(Buffer p0, long p1){} + public void readFully(byte[] p0){} + public void require(long p0){} + public void skip(long p0){} + public void write(Buffer p0, long p1){} + static public class UnsafeCursor implements Closeable + { public Buffer buffer = null; - - public UnsafeCursor() {} - + public UnsafeCursor(){} public boolean readWrite = false; public byte[] data = null; - - public final int next() { - return 0; - } - - public final int seek(long p0) { - return 0; - } - - public final long expandBuffer(int p0) { - return 0; - } - - public final long resizeBuffer(long p0) { - return 0; - } - + public final int next(){ return 0; } + public final int seek(long p0){ return 0; } + public final long expandBuffer(int p0){ return 0; } + public final long resizeBuffer(long p0){ return 0; } public int end = 0; public int start = 0; public long offset = 0; - - public void close() {} + public void close(){} } } diff --git a/java/ql/test/stubs/okhttp-4.9.3/okio/ByteString.java b/java/ql/test/stubs/okhttp-4.9.3/okio/ByteString.java index 2ac5fe9901a..8378e6a047d 100644 --- a/java/ql/test/stubs/okhttp-4.9.3/okio/ByteString.java +++ b/java/ql/test/stubs/okhttp-4.9.3/okio/ByteString.java @@ -9,276 +9,81 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; import okio.Buffer; -public class ByteString implements Comparable, Serializable { +public class ByteString implements Comparable, Serializable +{ protected ByteString() {} - - public ByteBuffer asByteBuffer() { - return null; - } - - public ByteString digest$okio(String p0) { - return null; - } - - public ByteString hmac$okio(String p0, ByteString p1) { - return null; - } - - public ByteString hmacSha1(ByteString p0) { - return null; - } - - public ByteString hmacSha256(ByteString p0) { - return null; - } - - public ByteString hmacSha512(ByteString p0) { - return null; - } - - public ByteString md5() { - return null; - } - - public ByteString sha1() { - return null; - } - - public ByteString sha256() { - return null; - } - - public ByteString sha512() { - return null; - } - - public ByteString substring(int p0, int p1) { - return null; - } - - public ByteString toAsciiLowercase() { - return null; - } - - public ByteString toAsciiUppercase() { - return null; - } - - public ByteString(byte[] p0) {} - - public String base64() { - return null; - } - - public String base64Url() { - return null; - } - - public String hex() { - return null; - } - - public String string(Charset p0) { - return null; - } - - public String toString() { - return null; - } - - public String utf8() { - return null; - } - - public boolean equals(Object p0) { - return false; - } - - public boolean rangeEquals(int p0, ByteString p1, int p2, int p3) { - return false; - } - - public boolean rangeEquals(int p0, byte[] p1, int p2, int p3) { - return false; - } - - public byte internalGet$okio(int p0) { - return 0; - } - - public byte[] internalArray$okio() { - return null; - } - - public byte[] toByteArray() { - return null; - } - - public final ByteString substring() { - return null; - } - - public final ByteString substring(int p0) { - return null; - } - - public final String getUtf8$okio() { - return null; - } - - public final boolean endsWith(ByteString p0) { - return false; - } - - public final boolean endsWith(byte[] p0) { - return false; - } - - public final boolean startsWith(ByteString p0) { - return false; - } - - public final boolean startsWith(byte[] p0) { - return false; - } - - public final byte getByte(int p0) { - return 0; - } - - public final byte[] getData$okio() { - return null; - } - - public final int getHashCode$okio() { - return 0; - } - - public final int indexOf(ByteString p0) { - return 0; - } - - public final int indexOf(ByteString p0, int p1) { - return 0; - } - - public final int indexOf(byte[] p0) { - return 0; - } - - public final int lastIndexOf(ByteString p0) { - return 0; - } - - public final int lastIndexOf(ByteString p0, int p1) { - return 0; - } - - public final int lastIndexOf(byte[] p0) { - return 0; - } - - public final int size() { - return 0; - } - - public final void setHashCode$okio(int p0) {} - - public final void setUtf8$okio(String p0) {} - - public int compareTo(ByteString p0) { - return 0; - } - - public int getSize$okio() { - return 0; - } - - public int hashCode() { - return 0; - } - - public int indexOf(byte[] p0, int p1) { - return 0; - } - - public int lastIndexOf(byte[] p0, int p1) { - return 0; - } - + public ByteBuffer asByteBuffer(){ return null; } + public ByteString digest$okio(String p0){ return null; } + public ByteString hmac$okio(String p0, ByteString p1){ return null; } + public ByteString hmacSha1(ByteString p0){ return null; } + public ByteString hmacSha256(ByteString p0){ return null; } + public ByteString hmacSha512(ByteString p0){ return null; } + public ByteString md5(){ return null; } + public ByteString sha1(){ return null; } + public ByteString sha256(){ return null; } + public ByteString sha512(){ return null; } + public ByteString substring(int p0, int p1){ return null; } + public ByteString toAsciiLowercase(){ return null; } + public ByteString toAsciiUppercase(){ return null; } + public ByteString(byte[] p0){} + public String base64(){ return null; } + public String base64Url(){ return null; } + public String hex(){ return null; } + public String string(Charset p0){ return null; } + public String toString(){ return null; } + public String utf8(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean rangeEquals(int p0, ByteString p1, int p2, int p3){ return false; } + public boolean rangeEquals(int p0, byte[] p1, int p2, int p3){ return false; } + public byte internalGet$okio(int p0){ return 0; } + public byte[] internalArray$okio(){ return null; } + public byte[] toByteArray(){ return null; } + public final ByteString substring(){ return null; } + public final ByteString substring(int p0){ return null; } + public final String getUtf8$okio(){ return null; } + public final boolean endsWith(ByteString p0){ return false; } + public final boolean endsWith(byte[] p0){ return false; } + public final boolean startsWith(ByteString p0){ return false; } + public final boolean startsWith(byte[] p0){ return false; } + public final byte getByte(int p0){ return 0; } + public final byte[] getData$okio(){ return null; } + public final int getHashCode$okio(){ return 0; } + public final int indexOf(ByteString p0){ return 0; } + public final int indexOf(ByteString p0, int p1){ return 0; } + public final int indexOf(byte[] p0){ return 0; } + public final int lastIndexOf(ByteString p0){ return 0; } + public final int lastIndexOf(ByteString p0, int p1){ return 0; } + public final int lastIndexOf(byte[] p0){ return 0; } + public final int size(){ return 0; } + public final void setHashCode$okio(int p0){} + public final void setUtf8$okio(String p0){} + public int compareTo(ByteString p0){ return 0; } + public int getSize$okio(){ return 0; } + public int hashCode(){ return 0; } + public int indexOf(byte[] p0, int p1){ return 0; } + public int lastIndexOf(byte[] p0, int p1){ return 0; } public static ByteString EMPTY = null; - - public static ByteString decodeBase64(String p0) { - return null; - } - - public static ByteString decodeHex(String p0) { - return null; - } - - public static ByteString encodeString(String p0, Charset p1) { - return null; - } - - public static ByteString encodeUtf8(String p0) { - return null; - } - - public static ByteString of(ByteBuffer p0) { - return null; - } - - public static ByteString of(byte... p0) { - return null; - } - - public static ByteString of(byte[] p0, int p1, int p2) { - return null; - } - - public static ByteString read(InputStream p0, int p1) { - return null; - } - + public static ByteString decodeBase64(String p0){ return null; } + public static ByteString decodeHex(String p0){ return null; } + public static ByteString encodeString(String p0, Charset p1){ return null; } + public static ByteString encodeUtf8(String p0){ return null; } + public static ByteString of(ByteBuffer p0){ return null; } + public static ByteString of(byte... p0){ return null; } + public static ByteString of(byte[] p0, int p1, int p2){ return null; } + public static ByteString read(InputStream p0, int p1){ return null; } public static ByteString.Companion Companion = null; - - public void write$okio(Buffer p0, int p1, int p2) {} - - public void write(OutputStream p0) {} - - static public class Companion { + public void write$okio(Buffer p0, int p1, int p2){} + public void write(OutputStream p0){} + static public class Companion + { protected Companion() {} - - public final ByteString decodeBase64(String p0) { - return null; - } - - public final ByteString decodeHex(String p0) { - return null; - } - - public final ByteString encodeString(String p0, Charset p1) { - return null; - } - - public final ByteString encodeUtf8(String p0) { - return null; - } - - public final ByteString of(ByteBuffer p0) { - return null; - } - - public final ByteString of(byte... p0) { - return null; - } - - public final ByteString of(byte[] p0, int p1, int p2) { - return null; - } - - public final ByteString read(InputStream p0, int p1) { - return null; - } + public final ByteString decodeBase64(String p0){ return null; } + public final ByteString decodeHex(String p0){ return null; } + public final ByteString encodeString(String p0, Charset p1){ return null; } + public final ByteString encodeUtf8(String p0){ return null; } + public final ByteString of(ByteBuffer p0){ return null; } + public final ByteString of(byte... p0){ return null; } + public final ByteString of(byte[] p0, int p1, int p2){ return null; } + public final ByteString read(InputStream p0, int p1){ return null; } } } From c8aca0619012f6c9483d3fe8f12095a34dbb701c Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 23 Nov 2022 10:30:24 +0000 Subject: [PATCH 28/93] Implement pinning through a TrustManager + Fix that the query was accidentally placed in experimental --- .../AndroidCertificatePinningQuery.qll | 64 ++++++++++++++++++- .../AndroidMissingCertificatePinning.ql | 0 2 files changed, 62 insertions(+), 2 deletions(-) rename java/ql/src/{experimental => }/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql (100%) diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index 80549967090..9d8a7bc29b2 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -52,6 +52,66 @@ predicate trustedDomain(string domainName) { trustedDomainViaOkHttp(domainName) } +/** + * Holds if `setSocketFactory` is a call to `HttpsURLConnection.setSSLSocketFactory` or `HttpsURLConnection.setDefaultSSLSocketFactory` + * that uses a socket factory derrived from a `TrustManager`. + * `default` is true if the default SSL socket factory for all URLs is being set. + */ +private predicate trustedSocketFactory(MethodAccess setSocketFactory, boolean default) { + exists(MethodAccess getSocketFactory, MethodAccess initSslContext, string methodName | + setSocketFactory + .getMethod() + .getASourceOverriddenMethod*() + .hasQualifiedName("javax.net.ssl", "HttpsURLConnection", methodName) and + ( + default = true and methodName = "setDefaultSSLSocketFactory" + or + default = false and methodName = "setSSLSocketFactory" + ) and + initSslContext.getMethod().hasQualifiedName("javax.net.ssl", "SSLContext", "init") and + getSocketFactory + .getMethod() + .getASourceOverriddenMethod*() + .hasQualifiedName("javax.net.ssl", "SSLContext", "getSocketFactory") and + not initSslContext.getArgument(1) instanceof NullLiteral and + DataFlow::localExprFlow(initSslContext.getQualifier(), getSocketFactory.getQualifier()) and + DataFlow::localExprFlow(getSocketFactory, setSocketFactory.getArgument(0)) + ) +} + +/** + * Holds if the given expression is an qualifier to a `URL.openConnection` or `URL.openStream` call + * that is trusted due to its SSL socket factory being set. + */ +private predicate trustedUrlConnection(Expr url) { + exists(MethodAccess openCon | + openCon + .getMethod() + .getASourceOverriddenMethod*() + .hasQualifiedName("java.net", "URL", "openConnection") and + url = openCon.getQualifier() and + exists(MethodAccess setSocketFactory | + trustedSocketFactory(setSocketFactory, false) and + TaintTracking::localExprTaint(openCon, setSocketFactory.getQualifier()) + ) + ) + or + trustedSocketFactory(_, true) and + exists(MethodAccess open | + open.getMethod() + .getASourceOverriddenMethod*() + .hasQualifiedName("java.net", "URL", ["openConnection", "openStream"]) and + url = open.getQualifier() + ) +} + +private class MissingPinningSink extends DataFlow::Node { + MissingPinningSink() { + this instanceof UrlOpenSink and + not trustedUrlConnection(this.asExpr()) + } +} + /** Configuration for finding uses of non trusted URLs. */ private class UntrustedUrlConfig extends TaintTracking::Configuration { UntrustedUrlConfig() { this = "UntrustedUrlConfig" } @@ -64,13 +124,13 @@ private class UntrustedUrlConfig extends TaintTracking::Configuration { ) } - override predicate isSink(DataFlow::Node node) { node instanceof UrlOpenSink } + override predicate isSink(DataFlow::Node node) { node instanceof MissingPinningSink } } /** Holds if `node` is a network communication call for which certificate pinning is not implemented. */ predicate missingPinning(DataFlow::Node node) { isAndroid() and - node instanceof UrlOpenSink and + node instanceof MissingPinningSink and ( not exists(string s | trustedDomain(s)) or diff --git a/java/ql/src/experimental/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql rename to java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql From 0d6a376a36c75b66941a5fc89293572a8b5fec04 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 25 Nov 2022 16:37:41 +0000 Subject: [PATCH 29/93] Add test cases for TrustManager case --- .../Test4/AndroidManifest.xml | 10 ++++++ .../Test4/R.java | 7 ++++ .../Test4/Test.java | 32 +++++++++++++++++ .../Test4/options | 1 + .../Test4/res/xml/NetworkSecurityConfig.xml | 4 +++ .../Test4/test.expected | 0 .../Test4/test.ql | 23 ++++++++++++ .../Test5/AndroidManifest.xml | 10 ++++++ .../Test5/R.java | 7 ++++ .../Test5/Test.java | 35 +++++++++++++++++++ .../Test5/options | 1 + .../Test5/res/xml/NetworkSecurityConfig.xml | 4 +++ .../Test5/test.expected | 0 .../Test5/test.ql | 23 ++++++++++++ 14 files changed, 157 insertions(+) create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/R.java create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/Test.java create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/options create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/res/xml/NetworkSecurityConfig.xml create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.expected create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/R.java create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/Test.java create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/options create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/res/xml/NetworkSecurityConfig.xml create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.expected create mode 100644 java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/AndroidManifest.xml new file mode 100644 index 00000000000..da5cdabce67 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/R.java b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/R.java new file mode 100644 index 00000000000..16f953ea106 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/R.java @@ -0,0 +1,7 @@ +package com.example; + +class R { + static final class raw { + static final int cert = 0; + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/Test.java b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/Test.java new file mode 100644 index 00000000000..fd745a0ca1c --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/Test.java @@ -0,0 +1,32 @@ +package com.example; + +import java.net.URL; +import java.net.URLConnection; +import java.security.KeyStore; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import android.content.res.Resources; + +class Test{ + void test1(Resources resources) throws Exception { + KeyStore keyStore = KeyStore.getInstance("BKS"); + keyStore.load(resources.openRawResource(R.raw.cert), null); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keyStore); + + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, tmf.getTrustManagers(), null); + + URL url = new URL("http://www.example.com/"); + HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); + + urlConnection.setSSLSocketFactory(sslContext.getSocketFactory()); + } + + void test2() throws Exception { + URL url = new URL("http://www.example.com/"); + HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); // $hasNoTrustedResult + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/options b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/options new file mode 100644 index 00000000000..7d1644b057b --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/options @@ -0,0 +1 @@ +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/google-android-9.0.0 \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/res/xml/NetworkSecurityConfig.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/res/xml/NetworkSecurityConfig.xml new file mode 100644 index 00000000000..3fd128a05a2 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/res/xml/NetworkSecurityConfig.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql new file mode 100644 index 00000000000..22238774af5 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql @@ -0,0 +1,23 @@ +import java +import TestUtilities.InlineExpectationsTest +import semmle.code.java.security.AndroidCertificatePinningQuery + +class Test extends InlineExpectationsTest { + Test() { this = "AndroidMissingCertificatePinningTest" } + + override string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } + + override predicate hasActualResult(Location loc, string el, string tag, string value) { + exists(DataFlow::Node node | + missingPinning(node) and + loc = node.getLocation() and + el = node.toString() and + value = "" and + ( + if exists(string x | trustedDomain(x)) + then tag = "hasUntrustedResult" + else tag = "hasNoTrustedResult" + ) + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/AndroidManifest.xml new file mode 100644 index 00000000000..da5cdabce67 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/R.java b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/R.java new file mode 100644 index 00000000000..16f953ea106 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/R.java @@ -0,0 +1,7 @@ +package com.example; + +class R { + static final class raw { + static final int cert = 0; + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/Test.java b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/Test.java new file mode 100644 index 00000000000..00aa99775c1 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/Test.java @@ -0,0 +1,35 @@ +package com.example; + +import java.net.URL; +import java.net.URLConnection; +import java.io.InputStream; +import java.security.KeyStore; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import android.content.res.Resources; + +class Test{ + void init(Resources resources) throws Exception { + KeyStore keyStore = KeyStore.getInstance("BKS"); + keyStore.load(resources.openRawResource(R.raw.cert), null); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keyStore); + + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, tmf.getTrustManagers(), null); + + HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); + } + + URLConnection test1() throws Exception { + URL url = new URL("http://www.example.com/"); + return url.openConnection(); + } + + InputStream test2() throws Exception { + URL url = new URL("http://www.example.com/"); + return url.openStream(); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/options b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/options new file mode 100644 index 00000000000..7d1644b057b --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/options @@ -0,0 +1 @@ +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/google-android-9.0.0 \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/res/xml/NetworkSecurityConfig.xml b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/res/xml/NetworkSecurityConfig.xml new file mode 100644 index 00000000000..3fd128a05a2 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/res/xml/NetworkSecurityConfig.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql new file mode 100644 index 00000000000..22238774af5 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql @@ -0,0 +1,23 @@ +import java +import TestUtilities.InlineExpectationsTest +import semmle.code.java.security.AndroidCertificatePinningQuery + +class Test extends InlineExpectationsTest { + Test() { this = "AndroidMissingCertificatePinningTest" } + + override string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } + + override predicate hasActualResult(Location loc, string el, string tag, string value) { + exists(DataFlow::Node node | + missingPinning(node) and + loc = node.getLocation() and + el = node.toString() and + value = "" and + ( + if exists(string x | trustedDomain(x)) + then tag = "hasUntrustedResult" + else tag = "hasNoTrustedResult" + ) + ) + } +} From 749ecab6b1035b5d1f25f1bb34ac690f2e6d61b1 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 25 Nov 2022 16:42:59 +0000 Subject: [PATCH 30/93] Add security severity --- .../src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql index 60328fac38e..ac36cad88e3 100644 --- a/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql +++ b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql @@ -3,6 +3,7 @@ * @description Network communication should use certificate pinning. * @kind problem * @problem.severity warning + * @security-severity 7.5 * @precision medium * @id java/android/missing-certificate-pinning * @tags security From ceb253e6d1055fce124afa781c6d0bb34c0c9187 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 30 Nov 2022 11:29:45 +0000 Subject: [PATCH 31/93] Add qhelp --- .../AndroidMissingCertificatePinning.qhelp | 46 +++++++++++++++++++ .../AndroidMissingCertificatePinning1.java | 2 + .../AndroidMissingCertificatePinning2.xml | 21 +++++++++ .../AndroidMissingCertificatePinning3.java | 26 +++++++++++ 4 files changed, 95 insertions(+) create mode 100644 java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.qhelp create mode 100644 java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning1.java create mode 100644 java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning2.xml create mode 100644 java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning3.java diff --git a/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.qhelp b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.qhelp new file mode 100644 index 00000000000..dbadf7a6fb7 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.qhelp @@ -0,0 +1,46 @@ + + + +Certificate pinning is the practice of only trusting a specific set of SSL certificates, rather than those that the device trusts by default. +In Android applications, it is reccomended to use certificate pinning when communicating over the network, +in order to minimize the risk of machine-in-the-middle attacks from a comprimised CA. + + + +

    +The easiest way to implement certificate pinning is to declare your pins in a network-security-config XML file. +This will automatically provide certificate pinning for any network connection made by the app. +

    +

    +Another way to implement certificate pinning is to use the `CertificatePinner` from the `okhttp` library. +

    +

    +A final way to implement certificate pinning is to use a TrustManager, initialized from a KeyStore loaded with only the neccesary certificates. +

    + +
    + + +

    +In the first (bad) case below, a network call is performed with no certificate pinning implemented. +The other (good) cases demonstrate the different ways to implement certificate pinning. +

    + + + +
    + + +
  • + OWASP Mobile Security: Testing Custom Certificate Stores and Certificate Pinning (MSTG-NETWORK-4) +
  • +
  • + Android Developers: Network security configuration +
  • +
  • + OkHttp: CertificatePinner +
  • +
    +
    diff --git a/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning1.java b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning1.java new file mode 100644 index 00000000000..78d80ea882f --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning1.java @@ -0,0 +1,2 @@ +// BAD - By default, this network cal does not use certificate pinning +URLConnection conn = new URL("https://example.com").openonnection(); \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning2.xml b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning2.xml new file mode 100644 index 00000000000..dd656b97ba2 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning2.xml @@ -0,0 +1,21 @@ + + + + + + + ... + + + + + + + + good.example.com + + ... + + + \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning3.java b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning3.java new file mode 100644 index 00000000000..08327d7636e --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning3.java @@ -0,0 +1,26 @@ +// GOOD: Certificate pinning implemented via okhttp3.CertificatePinner +CertificatePinner certificatePinner = new CertificatePinner.Builder() + .add("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") + .build(); +OkHttpClient client = new OkHttpClient.Builder() + .certificatePinner(certificatePinner) + .build(); + +client.newCall(new Request.Builder().url("https://example.com").build()).execute(); + + + +// GOOD: Certificate pinning implemented vis a TrustManager +KeyStore keyStore = KeyStore.getInstance("BKS"); +keyStore.load(resources.openRawResource(R.raw.cert), null); + +TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); +tmf.init(keyStore); + +SSLContext sslContext = SSLContext.getInstance("TLS"); +sslContext.init(null, tmf.getTrustManagers(), null); + +URL url = new URL("http://www.example.com/"); +HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); + +urlConnection.setSSLSocketFactory(sslContext.getSocketFactory()); \ No newline at end of file From 603c1c1693c9d637c224707e7f6ed1aa90e1384c Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 30 Nov 2022 11:37:08 +0000 Subject: [PATCH 32/93] Add the domain used to the alert message --- .../security/AndroidCertificatePinningQuery.qll | 15 ++++++++++++--- .../CWE-295/AndroidMissingCertificatePinning.ql | 10 +++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index 9d8a7bc29b2..7c1a034363b 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -128,12 +128,21 @@ private class UntrustedUrlConfig extends TaintTracking::Configuration { } /** Holds if `node` is a network communication call for which certificate pinning is not implemented. */ -predicate missingPinning(DataFlow::Node node) { +predicate missingPinning(DataFlow::Node node, string domain) { isAndroid() and node instanceof MissingPinningSink and ( - not exists(string s | trustedDomain(s)) + not exists(string s | trustedDomain(s)) and + domain = "" or - exists(UntrustedUrlConfig conf | conf.hasFlow(_, node)) + exists(UntrustedUrlConfig conf, DataFlow::Node src | + conf.hasFlow(src, node) and + domain = getDomain(src.asExpr()) + ) ) } + +/** Gets the domain name from the given string literal */ +private string getDomain(CompileTimeConstantExpr expr) { + result = expr.getStringValue().regexpCapture("(https?://)?([^/]*)/?", 2) +} diff --git a/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql index ac36cad88e3..829dec1de3b 100644 --- a/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql +++ b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.ql @@ -13,10 +13,10 @@ import java import semmle.code.java.security.AndroidCertificatePinningQuery -from DataFlow::Node node, string msg +from DataFlow::Node node, string domain, string msg where - missingPinning(node) and - if exists(string x | trustedDomain(x)) - then msg = "(untrusted domain)" - else msg = "(no trusted domains)" + missingPinning(node, domain) and + if domain = "" + then msg = "(no explicitly trusted domains)" + else msg = "(" + domain + " is not trusted by a pin)" select node, "This network call does not implement certificate pinning. " + msg From fae404300802a235c235295b7fa17168bed89aa5 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 30 Nov 2022 11:40:57 +0000 Subject: [PATCH 33/93] Add change note --- .../change-notes/2022-11-31-android-certificate-pinning.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/src/change-notes/2022-11-31-android-certificate-pinning.md diff --git a/java/ql/src/change-notes/2022-11-31-android-certificate-pinning.md b/java/ql/src/change-notes/2022-11-31-android-certificate-pinning.md new file mode 100644 index 00000000000..3ec8f19aa18 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-31-android-certificate-pinning.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `java/android/missing-certificate-pinning`, to find network calls where certificate pinning is not implemented. \ No newline at end of file From a14ebb7c039cfeda6d63fd1942ef9b446d910eca Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 30 Nov 2022 11:42:19 +0000 Subject: [PATCH 34/93] Fixes --- .../code/java/security/AndroidCertificatePinningQuery.qll | 2 +- .../Security/CWE/CWE-295/AndroidMissingCertificatePinning.qhelp | 2 ++ ...ate-pinning.md => 2022-11-30-android-certificate-pinning.md} | 0 .../CWE-295/AndroidMissingCertificatePinning/Test1/test.ql | 2 +- .../CWE-295/AndroidMissingCertificatePinning/Test2/test.ql | 2 +- .../CWE-295/AndroidMissingCertificatePinning/Test3/test.ql | 2 +- .../CWE-295/AndroidMissingCertificatePinning/Test4/test.ql | 2 +- .../CWE-295/AndroidMissingCertificatePinning/Test5/test.ql | 2 +- 8 files changed, 8 insertions(+), 6 deletions(-) rename java/ql/src/change-notes/{2022-11-31-android-certificate-pinning.md => 2022-11-30-android-certificate-pinning.md} (100%) diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index 7c1a034363b..c8cf09bd0e9 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -144,5 +144,5 @@ predicate missingPinning(DataFlow::Node node, string domain) { /** Gets the domain name from the given string literal */ private string getDomain(CompileTimeConstantExpr expr) { - result = expr.getStringValue().regexpCapture("(https?://)?([^/]*)/?", 2) + result = expr.getStringValue().regexpCapture("(https?://)?([^/]*)(/.*)?", 2) } diff --git a/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.qhelp b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.qhelp index dbadf7a6fb7..db97c98250e 100644 --- a/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.qhelp +++ b/java/ql/src/Security/CWE/CWE-295/AndroidMissingCertificatePinning.qhelp @@ -3,9 +3,11 @@ "qhelp.dtd"> +

    Certificate pinning is the practice of only trusting a specific set of SSL certificates, rather than those that the device trusts by default. In Android applications, it is reccomended to use certificate pinning when communicating over the network, in order to minimize the risk of machine-in-the-middle attacks from a comprimised CA. +

    diff --git a/java/ql/src/change-notes/2022-11-31-android-certificate-pinning.md b/java/ql/src/change-notes/2022-11-30-android-certificate-pinning.md similarity index 100% rename from java/ql/src/change-notes/2022-11-31-android-certificate-pinning.md rename to java/ql/src/change-notes/2022-11-30-android-certificate-pinning.md diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.ql index 22238774af5..6dc626a59e0 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.ql +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.ql @@ -9,7 +9,7 @@ class Test extends InlineExpectationsTest { override predicate hasActualResult(Location loc, string el, string tag, string value) { exists(DataFlow::Node node | - missingPinning(node) and + missingPinning(node, _) and loc = node.getLocation() and el = node.toString() and value = "" and diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.ql index 22238774af5..6dc626a59e0 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.ql +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.ql @@ -9,7 +9,7 @@ class Test extends InlineExpectationsTest { override predicate hasActualResult(Location loc, string el, string tag, string value) { exists(DataFlow::Node node | - missingPinning(node) and + missingPinning(node, _) and loc = node.getLocation() and el = node.toString() and value = "" and diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.ql index 22238774af5..6dc626a59e0 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.ql +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.ql @@ -9,7 +9,7 @@ class Test extends InlineExpectationsTest { override predicate hasActualResult(Location loc, string el, string tag, string value) { exists(DataFlow::Node node | - missingPinning(node) and + missingPinning(node, _) and loc = node.getLocation() and el = node.toString() and value = "" and diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql index 22238774af5..6dc626a59e0 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql @@ -9,7 +9,7 @@ class Test extends InlineExpectationsTest { override predicate hasActualResult(Location loc, string el, string tag, string value) { exists(DataFlow::Node node | - missingPinning(node) and + missingPinning(node, _) and loc = node.getLocation() and el = node.toString() and value = "" and diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql index 22238774af5..6dc626a59e0 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql @@ -9,7 +9,7 @@ class Test extends InlineExpectationsTest { override predicate hasActualResult(Location loc, string el, string tag, string value) { exists(DataFlow::Node node | - missingPinning(node) and + missingPinning(node, _) and loc = node.getLocation() and el = node.toString() and value = "" and From 2be68b2f1d90cff45f70bb86024812c3480eca98 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 8 Dec 2022 15:12:14 +0000 Subject: [PATCH 35/93] Apply suggestions from code review Co-authored-by: Tony Torralba --- .../AndroidCertificatePinningQuery.qll | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index c8cf09bd0e9..53f8ef805ca 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -3,6 +3,8 @@ import java import semmle.code.xml.AndroidManifest import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.frameworks.Networking +import semmle.code.java.security.Encryption import HttpsUrls /** An Android Network Security Configuration XML file. */ @@ -58,21 +60,17 @@ predicate trustedDomain(string domainName) { * `default` is true if the default SSL socket factory for all URLs is being set. */ private predicate trustedSocketFactory(MethodAccess setSocketFactory, boolean default) { - exists(MethodAccess getSocketFactory, MethodAccess initSslContext, string methodName | - setSocketFactory - .getMethod() - .getASourceOverriddenMethod*() - .hasQualifiedName("javax.net.ssl", "HttpsURLConnection", methodName) and - ( - default = true and methodName = "setDefaultSSLSocketFactory" + exists(MethodAccess getSocketFactory, MethodAccess initSslContext | + exists(Method m | setSocketFactory.getMethod().getASourceOverriddenMethod*() = m | + default = true and + m.getDeclaringType() instanceof HttpsUrlConnection and + m.hasName("setDefaultSSLSocketFactory") or - default = false and methodName = "setSSLSocketFactory" + default = false and m instanceof SetConnectionFactoryMethod ) and - initSslContext.getMethod().hasQualifiedName("javax.net.ssl", "SSLContext", "init") and - getSocketFactory - .getMethod() - .getASourceOverriddenMethod*() - .hasQualifiedName("javax.net.ssl", "SSLContext", "getSocketFactory") and + initSslContext.getMethod().getDeclaringType() instanceof SslContext and + initSslContext.getMethod().hasName("init") and + getSocketFactory.getMethod().getASourceOverriddenMethod*() instanceof GetSocketFactory and not initSslContext.getArgument(1) instanceof NullLiteral and DataFlow::localExprFlow(initSslContext.getQualifier(), getSocketFactory.getQualifier()) and DataFlow::localExprFlow(getSocketFactory, setSocketFactory.getArgument(0)) @@ -85,10 +83,7 @@ private predicate trustedSocketFactory(MethodAccess setSocketFactory, boolean de */ private predicate trustedUrlConnection(Expr url) { exists(MethodAccess openCon | - openCon - .getMethod() - .getASourceOverriddenMethod*() - .hasQualifiedName("java.net", "URL", "openConnection") and + openCon.getMethod().getASourceOverriddenMethod*() instanceof UrlOpenConnectionMethod and url = openCon.getQualifier() and exists(MethodAccess setSocketFactory | trustedSocketFactory(setSocketFactory, false) and @@ -97,10 +92,10 @@ private predicate trustedUrlConnection(Expr url) { ) or trustedSocketFactory(_, true) and - exists(MethodAccess open | - open.getMethod() - .getASourceOverriddenMethod*() - .hasQualifiedName("java.net", "URL", ["openConnection", "openStream"]) and + exists(MethodAccess open, Method m | + m instanceof UrlOpenConnectionMethod or m instanceof UrlOpenStreamMethod + | + open.getMethod().getASourceOverriddenMethod*() = m and url = open.getQualifier() ) } From 0dea5daffe98c2ebdd6e2d92e4ff7f0a846fa773 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 8 Dec 2022 15:19:50 +0000 Subject: [PATCH 36/93] Change import for consistency, fix some typos --- .../code/java/security/AndroidCertificatePinningQuery.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index 53f8ef805ca..fc57af95b98 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -5,7 +5,7 @@ import semmle.code.xml.AndroidManifest import semmle.code.java.dataflow.TaintTracking import semmle.code.java.frameworks.Networking import semmle.code.java.security.Encryption -import HttpsUrls +import semmle.code.java.security.HttpsUrls /** An Android Network Security Configuration XML file. */ class AndroidNetworkSecurityConfigFile extends XmlFile { @@ -47,7 +47,7 @@ private predicate trustedDomainViaOkHttp(string domainName) { ) } -/** Holds if the given domain name is trusted by some certifiacte pinning implementation. */ +/** Holds if the given domain name is trusted by some certificate pinning implementation. */ predicate trustedDomain(string domainName) { trustedDomainViaXml(domainName) or @@ -56,11 +56,11 @@ predicate trustedDomain(string domainName) { /** * Holds if `setSocketFactory` is a call to `HttpsURLConnection.setSSLSocketFactory` or `HttpsURLConnection.setDefaultSSLSocketFactory` - * that uses a socket factory derrived from a `TrustManager`. + * that uses a socket factory derived from a `TrustManager`. * `default` is true if the default SSL socket factory for all URLs is being set. */ private predicate trustedSocketFactory(MethodAccess setSocketFactory, boolean default) { - exists(MethodAccess getSocketFactory, MethodAccess initSslContext | + exists(MethodAccess getSocketFactory, MethodAccess initSslContext | exists(Method m | setSocketFactory.getMethod().getASourceOverriddenMethod*() = m | default = true and m.getDeclaringType() instanceof HttpsUrlConnection and From 8de5efb28fde92f24a757e7efc741f92c28ec20b Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 8 Dec 2022 15:24:32 +0000 Subject: [PATCH 37/93] Add SetDefaultConnectionFactoryMethod class --- .../code/java/security/AndroidCertificatePinningQuery.qll | 6 ++---- java/ql/lib/semmle/code/java/security/Encryption.qll | 7 +++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index fc57af95b98..19ab883efa2 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -61,10 +61,8 @@ predicate trustedDomain(string domainName) { */ private predicate trustedSocketFactory(MethodAccess setSocketFactory, boolean default) { exists(MethodAccess getSocketFactory, MethodAccess initSslContext | - exists(Method m | setSocketFactory.getMethod().getASourceOverriddenMethod*() = m | - default = true and - m.getDeclaringType() instanceof HttpsUrlConnection and - m.hasName("setDefaultSSLSocketFactory") + exists(Method m | setSocketFactory.getMethod() = m | + default = true and m instanceof SetDefaultConnectionFactoryMethod or default = false and m instanceof SetConnectionFactoryMethod ) and diff --git a/java/ql/lib/semmle/code/java/security/Encryption.qll b/java/ql/lib/semmle/code/java/security/Encryption.qll index 042018d3e34..fa1428e12cc 100644 --- a/java/ql/lib/semmle/code/java/security/Encryption.qll +++ b/java/ql/lib/semmle/code/java/security/Encryption.qll @@ -150,6 +150,13 @@ class SetConnectionFactoryMethod extends Method { } } +class SetDefaultConnectionFactoryMethod extends Method { + SetDefaultConnectionFactoryMethod() { + this.hasName("setDefaultSSLSocketFactory") and + this.getDeclaringType().getAnAncestor() instanceof HttpsUrlConnection + } +} + class SetHostnameVerifierMethod extends Method { SetHostnameVerifierMethod() { this.hasName("setHostnameVerifier") and From 12dc11aa1889176811441657ac01e891887de1db Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 9 Dec 2022 15:07:49 +0000 Subject: [PATCH 38/93] Add qldoc --- java/ql/lib/semmle/code/java/security/Encryption.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/ql/lib/semmle/code/java/security/Encryption.qll b/java/ql/lib/semmle/code/java/security/Encryption.qll index fa1428e12cc..a8c8f077884 100644 --- a/java/ql/lib/semmle/code/java/security/Encryption.qll +++ b/java/ql/lib/semmle/code/java/security/Encryption.qll @@ -143,6 +143,7 @@ class CreateSslEngineMethod extends Method { } } +/** The `setConnectionFactory` method of the class `javax.net.ssl.HttpsURLConnection`. */ class SetConnectionFactoryMethod extends Method { SetConnectionFactoryMethod() { this.hasName("setSSLSocketFactory") and @@ -150,6 +151,7 @@ class SetConnectionFactoryMethod extends Method { } } +/** The `setDefaultConnectionFactory` method of the class `javax.net.ssl.HttpsURLConnection`. */ class SetDefaultConnectionFactoryMethod extends Method { SetDefaultConnectionFactoryMethod() { this.hasName("setDefaultSSLSocketFactory") and From af08fe8659f651d7e0f8f0cd78b40cc30bc34f33 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Sat, 10 Dec 2022 15:32:22 +0000 Subject: [PATCH 39/93] Add change note re: Kotlin version limit --- java/ql/src/change-notes/2022-12-10-kotlin-max-version.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/src/change-notes/2022-12-10-kotlin-max-version.md diff --git a/java/ql/src/change-notes/2022-12-10-kotlin-max-version.md b/java/ql/src/change-notes/2022-12-10-kotlin-max-version.md new file mode 100644 index 00000000000..9c87671dd97 --- /dev/null +++ b/java/ql/src/change-notes/2022-12-10-kotlin-max-version.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Kotlin extraction will now fail if the Kotlin version in use is at least 1.7.30. This is to ensure using an as-yet-unsupported version is noticable, rather than silently failing to extract Kotlin code and therefore producing false-negative results. From 0b2fb4f70a221434560fedc5f519381b9ab7817e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 10 Dec 2022 15:49:35 +0000 Subject: [PATCH 40/93] Release preparation for version 2.11.6 --- cpp/ql/lib/CHANGELOG.md | 4 ++++ cpp/ql/lib/change-notes/released/0.4.6.md | 3 +++ cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 4 ++++ cpp/ql/src/change-notes/released/0.4.6.md | 3 +++ cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ++++ .../Solorigate/lib/change-notes/released/1.3.6.md | 3 +++ csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ++++ .../Solorigate/src/change-notes/released/1.3.6.md | 3 +++ csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 4 ++++ csharp/ql/lib/change-notes/released/0.4.6.md | 3 +++ csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 4 ++++ csharp/ql/src/change-notes/released/0.4.6.md | 3 +++ csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 4 ++++ go/ql/lib/change-notes/released/0.3.6.md | 3 +++ go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 4 ++++ go/ql/src/change-notes/released/0.3.6.md | 3 +++ go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 4 ++++ java/ql/lib/change-notes/released/0.4.6.md | 3 +++ java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 6 ++++++ .../0.4.6.md} | 7 ++++--- java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 4 ++++ javascript/ql/lib/change-notes/released/0.3.6.md | 3 +++ javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 4 ++++ javascript/ql/src/change-notes/released/0.4.6.md | 3 +++ javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ++++ misc/suite-helpers/change-notes/released/0.3.6.md | 3 +++ misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 4 ++++ python/ql/lib/change-notes/released/0.6.6.md | 3 +++ python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 4 ++++ python/ql/src/change-notes/released/0.5.6.md | 3 +++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 4 ++++ ruby/ql/lib/change-notes/released/0.4.6.md | 3 +++ ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 4 ++++ ruby/ql/src/change-notes/released/0.4.6.md | 3 +++ ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/regex/CHANGELOG.md | 4 ++++ shared/regex/change-notes/released/0.0.3.md | 3 +++ shared/regex/codeql-pack.release.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ++++ shared/ssa/change-notes/released/0.0.7.md | 3 +++ shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ++++ shared/typos/change-notes/released/0.0.7.md | 3 +++ shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- 80 files changed, 183 insertions(+), 43 deletions(-) create mode 100644 cpp/ql/lib/change-notes/released/0.4.6.md create mode 100644 cpp/ql/src/change-notes/released/0.4.6.md create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.6.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.6.md create mode 100644 csharp/ql/lib/change-notes/released/0.4.6.md create mode 100644 csharp/ql/src/change-notes/released/0.4.6.md create mode 100644 go/ql/lib/change-notes/released/0.3.6.md create mode 100644 go/ql/src/change-notes/released/0.3.6.md create mode 100644 java/ql/lib/change-notes/released/0.4.6.md rename java/ql/src/change-notes/{2022-12-10-kotlin-max-version.md => released/0.4.6.md} (85%) create mode 100644 javascript/ql/lib/change-notes/released/0.3.6.md create mode 100644 javascript/ql/src/change-notes/released/0.4.6.md create mode 100644 misc/suite-helpers/change-notes/released/0.3.6.md create mode 100644 python/ql/lib/change-notes/released/0.6.6.md create mode 100644 python/ql/src/change-notes/released/0.5.6.md create mode 100644 ruby/ql/lib/change-notes/released/0.4.6.md create mode 100644 ruby/ql/src/change-notes/released/0.4.6.md create mode 100644 shared/regex/change-notes/released/0.0.3.md create mode 100644 shared/ssa/change-notes/released/0.0.7.md create mode 100644 shared/typos/change-notes/released/0.0.7.md diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 132d1bf3537..6fa6f76aabd 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.6 + +No user-facing changes. + ## 0.4.5 No user-facing changes. diff --git a/cpp/ql/lib/change-notes/released/0.4.6.md b/cpp/ql/lib/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 466cd01cf4e..2b842473675 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.5 +lastReleaseVersion: 0.4.6 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 585ab2170e5..80867fab833 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.4.6-dev +version: 0.4.6 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index c50e54bd80f..5cfd60bc84c 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.6 + +No user-facing changes. + ## 0.4.5 No user-facing changes. diff --git a/cpp/ql/src/change-notes/released/0.4.6.md b/cpp/ql/src/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 466cd01cf4e..2b842473675 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.5 +lastReleaseVersion: 0.4.6 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 75d3e65c592..4cc022a1590 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.4.6-dev +version: 0.4.6 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index d34f03b0e37..8d5d8f7df35 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.6 + +No user-facing changes. + ## 1.3.5 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.6.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.6.md new file mode 100644 index 00000000000..ce7baecf210 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.6.md @@ -0,0 +1,3 @@ +## 1.3.6 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index 1e1845ea66d..0a0b0986311 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.5 +lastReleaseVersion: 1.3.6 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index d10c89a3f5c..119ce73e54f 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.3.6-dev +version: 1.3.6 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index d34f03b0e37..8d5d8f7df35 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.6 + +No user-facing changes. + ## 1.3.5 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.6.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.6.md new file mode 100644 index 00000000000..ce7baecf210 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.6.md @@ -0,0 +1,3 @@ +## 1.3.6 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index 1e1845ea66d..0a0b0986311 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.5 +lastReleaseVersion: 1.3.6 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 98c95da4b03..cf800993043 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.3.6-dev +version: 1.3.6 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 438927d036b..0dbf4820b2a 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.6 + +No user-facing changes. + ## 0.4.5 No user-facing changes. diff --git a/csharp/ql/lib/change-notes/released/0.4.6.md b/csharp/ql/lib/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/csharp/ql/lib/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 466cd01cf4e..2b842473675 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.5 +lastReleaseVersion: 0.4.6 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 05eb16f3750..20d1d7d6b74 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.4.6-dev +version: 0.4.6 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 57d44189f70..8110355ef6a 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.6 + +No user-facing changes. + ## 0.4.5 No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/0.4.6.md b/csharp/ql/src/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 466cd01cf4e..2b842473675 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.5 +lastReleaseVersion: 0.4.6 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index f7da9740b21..35c8c90ebb4 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.4.6-dev +version: 0.4.6 groups: - csharp - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index a24d1c5919b..ba72eb8950a 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.6 + +No user-facing changes. + ## 0.3.5 No user-facing changes. diff --git a/go/ql/lib/change-notes/released/0.3.6.md b/go/ql/lib/change-notes/released/0.3.6.md new file mode 100644 index 00000000000..0c7a392e88f --- /dev/null +++ b/go/ql/lib/change-notes/released/0.3.6.md @@ -0,0 +1,3 @@ +## 0.3.6 + +No user-facing changes. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 468917f2543..7bbaa8987dd 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.5 +lastReleaseVersion: 0.3.6 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index b9088307812..6ec12d0956d 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.3.6-dev +version: 0.3.6 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 0ab2f98312a..aed077e28d9 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.6 + +No user-facing changes. + ## 0.3.5 No user-facing changes. diff --git a/go/ql/src/change-notes/released/0.3.6.md b/go/ql/src/change-notes/released/0.3.6.md new file mode 100644 index 00000000000..0c7a392e88f --- /dev/null +++ b/go/ql/src/change-notes/released/0.3.6.md @@ -0,0 +1,3 @@ +## 0.3.6 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 468917f2543..7bbaa8987dd 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.5 +lastReleaseVersion: 0.3.6 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 7d586cfb931..c8e34582560 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.3.6-dev +version: 0.3.6 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 56dfcebfb1f..21b8949ce62 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.6 + +No user-facing changes. + ## 0.4.5 No user-facing changes. diff --git a/java/ql/lib/change-notes/released/0.4.6.md b/java/ql/lib/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/java/ql/lib/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 466cd01cf4e..2b842473675 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.5 +lastReleaseVersion: 0.4.6 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index f4040ca5619..b4fa6097149 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.4.6-dev +version: 0.4.6 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 5de970b8981..7bab127cafc 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.4.6 + +### Minor Analysis Improvements + +* Kotlin extraction will now fail if the Kotlin version in use is at least 1.7.30. This is to ensure using an as-yet-unsupported version is noticable, rather than silently failing to extract Kotlin code and therefore producing false-negative results. + ## 0.4.5 No user-facing changes. diff --git a/java/ql/src/change-notes/2022-12-10-kotlin-max-version.md b/java/ql/src/change-notes/released/0.4.6.md similarity index 85% rename from java/ql/src/change-notes/2022-12-10-kotlin-max-version.md rename to java/ql/src/change-notes/released/0.4.6.md index 9c87671dd97..ae160f06a20 100644 --- a/java/ql/src/change-notes/2022-12-10-kotlin-max-version.md +++ b/java/ql/src/change-notes/released/0.4.6.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.4.6 + +### Minor Analysis Improvements + * Kotlin extraction will now fail if the Kotlin version in use is at least 1.7.30. This is to ensure using an as-yet-unsupported version is noticable, rather than silently failing to extract Kotlin code and therefore producing false-negative results. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 466cd01cf4e..2b842473675 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.5 +lastReleaseVersion: 0.4.6 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 00070f5ccf2..b8abfe36e16 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.4.6-dev +version: 0.4.6 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index 7c3e43e8a0a..b6dc74b4a65 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.6 + +No user-facing changes. + ## 0.3.5 No user-facing changes. diff --git a/javascript/ql/lib/change-notes/released/0.3.6.md b/javascript/ql/lib/change-notes/released/0.3.6.md new file mode 100644 index 00000000000..0c7a392e88f --- /dev/null +++ b/javascript/ql/lib/change-notes/released/0.3.6.md @@ -0,0 +1,3 @@ +## 0.3.6 + +No user-facing changes. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 468917f2543..7bbaa8987dd 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.5 +lastReleaseVersion: 0.3.6 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 0eb9a36345a..4bbe50ae2ea 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.3.6-dev +version: 0.3.6 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index e15a58fe74d..37e184e9490 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.6 + +No user-facing changes. + ## 0.4.5 No user-facing changes. diff --git a/javascript/ql/src/change-notes/released/0.4.6.md b/javascript/ql/src/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/javascript/ql/src/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 466cd01cf4e..2b842473675 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.5 +lastReleaseVersion: 0.4.6 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index b297ae8268d..85dbe345a4a 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.4.6-dev +version: 0.4.6 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index add84a5c77e..c7efd60a3c7 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.6 + +No user-facing changes. + ## 0.3.5 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/0.3.6.md b/misc/suite-helpers/change-notes/released/0.3.6.md new file mode 100644 index 00000000000..0c7a392e88f --- /dev/null +++ b/misc/suite-helpers/change-notes/released/0.3.6.md @@ -0,0 +1,3 @@ +## 0.3.6 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 468917f2543..7bbaa8987dd 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.5 +lastReleaseVersion: 0.3.6 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 5272d0402e2..ff25ba041c8 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.3.6-dev +version: 0.3.6 groups: shared diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 516f4e8307a..793438c4fb6 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.6 + +No user-facing changes. + ## 0.6.5 No user-facing changes. diff --git a/python/ql/lib/change-notes/released/0.6.6.md b/python/ql/lib/change-notes/released/0.6.6.md new file mode 100644 index 00000000000..ab10d897be1 --- /dev/null +++ b/python/ql/lib/change-notes/released/0.6.6.md @@ -0,0 +1,3 @@ +## 0.6.6 + +No user-facing changes. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 86780fb6148..f4cae0a77ad 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.5 +lastReleaseVersion: 0.6.6 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 237c3c5b0bb..3d999d1eeb6 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.6.6-dev +version: 0.6.6 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 1bd769949ae..e5d6103239d 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.6 + +No user-facing changes. + ## 0.5.5 No user-facing changes. diff --git a/python/ql/src/change-notes/released/0.5.6.md b/python/ql/src/change-notes/released/0.5.6.md new file mode 100644 index 00000000000..f717e01ed57 --- /dev/null +++ b/python/ql/src/change-notes/released/0.5.6.md @@ -0,0 +1,3 @@ +## 0.5.6 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index 03e491f0899..361de279943 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.5 +lastReleaseVersion: 0.5.6 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index f82723bb46a..9db8396f395 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.5.6-dev +version: 0.5.6 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 094859ea0dc..2e1a767da78 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.6 + +No user-facing changes. + ## 0.4.5 No user-facing changes. diff --git a/ruby/ql/lib/change-notes/released/0.4.6.md b/ruby/ql/lib/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/ruby/ql/lib/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 466cd01cf4e..2b842473675 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.5 +lastReleaseVersion: 0.4.6 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index ee703754c4e..64951c49556 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.4.6-dev +version: 0.4.6 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 4cedef4f572..30c0bdbce56 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.6 + +No user-facing changes. + ## 0.4.5 No user-facing changes. diff --git a/ruby/ql/src/change-notes/released/0.4.6.md b/ruby/ql/src/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/ruby/ql/src/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 466cd01cf4e..2b842473675 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.5 +lastReleaseVersion: 0.4.6 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index ce73dffcf88..df7aa757652 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.4.6-dev +version: 0.4.6 groups: - ruby - queries diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index 88dc3212e64..4babb26821b 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.3 + +No user-facing changes. + ## 0.0.2 No user-facing changes. diff --git a/shared/regex/change-notes/released/0.0.3.md b/shared/regex/change-notes/released/0.0.3.md new file mode 100644 index 00000000000..af7864fc7d5 --- /dev/null +++ b/shared/regex/change-notes/released/0.0.3.md @@ -0,0 +1,3 @@ +## 0.0.3 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index 55dc06fbd76..a24b693d1e7 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.2 +lastReleaseVersion: 0.0.3 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index cb2ff3557b8..a03b79a0778 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.0.3-dev +version: 0.0.3 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index e76e9fa4268..3c81fd2e095 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.7 + +No user-facing changes. + ## 0.0.6 No user-facing changes. diff --git a/shared/ssa/change-notes/released/0.0.7.md b/shared/ssa/change-notes/released/0.0.7.md new file mode 100644 index 00000000000..84da6f18c42 --- /dev/null +++ b/shared/ssa/change-notes/released/0.0.7.md @@ -0,0 +1,3 @@ +## 0.0.7 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index cf398ce02aa..a2a5484910b 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.6 +lastReleaseVersion: 0.0.7 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 0946f820a92..0d4719584ce 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/ssa -version: 0.0.7-dev +version: 0.0.7 groups: shared library: true diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 1d2195d28a7..f8ea7de20ff 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.7 + +No user-facing changes. + ## 0.0.6 No user-facing changes. diff --git a/shared/typos/change-notes/released/0.0.7.md b/shared/typos/change-notes/released/0.0.7.md new file mode 100644 index 00000000000..84da6f18c42 --- /dev/null +++ b/shared/typos/change-notes/released/0.0.7.md @@ -0,0 +1,3 @@ +## 0.0.7 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index cf398ce02aa..a2a5484910b 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.6 +lastReleaseVersion: 0.0.7 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 6bfd03987de..4ce79250a0d 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/typos -version: 0.0.7-dev +version: 0.0.7 groups: shared library: true From 343b7b1c8bea333c9f0ef24787c85e4777ce21a8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 11 Dec 2022 18:15:04 +0000 Subject: [PATCH 41/93] Post-release preparation for codeql-cli-2.11.6 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 80867fab833..b5c7ec3bd7a 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.4.6 +version: 0.4.7-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 4cc022a1590..603410f7946 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.4.6 +version: 0.4.7-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 119ce73e54f..e02e0a23130 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.3.6 +version: 1.3.7-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index cf800993043..06e38173f20 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.3.6 +version: 1.3.7-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 20d1d7d6b74..9ef9fd5b611 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.4.6 +version: 0.4.7-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 35c8c90ebb4..875aa77fff2 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.4.6 +version: 0.4.7-dev groups: - csharp - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 6ec12d0956d..0e39e54998a 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.3.6 +version: 0.3.7-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index c8e34582560..4427152eef6 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.3.6 +version: 0.3.7-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index b4fa6097149..8bd73a555c8 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.4.6 +version: 0.4.7-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index b8abfe36e16..032ff0b0d16 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.4.6 +version: 0.4.7-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 4bbe50ae2ea..a3afa629da8 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.3.6 +version: 0.3.7-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 85dbe345a4a..25854a00154 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.4.6 +version: 0.4.7-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index ff25ba041c8..68b88ed9a9e 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.3.6 +version: 0.3.7-dev groups: shared diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 3d999d1eeb6..b96adba40f0 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.6.6 +version: 0.6.7-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 9db8396f395..cb7193ce215 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.5.6 +version: 0.5.7-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 64951c49556..449b7e28aec 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.4.6 +version: 0.4.7-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index df7aa757652..4ab00a5bd38 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.4.6 +version: 0.4.7-dev groups: - ruby - queries diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index a03b79a0778..6ce99fb48b6 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.0.3 +version: 0.0.4-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 0d4719584ce..6abc7e0643b 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/ssa -version: 0.0.7 +version: 0.0.8-dev groups: shared library: true diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 4ce79250a0d..ac9084e7c06 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/typos -version: 0.0.7 +version: 0.0.8-dev groups: shared library: true From 7526c35c6091c417e9edbcfb975afb0b64b215c2 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 12 Dec 2022 16:23:26 +0100 Subject: [PATCH 42/93] speedup the "ATM - Check query suite" CI job --- .github/workflows/atm-check-query-suite.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/atm-check-query-suite.yml b/.github/workflows/atm-check-query-suite.yml index 7317746fe62..06e38bc7641 100644 --- a/.github/workflows/atm-check-query-suite.yml +++ b/.github/workflows/atm-check-query-suite.yml @@ -13,7 +13,7 @@ on: jobs: atm-check-query-suite: - runs-on: ubuntu-latest + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 @@ -23,6 +23,12 @@ jobs: with: channel: release + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: atm-suite + - name: Install ATM model run: | set -exu @@ -54,6 +60,7 @@ jobs: --output "${SARIF_PATH}" \ --sarif-group-rules-by-pack \ -vv \ + --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \ -- \ "${DB_PATH}" \ "${QUERY_PACK}/${QUERY_SUITE}" From f554e1fef16dd296252308ebca6c64288eca5d93 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 12 Dec 2022 16:27:32 +0100 Subject: [PATCH 43/93] more threads --- .github/workflows/atm-check-query-suite.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/atm-check-query-suite.yml b/.github/workflows/atm-check-query-suite.yml index 06e38bc7641..454093b9051 100644 --- a/.github/workflows/atm-check-query-suite.yml +++ b/.github/workflows/atm-check-query-suite.yml @@ -56,6 +56,7 @@ jobs: echo "SARIF_PATH=${SARIF_PATH}" >> "${GITHUB_ENV}" codeql database analyze \ + --threads=0 \ --format sarif-latest \ --output "${SARIF_PATH}" \ --sarif-group-rules-by-pack \ From a1564de126ca81f42f378a7c40d00703b7c3adf9 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 12 Dec 2022 16:35:01 +0100 Subject: [PATCH 44/93] more ram --- .github/workflows/atm-check-query-suite.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/atm-check-query-suite.yml b/.github/workflows/atm-check-query-suite.yml index 454093b9051..ed93a6f8f2f 100644 --- a/.github/workflows/atm-check-query-suite.yml +++ b/.github/workflows/atm-check-query-suite.yml @@ -57,6 +57,7 @@ jobs: codeql database analyze \ --threads=0 \ + --ram 50000 \ --format sarif-latest \ --output "${SARIF_PATH}" \ --sarif-group-rules-by-pack \ From dd86f7a69696c4df4b962ae03f2b23922aec29e9 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 12 Dec 2022 18:33:22 +0000 Subject: [PATCH 45/93] Kotlin: Revert type erasure within $default functions This imprecise implementation turned out to cause linkage errors, e.g. when type variables in the signatures of member methods were inappropriately erased. For the time being we accept that $default methods despite having erased signatures in keeping with their JVM representation can contain expressions whose types make reference to their surrounding function or class' type variables, even though they should be out of scope since $default methods are static and don't have type parameters, and need to cope with the inconsistency in QL. --- .../src/main/kotlin/KotlinFileExtractor.kt | 2 -- .../src/main/kotlin/KotlinUsesExtractor.kt | 32 +++++------------ .../parameter-defaults/PrintAst.expected | 4 +-- .../parameter-defaults/erasure.expected | 36 +++++++++++++++++++ .../parameter-defaults/erasure.ql | 2 ++ 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index faa83139bbb..cce26ed2380 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -1194,8 +1194,6 @@ open class KotlinFileExtractor( // n + o'th parameter, where `o` is the parameter offset caused by adding any dispatch receiver to the parameter list. // Note we don't need to add the extension receiver here because `useValueParameter` always assumes an extension receiver // will be prepended if one exists. - // Note we have to get the real function ID here before entering this block, because otherwise we'll misrepresent the signature of a generic - // function without its type variables -- for example, trying to address `f(T, List)` as `f(Object, List)`. val realFunctionId = useFunction(f) DeclarationStackAdjuster(f, OverriddenFunctionAttributes(id, id, locId, nonSyntheticParams, typeParameters = listOf(), isStatic = true)).use { val realParamsVarId = getValueParameterLabel(id, parameterTypes.size - 2) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index cc335d3f8cb..fe55fdba256 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -643,26 +643,6 @@ open class KotlinUsesExtractor( RETURN, GENERIC_ARGUMENT, OTHER } - private fun isOnDeclarationStackWithoutTypeParameters(f: IrFunction) = - this is KotlinFileExtractor && this.declarationStack.findOverriddenAttributes(f)?.typeParameters?.isEmpty() == true - - private fun isStaticFunctionOnStackBeforeClass(c: IrClass) = - this is KotlinFileExtractor && (this.declarationStack.findFirst { it.first == c || it.second?.isStatic == true })?.second?.isStatic == true - - private fun isUnavailableTypeParameter(t: IrType) = - t is IrSimpleType && t.classifier.owner.let { owner -> - owner is IrTypeParameter && owner.parent.let { parent -> - when (parent) { - is IrFunction -> isOnDeclarationStackWithoutTypeParameters(parent) - is IrClass -> isStaticFunctionOnStackBeforeClass(parent) - else -> false - } - } - } - - private fun argIsUnavailableTypeParameter(t: IrTypeArgument) = - t is IrTypeProjection && isUnavailableTypeParameter(t.type) - private fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults { if (s.abbreviation != null) { // TODO: Extract this information @@ -735,13 +715,11 @@ open class KotlinUsesExtractor( } owner is IrClass -> { - val args = if (s.isRawType() || s.arguments.any { argIsUnavailableTypeParameter(it) }) null else s.arguments + val args = if (s.isRawType()) null else s.arguments return useSimpleTypeClass(owner, args, s.isNullable()) } owner is IrTypeParameter -> { - if (isUnavailableTypeParameter(s)) - return useType(erase(s), context) val javaResult = useTypeParameter(owner) val aClassId = makeClass("kotlin", "TypeParam") // TODO: Wrong val kotlinResult = if (true) TypeResult(fakeKotlinType(), "TODO", "TODO") else @@ -1474,7 +1452,13 @@ open class KotlinUsesExtractor( param.parent.let { (it as? IrFunction)?.let { fn -> if (this is KotlinFileExtractor) - this.declarationStack.findOverriddenAttributes(fn)?.id + this.declarationStack.findOverriddenAttributes(fn)?.takeUnless { + // When extracting the `static fun f$default(...)` that accompanies `fun f(val x: T? = defaultExpr, ...)`, + // `f$default` has no type parameters, and so there is no `f$default::T` to refer to. + // We have no good way to extract references to `T` in `defaultExpr`, so we just fall back on describing it + // in terms of `f::T`, even though that type variable ought to be out of scope here. + attribs -> attribs.typeParameters?.isEmpty() == true + }?.id else null } ?: diff --git a/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected b/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected index 13bd441dfcd..dcce5baa1da 100644 --- a/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected @@ -1337,7 +1337,7 @@ test.kt: # 145| 0: [AssignExpr] ...=... # 145| 0: [VarAccess] p4 # 145| 1: [MethodAccess] listOf(...) -# 145| -2: [TypeAccess] Object +# 145| -2: [TypeAccess] T # 145| -1: [TypeAccess] CollectionsKt # 145| 0: [VarAccess] p2 # 145| 3: [IfStmt] if (...) @@ -1360,7 +1360,7 @@ test.kt: # 145| 0: [AssignExpr] ...=... # 145| 0: [VarAccess] p6 # 145| 1: [MethodAccess] listOf(...) -# 145| -2: [TypeAccess] Object +# 145| -2: [TypeAccess] S # 145| -1: [TypeAccess] CollectionsKt # 145| 0: [VarAccess] p1 # 145| 5: [ReturnStmt] return ... diff --git a/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.expected b/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.expected index e69de29bb2d..e6ed6dd1432 100644 --- a/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.expected +++ b/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.expected @@ -0,0 +1,36 @@ +| test.kt:124:3:126:3 | ...=... | test.kt:122:19:122:19 | T | +| test.kt:124:3:126:3 | ...=... | test.kt:122:19:122:19 | T | +| test.kt:124:3:126:3 | p1 | test.kt:122:19:122:19 | T | +| test.kt:124:3:126:3 | p2 | test.kt:122:19:122:19 | T | +| test.kt:124:3:126:3 | p2 | test.kt:122:19:122:19 | T | +| test.kt:124:3:126:3 | p3 | test.kt:122:19:122:19 | T | +| test.kt:124:3:126:3 | p3 | test.kt:122:19:122:19 | T | +| test.kt:124:22:124:22 | p1 | test.kt:122:19:122:19 | T | +| test.kt:135:3:135:43 | ...=... | test.kt:122:19:122:19 | T | +| test.kt:135:3:135:43 | p1 | test.kt:122:19:122:19 | T | +| test.kt:135:3:135:43 | p2 | test.kt:122:19:122:19 | T | +| test.kt:135:3:135:43 | p2 | test.kt:122:19:122:19 | T | +| test.kt:135:3:135:43 | testReturn(...) | test.kt:122:19:122:19 | T | +| test.kt:145:3:147:3 | ...=... | file:///modules/java.base/java/util/List.class:0:0:0:0 | List | +| test.kt:145:3:147:3 | ...=... | file:///modules/java.base/java/util/List.class:0:0:0:0 | List | +| test.kt:145:3:147:3 | ...=... | test.kt:143:27:143:27 | T | +| test.kt:145:3:147:3 | ...=... | test.kt:143:27:143:27 | T | +| test.kt:145:3:147:3 | ...=... | test.kt:145:8:145:12 | S | +| test.kt:145:3:147:3 | p1 | test.kt:145:8:145:12 | S | +| test.kt:145:3:147:3 | p2 | test.kt:143:27:143:27 | T | +| test.kt:145:3:147:3 | p2 | test.kt:143:27:143:27 | T | +| test.kt:145:3:147:3 | p3 | test.kt:143:27:143:27 | T | +| test.kt:145:3:147:3 | p3 | test.kt:143:27:143:27 | T | +| test.kt:145:3:147:3 | p4 | file:///modules/java.base/java/util/List.class:0:0:0:0 | List | +| test.kt:145:3:147:3 | p4 | file:///modules/java.base/java/util/List.class:0:0:0:0 | List | +| test.kt:145:3:147:3 | p5 | test.kt:145:8:145:12 | S | +| test.kt:145:3:147:3 | p5 | test.kt:145:8:145:12 | S | +| test.kt:145:3:147:3 | p6 | file:///modules/java.base/java/util/List.class:0:0:0:0 | List | +| test.kt:145:3:147:3 | p6 | file:///modules/java.base/java/util/List.class:0:0:0:0 | List | +| test.kt:145:30:145:30 | p1 | test.kt:145:8:145:12 | S | +| test.kt:145:66:145:74 | T | test.kt:143:27:143:27 | T | +| test.kt:145:66:145:74 | listOf(...) | file:///modules/java.base/java/util/List.class:0:0:0:0 | List | +| test.kt:145:73:145:73 | p2 | test.kt:143:27:143:27 | T | +| test.kt:145:111:145:119 | S | test.kt:145:8:145:12 | S | +| test.kt:145:111:145:119 | listOf(...) | file:///modules/java.base/java/util/List.class:0:0:0:0 | List | +| test.kt:145:118:145:118 | p1 | test.kt:145:8:145:12 | S | diff --git a/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql b/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql index 9bb2ad44c15..9818700479e 100644 --- a/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql +++ b/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql @@ -5,6 +5,8 @@ class InstantiatedType extends ParameterizedType { } // This checks that all type parameter references are erased in the context of a $default function. +// Note this is currently expected to fail since for the time being we extract type variable references +// even where they should be out of scope. predicate containsTypeVariables(Type t) { t instanceof TypeVariable or containsTypeVariables(t.(InstantiatedType).getATypeArgument()) or From e0045d27363f1ec63ddc5b55763624d8ec927bee Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 12 Dec 2022 21:44:24 +0100 Subject: [PATCH 46/93] filter out string literals from the taint-sink meta query --- ruby/ql/src/queries/meta/internal/TaintMetrics.qll | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ruby/ql/src/queries/meta/internal/TaintMetrics.qll b/ruby/ql/src/queries/meta/internal/TaintMetrics.qll index 19d26103cb9..7768828caf6 100644 --- a/ruby/ql/src/queries/meta/internal/TaintMetrics.qll +++ b/ruby/ql/src/queries/meta/internal/TaintMetrics.qll @@ -1,5 +1,5 @@ +private import ruby private import codeql.files.FileSystem -private import codeql.ruby.DataFlow private import codeql.ruby.dataflow.RemoteFlowSources private import codeql.ruby.security.CodeInjectionCustomizations private import codeql.ruby.security.CommandInjectionCustomizations @@ -34,6 +34,12 @@ DataFlow::Node relevantTaintSink(string kind) { kind = "UnsafeDeserialization" and result instanceof UnsafeDeserialization::Sink or kind = "UrlRedirect" and result instanceof UrlRedirect::Sink + ) and + // the sink is not a string literal + not exists(Ast::StringLiteral str | + str = result.asExpr().getExpr() and + // ensure there is no interpolation, as that is not a literal + not str.getComponent(_) instanceof Ast::StringInterpolationComponent ) } From 406a12e7978fadee85e1f8a8ec69d6b82c8905bb Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 13 Dec 2022 09:34:36 +0000 Subject: [PATCH 47/93] Remove unused function DeclarationStack.findFirst --- java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index cce26ed2380..5990fb3389d 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -5794,9 +5794,6 @@ open class KotlinFileExtractor( fun findOverriddenAttributes(f: IrFunction) = stack.lastOrNull { it.first == f } ?.second - - fun findFirst(f: (Pair) -> Boolean) = - stack.findLast(f) } data class OverriddenFunctionAttributes( From a2c886d3679023e9066a18288f09e738fca3d4c0 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 13 Dec 2022 11:57:46 -0500 Subject: [PATCH 48/93] Grammar and wording changes from docs review Co-authored-by: Sam Browning <106113886+sabrowning1@users.noreply.github.com> --- .../AndroidWebViewAddJavascriptInterface.qhelp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.qhelp b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.qhelp index 5cadc31d810..7917a96839d 100644 --- a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.qhelp +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.qhelp @@ -4,27 +4,27 @@

    - The addJavascriptInterface method of + Calling the addJavascriptInterface method of the android.webkit.WebView class allows the web pages of a - WebView to access methods of a Java object via JavaScript. + WebView to access a Java object's methods via JavaScript.

    - Objects exposed to Javascript are available in all frames of the + Objects exposed to JavaScript are available in all frames of the WebView.

    - If you need to expose Java objects with Javascript, you should guarantee - that no untrusted third party content is loaded into the WebView. + If you need to expose Java objects to JavaScript, guarantee that no + untrusted third-party content is loaded into the WebView.

    - In the following (bad) example, a Java object is exposed to Javascript. + In the following (bad) example, a Java object is exposed to JavaScript.

    @@ -33,7 +33,7 @@
  • - Android DocumentationaddJavascriptInterface + Android Documentation: addJavascriptInterface
  • From a3933fbf4fa8c1ae49a246f16c1b63812b004c30 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 13 Dec 2022 18:59:24 +0000 Subject: [PATCH 49/93] Bump minor versions of packs we regularly release --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 3 +-- ruby/ql/src/qlpack.yml | 2 +- 17 files changed, 17 insertions(+), 18 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index b5c7ec3bd7a..ee8913624dc 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.4.7-dev +version: 0.5.0-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 603410f7946..b8b2f8a31ca 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.4.7-dev +version: 0.5.0-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index e02e0a23130..3db26da98de 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.3.7-dev +version: 1.4.0-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 06e38173f20..9d3c5a80b02 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.3.7-dev +version: 1.4.0-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 9ef9fd5b611..75d3cd21610 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.4.7-dev +version: 0.5.0-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 875aa77fff2..926a272097e 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.4.7-dev +version: 0.5.0-dev groups: - csharp - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 0e39e54998a..a3b398f3a0b 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.3.7-dev +version: 0.4.0-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 4427152eef6..88d4e107152 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.3.7-dev +version: 0.4.0-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index feb377ca9ff..9eb1924a3d3 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.4.7-dev +version: 0.5.0-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 032ff0b0d16..9017221edc3 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.4.7-dev +version: 0.5.0-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 2d9cc82e7b2..f506e391d72 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.3.7-dev +version: 0.4.0-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 25854a00154..e22b3c4b5f1 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.4.7-dev +version: 0.5.0-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 68b88ed9a9e..5ecfc312c46 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.3.7-dev +version: 0.4.0-dev groups: shared diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 6ba0baa9fc2..7da58edd333 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.6.7-dev +version: 0.7.0-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index cb7193ce215..0bcf45523e7 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.5.7-dev +version: 0.6.0-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 004e41ae9c2..153afd88563 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.4.7-dev +version: 0.5.0-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme @@ -8,6 +8,5 @@ library: true dependencies: codeql/ssa: ${workspace} codeql/regex: ${workspace} - codeql/ssa: 0.0.1 dataExtensions: - codeql/ruby/frameworks/**/model.yml diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 4ab00a5bd38..85a6b678753 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.4.7-dev +version: 0.5.0-dev groups: - ruby - queries From 40c759e61a40354a4fd63ff33153057fc93cd66b Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Tue, 13 Dec 2022 16:14:28 -0500 Subject: [PATCH 50/93] Add @name property Co-authored-by: Sam Browning <106113886+sabrowning1@users.noreply.github.com> --- .../Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql index d481de249ca..4be7a15daa8 100644 --- a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql @@ -1,4 +1,5 @@ /** + * @name Access Java object methods through JavaScript exposure * @id java/android-webview-addjavascriptinterface * @description Exposing a Javascript interface to a Java object in a WebView can lead to malicious JavaScript controlling the application. * @kind problem From 72484b9483ce3f457134955c636f2426d5c26c65 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 14 Dec 2022 16:15:41 -0500 Subject: [PATCH 51/93] Change wording of addJavascriptInterface query description --- .../CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql index 4be7a15daa8..1b6412138b1 100644 --- a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql @@ -1,7 +1,7 @@ /** * @name Access Java object methods through JavaScript exposure * @id java/android-webview-addjavascriptinterface - * @description Exposing a Javascript interface to a Java object in a WebView can lead to malicious JavaScript controlling the application. + * @description Exposing a Java object in a WebView with a JavaScript interface can lead to malicious JavaScript controlling the application. * @kind problem * @problem.severity warning * @security-severity 6.1 From 904a4bd48b6648e236a23416d2304cb0e53c24a2 Mon Sep 17 00:00:00 2001 From: Jean Helie Date: Fri, 16 Dec 2022 13:52:58 +0100 Subject: [PATCH 52/93] fix script updating endpoint_large_scale test data --- .../test/endpoint_large_scale/README.md | 9 ++++ .../test/update_endpoint_test_files.py | 45 ++++++++++--------- 2 files changed, 33 insertions(+), 21 deletions(-) create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/README.md diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/README.md b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/README.md new file mode 100644 index 00000000000..769dfa6fd27 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/README.md @@ -0,0 +1,9 @@ +# autogenerated folder + +This folder contains test data for the ATM endpoint CodeQL tests that has been autogenerated from the standard JS CodeQL libraries. + +It is helpful, but not required, to periodically update this test data to incorporate new test data introduced in the standard JS CodeQL libraries. + +To update this test data, run `python /path/to/codeql-lib/ql/javascript/test/update_endpoint_test_files.py`. + +For more information view the source code of [`update_endpoint_test_files.py`](../../update_endpoint_test_files.py). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/update_endpoint_test_files.py b/javascript/ql/experimental/adaptivethreatmodeling/test/update_endpoint_test_files.py index 9dc18530bee..131e4f8f93f 100755 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/update_endpoint_test_files.py +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/update_endpoint_test_files.py @@ -2,10 +2,17 @@ # This script updates the JavaScript test data used by the endpoint CodeQL tests. -import glob +import git import logging -import os import shutil +from pathlib import Path + +# Get relevant paths +script_path = Path(__file__).absolute() +git_repo = git.Repo(__file__, search_parent_directories=True) +git_root = Path(git_repo.git.rev_parse('--show-toplevel')) +autogenerated_dest_path = script_path.parent.joinpath('endpoint_large_scale', + 'autogenerated') # File extensions that should be copied to the endpoint tests. This should include source code files # e.g. .js, but not the tests themselves e.g. .expected, .ql, .qlref, etc. @@ -15,35 +22,31 @@ file_extensions_to_copy = ['.js', '.ts'] # path of that test relative to a checkout of github/codeql. test_root_relative_paths = { 'NosqlAndSqlInjection': 'javascript/ql/test/query-tests/Security/CWE-089', - 'TaintedPath': 'javascript/ql/test/query-tests/Security/CWE-022/TaintedPath', + 'TaintedPath': + 'javascript/ql/test/query-tests/Security/CWE-022/TaintedPath', 'Xss': 'javascript/ql/test/query-tests/Security/CWE-079', + 'XssThroughDom': 'javascript/ql/test/query-tests/Security/CWE-116' } -# The path of the endpoint tests, relative to a checkout of github/codeql -test_path = 'javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale' logging.basicConfig(level=logging.INFO) -codeql_lib_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))) - -autogenerated_dest_path = os.path.join(codeql_lib_path, test_path, 'autogenerated') -if os.path.exists(autogenerated_dest_path): +if autogenerated_dest_path.exists(): logging.info(f'Deleting existing autogenerated test files...') shutil.rmtree(autogenerated_dest_path) for key, rel_path in test_root_relative_paths.items(): - test_files_path = os.path.join(codeql_lib_path, rel_path) + test_files_path = git_root.joinpath(rel_path) logging.info(f'Copying test files for {key}...') - - for file in glob.glob(test_files_path + '/**', recursive=True): - # Ignore .testproj directories - if '.testproj' in file: + counter = 0 + for file in Path(test_files_path).glob('**/*'): + if file.is_dir() or '.test_proj' in str(file): continue - - file_extension = os.path.splitext(file)[1] - if file_extension in file_extensions_to_copy: - dest_path = os.path.normpath( - os.path.join(autogenerated_dest_path, key, os.path.relpath(file, test_files_path)) - ) + if file.suffix in file_extensions_to_copy: + autogenerated_dest_path.joinpath(key, ) + dest_path = autogenerated_dest_path.joinpath( + key, file.relative_to(test_files_path)) logging.debug(f'Copying {file} to {dest_path}') - os.makedirs(os.path.dirname(dest_path), exist_ok=True) + dest_path.parent.mkdir(parents=True, exist_ok=True) shutil.copyfile(file, dest_path) + counter += 1 + logging.info(f'copied {counter} files') From cd0220b248d1a949c8e3512ebb5e62cc97b4ccc6 Mon Sep 17 00:00:00 2001 From: Jean Helie Date: Fri, 16 Dec 2022 13:58:52 +0100 Subject: [PATCH 53/93] update autogenerated data for endpoint_large_scale --- .../NosqlAndSqlInjection/untyped/graphql.js | 121 +++++++ .../untyped/json-schema-validator.js | 27 ++ .../NosqlAndSqlInjection/untyped/ldap.js | 71 ++++ .../untyped/marsdb-flow-to.js | 2 +- .../NosqlAndSqlInjection/untyped/marsdb.js | 2 +- .../NosqlAndSqlInjection/untyped/mysql.js | 22 ++ .../untyped/pg-promise.js | 6 +- .../autogenerated/README.md | 7 - .../autogenerated/TaintedPath/TaintedPath.js | 21 +- .../autogenerated/TaintedPath/express.js | 9 + .../autogenerated/TaintedPath/handlebars.js | 52 +++ .../TaintedPath/normalizedPaths.js | 33 +- .../TaintedPath/other-fs-libraries.js | 20 ++ .../autogenerated/TaintedPath/prettier.js | 14 + .../TaintedPath/tainted-access-paths.js | 16 + .../TaintedPath/tainted-require.js | 9 + .../Xss/DomBasedXss/addEventListener.js | 13 + .../Xss/DomBasedXss/classnames.js | 2 + .../Xss/DomBasedXss/clipboard.ts | 101 ++++++ .../Xss/DomBasedXss/custom-element.js | 7 + .../autogenerated/Xss/DomBasedXss/dates.js | 43 +++ .../Xss/DomBasedXss/dragAndDrop.ts | 89 +++++ .../autogenerated/Xss/DomBasedXss/externs.js | 10 + .../autogenerated/Xss/DomBasedXss/jquery.js | 18 + .../Xss/DomBasedXss/trusted-types.js | 10 + .../autogenerated/Xss/DomBasedXss/tst.js | 61 +++- .../Xss/DomBasedXss/xmlRequest.js | 12 +- .../autogenerated/Xss/ExceptionXss/ajv.js | 13 + .../Xss/ReflectedXss/ReflectedXss.js | 9 +- .../Xss/ReflectedXss/live-server.js | 18 + .../autogenerated/Xss/ReflectedXss/tst2.js | 66 ++++ .../autogenerated/Xss/ReflectedXss/tst3.js | 13 + .../UnsafeHtmlConstruction/jquery-plugin.js | 6 + .../UnsafeHtmlConstruction/lib/src/MyNode.ts | 4 + .../Xss/UnsafeHtmlConstruction/lib2/index.ts | 4 + .../UnsafeHtmlConstruction/lib2/src/MyNode.ts | 4 + .../Xss/UnsafeHtmlConstruction/main.js | 42 +++ .../unsafe-jquery-plugin.js | 10 + .../Xss/XssThroughDom/xss-through-dom.js | 50 +++ .../XssThroughDom/BadTagFilter/tst.js | 28 ++ .../XssThroughDom/DoubleEscaping/tst.js | 96 +++++ .../UnsafeHtmlExpansion.js | 39 +++ .../tst-multi-character-sanitization.js | 155 ++++++++ .../IncompleteSanitization/tst.js | 330 ++++++++++++++++++ 44 files changed, 1667 insertions(+), 18 deletions(-) create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/graphql.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/ldap.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/mysql.js delete mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/README.md create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/express.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/handlebars.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/prettier.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/clipboard.ts create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/custom-element.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/dragAndDrop.ts create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/trusted-types.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/live-server.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/tst3.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib/src/MyNode.ts create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib2/index.ts create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib2/src/MyNode.ts create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/BadTagFilter/tst.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/DoubleEscaping/tst.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/IncompleteSanitization/UnsafeHtmlExpansion.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/IncompleteSanitization/tst-multi-character-sanitization.js create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/IncompleteSanitization/tst.js diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/graphql.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/graphql.js new file mode 100644 index 00000000000..723348daf57 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/graphql.js @@ -0,0 +1,121 @@ +var express = require('express'); +var app = express(); + +import { Octokit } from "@octokit/core"; +const kit = new Octokit(); + +app.get('/post/:id', function(req, res) { + const id = req.params.id; + // NOT OK + const response = kit.graphql(` + query { + repository(owner: "github", name: "${id}") { + object(expression: "master:foo") { + ... on Blob { + text + } + } + } + } + `); +}); + +import { graphql, withCustomRequest } from "@octokit/graphql"; + +app.get('/user/:id/', function(req, res) { + const id = req.params.id; + const response = graphql(`foo ${id}`); // NOT OK + + const myGraphql = withCustomRequest(request); + const response = myGraphql(`foo ${id}`); // NOT OK + + const withDefaults = graphql.defaults({}); + withDefaults(`foo ${id}`); // NOT OK +}); + +const { request } = require("@octokit/request"); + +app.get('/article/:id/', async function(req, res) { + const id = req.params.id; + const result = await request("POST /graphql", { + headers: { + authorization: "token 0000000000000000000000000000000000000001", + }, + query: `foo ${id}`, // NOT OK + }); + + const withDefaults = request.defaults({}); + withDefaults("POST /graphql", { query: `foo ${id}` }); // NOT OK +}); + +import { Octokit as Core } from "@octokit/rest"; +const kit2 = new Core(); + +app.get('/event/:id/', async function(req, res) { + const id = req.params.id; + const result = await kit2.graphql(`foo ${id}`); // NOT OK + + const result2 = await kit2.request("POST /graphql", { query: `foo ${id}` }); // NOT OK +}); + +import { graphql as nativeGraphql, buildSchema } from 'graphql'; +var schema = buildSchema(` + type Query { + hello: String + } +`); +var root = { + hello: () => { + return 'Hello world!'; + }, +}; + +app.get('/thing/:id', async function(req, res) { + const id = req.query.id; + const result = await nativeGraphql(schema, "{ foo" + id + " }", root); // NOT OK + + fetch("https://my-grpahql-server.com/graphql", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + // NOT OK + query: `{ + thing { + name + url + ${id} + } + }` + }) + }) + + fetch("https://my-grpahql-server.com/graphql", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + // OK + query: `{ + thing { + name + url + $id + } + }`, + variables: { + id: id + } + }) + }) +}); + +const github = require('@actions/github'); +app.get('/event/:id/', async function(req, res) { + const kit = github.getOctokit("foo") + + const id = req.params.id; + const result = await kit.graphql(`foo ${id}`); // NOT OK +}); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js index 93f09a51adb..a3bfcfd4a30 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js @@ -35,3 +35,30 @@ app.post('/documents/find', (req, res) => { doc.find(query); // NOT OK }); }); + +import Joi from 'joi'; + +const joiSchema = Joi.object({ + date: Joi.string().required(), + title: Joi.string().required() +}).with('date', 'title'); + +app.post('/documents/insert', (req, res) => { + MongoClient.connect('mongodb://localhost:27017/test', async (err, db) => { + let doc = db.collection('doc'); + + const query = JSON.parse(req.query.data); + const validate = joiSchema.validate(query); + if (!validate.error) { + doc.find(query); // OK + } else { + doc.find(query); // NOT OK + } + try { + await joiSchema.validateAsync(query); + doc.find(query); // OK - but still flagged [INCONSISTENCY] + } catch (e) { + doc.find(query); // NOT OK + } + }); +}); \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/ldap.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/ldap.js new file mode 100644 index 00000000000..9502cace21a --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/ldap.js @@ -0,0 +1,71 @@ +const http = require("http"); +const url = require("url"); +const ldap = require("ldapjs"); +const client = ldap.createClient({ + url: "ldap://127.0.0.1:1389", +}); + +// https://github.com/vesse/node-ldapauth-fork/commit/3feea43e243698bcaeffa904a7324f4d96df60e4 +const sanitizeInput = function (input) { + return input + .replace(/\*/g, "\\2a") + .replace(/\(/g, "\\28") + .replace(/\)/g, "\\29") + .replace(/\\/g, "\\5c") + .replace(/\0/g, "\\00") + .replace(/\//g, "\\2f"); +}; + +const server = http.createServer((req, res) => { + let q = url.parse(req.url, true); + + let username = q.query.username; + + var opts1 = { + filter: `(|(name=${username})(username=${username}))`, + }; + + client.search("o=example", opts1, function (err, res) {}); // NOT OK + + client.search( + "o=example", + { filter: `(|(name=${username})(username=${username}))` }, // NOT OK + function (err, res) {} + ); + + // GOOD + client.search( + "o=example", + { // OK + filter: `(|(name=${sanitizeInput(username)})(username=${sanitizeInput( + username + )}))`, + }, + function (err, res) {} + ); + + // GOOD (https://github.com/ldapjs/node-ldapjs/issues/181) + let f = new OrFilter({ + filters: [ + new EqualityFilter({ + attribute: "name", + value: username, + }), + new EqualityFilter({ + attribute: "username", + value: username, + }), + ], + }); + + client.search("o=example", { filter: f }, function (err, res) {}); + + const parsedFilter = ldap.parseFilter( + `(|(name=${username})(username=${username}))` + ); + client.search("o=example", { filter: parsedFilter }, function (err, res) {}); // NOT OK + + const dn = ldap.parseDN(`cn=${username}`, function (err, dn) {}); // NOT OK +}); + +server.listen(389, () => {}); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js index 0c9e49be8e1..9b6d9b2fb88 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js @@ -11,5 +11,5 @@ app.post("/documents/find", (req, res) => { query.title = req.body.title; // NOT OK: query is tainted by user-provided object value - db.myDoc.find(query); + db.myDoc.find(query, (err, data) => {}); }); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/marsdb.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/marsdb.js index dc85bc142b5..0ebbb3d8a71 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/marsdb.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/marsdb.js @@ -13,5 +13,5 @@ app.post("/documents/find", (req, res) => { query.title = req.body.title; // NOT OK: query is tainted by user-provided object value - doc.find(query); + doc.find(query, (err, data) => {}); }); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/mysql.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/mysql.js new file mode 100644 index 00000000000..de328fb49fa --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/mysql.js @@ -0,0 +1,22 @@ +const app = require("express")(); +const mysql = require('mysql'); +const pool = mysql.createPool(getConfig()); + +app.get("search", function handler(req, res) { + let temp = req.params.value; + pool.getConnection(function(err, connection) { + connection.query({ + sql: 'SELECT * FROM `books` WHERE `author` = ?', // OK + values: [temp] + }, function(error, results, fields) {}); + }); + pool.getConnection(function(err, connection) { + connection.query({ + sql: 'SELECT * FROM `books` WHERE `author` = ' + temp, // NOT OK + }, function(error, results, fields) {}); + }); + pool.getConnection(function(err, connection) { + connection.query('SELECT * FROM `books` WHERE `author` = ' + temp, // NOT OK + function(error, results, fields) {}); + }); +}); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js index 07d92a753ec..d3f190dd198 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js @@ -5,7 +5,7 @@ require('express')().get('/foo', (req, res) => { var query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + req.params.category + "' ORDER BY PRICE"; - + db.any(query); // NOT OK db.many(query); // NOT OK db.manyOrNone(query); // NOT OK @@ -17,7 +17,7 @@ require('express')().get('/foo', (req, res) => { db.oneOrNone(query); // NOT OK db.query(query); // NOT OK db.result(query); // NOT OK - + db.one({ text: query // NOT OK }); @@ -59,7 +59,7 @@ require('express')().get('/foo', (req, res) => { db.task(t => { return t.one(query); // NOT OK }); - db.task( + db.taskIf( { cnd: t => t.one(query) }, // NOT OK t => t.one(query) // NOT OK ); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/README.md b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/README.md deleted file mode 100644 index f854c482ba3..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# autogenerated - -This folder contains test data for the ATM endpoint CodeQL tests that has been autogenerated from the standard JS CodeQL libraries. - -It is helpful, but not required, to periodically update this test data to incorporate new test data introduced in the standard JS CodeQL libraries. -To update this test data, run `python /path/to/codeql-lib/ql/javascript/test/update_endpoint_test_files.py --codeql-lib-path /path/to/codeql-lib`. -For more information, run `python /path/to/codeql-lib/ql/javascript/test/update_endpoint_test_files.py --help` or view the source code of [`update_endpoint_test_files.py`](../../update_endpoint_test_files.py). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/TaintedPath.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/TaintedPath.js index 55e75a53757..f98cc9be554 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/TaintedPath.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/TaintedPath.js @@ -193,4 +193,23 @@ var server = http.createServer(function(req, res) { res.write(fs.readFileSync("prefix" + path.replace(/^(\.\.[\/\\])+/, ''))); // NOT OK - not normalized res.write(fs.readFileSync(pathModule.normalize(path).replace(/^(\.\.[\/\\])+/, ''))); // NOT OK (can be absolute) -}); \ No newline at end of file +}); + +import normalizeUrl from 'normalize-url'; + +var server = http.createServer(function(req, res) { + // tests for a few more uri-libraries + const qs = require("qs"); + res.write(fs.readFileSync(qs.parse(req.url).foo)); // NOT OK + res.write(fs.readFileSync(qs.parse(normalizeUrl(req.url)).foo)); // NOT OK + const parseqs = require("parseqs"); + res.write(fs.readFileSync(parseqs.decode(req.url).foo)); // NOT OK +}); + +const cp = require("child_process"); +var server = http.createServer(function(req, res) { + let path = url.parse(req.url, true).query.path; + cp.execSync("foobar", {cwd: path}); // NOT OK + cp.execFileSync("foobar", ["args"], {cwd: path}); // NOT OK + cp.execFileSync("foobar", {cwd: path}); // NOT OK +}); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/express.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/express.js new file mode 100644 index 00000000000..dad320e3aba --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/express.js @@ -0,0 +1,9 @@ +var express = require("express"), + fileUpload = require("express-fileupload"); + +let app = express(); +app.use(fileUpload()); + +app.get("/some/path", function (req, res) { + req.files.foo.mv(req.query.bar); +}); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/handlebars.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/handlebars.js new file mode 100644 index 00000000000..512b851592a --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/handlebars.js @@ -0,0 +1,52 @@ +const express = require('express'); +const hb = require("handlebars"); +const fs = require("fs"); + +const app = express(); + +const data = {}; + +function init() { + hb.registerHelper("catFile", function catFile(filePath) { + return fs.readFileSync(filePath); // SINK (reads file) + }); + hb.registerHelper("prependToLines", function prependToLines(prefix, filePath) { + return fs + .readFileSync(filePath) + .split("\n") + .map((line) => prefix + line) + .join("\n"); + }); + data.compiledFileAccess = hb.compile("contents of file {{path}} are: {{catFile path}}") + data.compiledBenign = hb.compile("hello, {{name}}"); + data.compiledUnknown = hb.compile(fs.readFileSync("greeting.template")); + data.compiledMixed = hb.compile("helpers may have several args, like here: {{prependToLines prefix path}}"); +} + +init(); + +app.get('/some/path1', function (req, res) { + res.send(data.compiledFileAccess({ path: req.params.path })); // NOT ALLOWED (template uses vulnerable catFile) +}); + +app.get('/some/path2', function (req, res) { + res.send(data.compiledBenign({ name: req.params.name })); // ALLOWED (this template does not use catFile) +}); + +app.get('/some/path3', function (req, res) { + res.send(data.compiledUnknown({ name: req.params.name })); // ALLOWED (could be using a vulnerable helper, but we'll assume it's ok) +}); + +app.get('/some/path4', function (req, res) { + res.send(data.compiledMixed({ + prefix: ">>> ", + path: req.params.path // NOT ALLOWED (template uses vulnerable helper) + })); +}); + +app.get('/some/path5', function (req, res) { + res.send(data.compiledMixed({ + prefix: req.params.prefix, // ALLOWED (this parameter is safe) + path: "data/path-5.txt" + })); +}); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/normalizedPaths.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/normalizedPaths.js index f03260e3c84..f5caae46c45 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/normalizedPaths.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/normalizedPaths.js @@ -370,4 +370,35 @@ app.get('/yet-another-prefix2', (req, res) => { function allowPath(requestPath, rootPath) { return requestPath.indexOf(rootPath) === 0; } -}); \ No newline at end of file +}); + +import slash from 'slash'; +app.get('/slash-stuff', (req, res) => { + let path = req.query.path; + + fs.readFileSync(path); // NOT OK + + fs.readFileSync(slash(path)); // NOT OK +}); + +app.get('/dotdot-regexp', (req, res) => { + let path = pathModule.normalize(req.query.x); + if (pathModule.isAbsolute(path)) + return; + fs.readFileSync(path); // NOT OK + if (!path.match(/\./)) { + fs.readFileSync(path); // OK + } + if (!path.match(/\.\./)) { + fs.readFileSync(path); // OK + } + if (!path.match(/\.\.\//)) { + fs.readFileSync(path); // OK + } + if (!path.match(/\.\.\/foo/)) { + fs.readFileSync(path); // NOT OK + } + if (!path.match(/(\.\.\/|\.\.\\)/)) { + fs.readFileSync(path); // OK + } +}); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/other-fs-libraries.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/other-fs-libraries.js index 14c9e357492..bda7051ba80 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/other-fs-libraries.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/other-fs-libraries.js @@ -50,4 +50,24 @@ http.createServer(function(req, res) { fs.readFileSync(path); // NOT OK asyncFS.readFileSync(path); // NOT OK + + require("pify")(fs.readFileSync)(path); // NOT OK + require("pify")(fs).readFileSync(path); // NOT OK + + require('util.promisify')(fs.readFileSync)(path); // NOT OK + + require("thenify")(fs.readFileSync)(path); // NOT OK + + const readPkg = require('read-pkg'); + var pkg = readPkg.readPackageSync({cwd: path}); // NOT OK + var pkgPromise = readPkg.readPackageAsync({cwd: path}); // NOT OK +}); + +const mkdirp = require("mkdirp"); +http.createServer(function(req, res) { + var path = url.parse(req.url, true).query.path; + + fs.readFileSync(path); // NOT OK + mkdirp(path); // NOT OK + mkdirp.sync(path); // NOT OK }); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/prettier.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/prettier.js new file mode 100644 index 00000000000..7546bb2c293 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/prettier.js @@ -0,0 +1,14 @@ +const express = require('express'); +const prettier = require("prettier"); + +const app = express(); +app.get('/some/path', function (req, res) { + const { p } = req.params; + prettier.resolveConfig(p).then((options) => { // NOT OK + const formatted = prettier.format("foo", options); + }); + + prettier.resolveConfig("foo", {config: p}).then((options) => { // NOT OK + const formatted = prettier.format("bar", options); + }); +}); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/tainted-access-paths.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/tainted-access-paths.js index 3c98512dad7..465b5b70b69 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/tainted-access-paths.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/tainted-access-paths.js @@ -32,3 +32,19 @@ var server = http.createServer(function(req, res) { }); server.listen(); + +var nodefs = require('node:fs'); + +var server2 = http.createServer(function(req, res) { + let path = url.parse(req.url, true).query.path; + nodefs.readFileSync(path); // NOT OK +}); + +server2.listen(); + +const chownr = require("chownr"); + +var server3 = http.createServer(function (req, res) { + let path = url.parse(req.url, true).query.path; + chownr(path, "someuid", "somegid", function (err) {}); // NOT OK +}); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/tainted-require.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/tainted-require.js index 443ccdd31b0..23f89c55c39 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/tainted-require.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/TaintedPath/tainted-require.js @@ -6,3 +6,12 @@ app.get('/some/path', function(req, res) { // BAD: loading a module based on un-sanitized query parameters var m = require(req.param("module")); }); + +const resolve = require("resolve"); +app.get('/some/path', function(req, res) { + var module = resolve.sync(req.param("module")); // NOT OK - resolving module based on query parameters + + resolve(req.param("module"), { basedir: __dirname }, function(err, res) { // NOT OK - resolving module based on query parameters + var module = res; + }); +}); \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/addEventListener.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/addEventListener.js index fbb1dcfe01d..97d21371d08 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/addEventListener.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/addEventListener.js @@ -14,4 +14,17 @@ function test() { } window.addEventListener("message", foo.bind(null, {data: 'items'})); + + window.onmessage = e => { + if (e.origin !== "https://foobar.com") { + return; + } + document.write(e.data); // OK - there is an origin check + } + + window.onmessage = e => { + if (mySet.includes(e.origin)) { + document.write(e.data); // OK - there is an origin check + } + } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/classnames.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/classnames.js index e18f7844f68..a0e75045a2e 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/classnames.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/classnames.js @@ -13,4 +13,6 @@ function main() { document.body.innerHTML = `Hello`; // NOT OK document.body.innerHTML = `Hello`; // OK document.body.innerHTML = `Hello`; // NOT OK + + document.body.innerHTML += `Hello`; // NOT OK } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/clipboard.ts b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/clipboard.ts new file mode 100644 index 00000000000..b87d5a43bee --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/clipboard.ts @@ -0,0 +1,101 @@ +$("#foo").on("paste", paste); + +function paste(e) { + const { clipboardData } = e.originalEvent; + if (!clipboardData) return; + + const text = clipboardData.getData('text/plain'); + const html = clipboardData.getData('text/html'); + if (!text && !html) return; + + e.preventDefault(); + + const div = document.createElement('div'); + if (html) { + div.innerHTML = html; // NOT OK + } else { + div.textContent = text; + } + document.body.append(div); +} + +export function install(el: HTMLElement): void { + el.addEventListener('paste', (e) => { + $("#id").html(e.clipboardData.getData('text/html')); // NOT OK + }) +} + +document.addEventListener('paste', (e) => { + $("#id").html(e.clipboardData.getData('text/html')); // NOT OK +}); + +$("#foo").bind('paste', (e) => { + $("#id").html(e.originalEvent.clipboardData.getData('text/html')); // NOT OK +}); + +(function () { + let div = document.createElement("div"); + div.onpaste = function (e: ClipboardEvent) { + const { clipboardData } = e; + if (!clipboardData) return; + + const text = clipboardData.getData('text/plain'); + const html = clipboardData.getData('text/html'); + if (!text && !html) return; + + e.preventDefault(); + + const div = document.createElement('div'); + if (html) { + div.innerHTML = html; // NOT OK + } else { + div.textContent = text; + } + document.body.append(div); + } +})(); + +async function getClipboardData(e: ClipboardEvent): Promise> { + // Using a set to filter out duplicates. For some reason, dropping URLs duplicates them 3 times (for me) + const dropItems = new Set(); + + // First get all files in the drop event + if (e.clipboardData.files.length > 0) { + // tslint:disable-next-line: prefer-for-of + for (let i = 0; i < e.clipboardData.files.length; i++) { + const file = e.clipboardData.files[i]; + } + } + + if (e.clipboardData.types.includes('text/html')) { + const droppedHtml = e.clipboardData.getData('text/html'); + const container = document.createElement('html'); + container.innerHTML = droppedHtml; + const imgs = container.getElementsByTagName('img'); + if (imgs.length === 1) { + const src = imgs[0].src; + dropItems.add(src); + } + } else if (e.clipboardData.types.includes('text/plain')) { + const plainText = e.clipboardData.getData('text/plain'); + // Check if text is an URL + if (/^https?:\/\//i.test(plainText)) { + dropItems.add(plainText); + } + } + + const imageItems = Array.from(dropItems); + return imageItems; + } + +// inputevent +(function () { + let div = document.createElement("div"); + div.addEventListener("beforeinput", function (e: InputEvent) { + const { data, inputType, isComposing, dataTransfer } = e; + if (!dataTransfer) return; + + const html = dataTransfer.getData('text/html'); + $("#id").html(html); // NOT OK + }); +})(); \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/custom-element.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/custom-element.js new file mode 100644 index 00000000000..9177f08bdc5 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/custom-element.js @@ -0,0 +1,7 @@ +import * as dummy from 'dummy'; + +class CustomElm extends HTMLElement { + test() { + this.innerHTML = window.name; // NOT OK + } +} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/dates.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/dates.js index 592dc37c973..47513c796d9 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/dates.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/dates.js @@ -16,4 +16,47 @@ function main() { document.body.innerHTML = `Time is ${moment(time).format(taint)}`; // NOT OK document.body.innerHTML = `Time is ${moment(taint).format()}`; // OK document.body.innerHTML = `Time is ${dateformat(time, taint)}`; // NOT OK + + import dayjs from 'dayjs'; + document.body.innerHTML = `Time is ${dayjs(time).format(taint)}`; // NOT OK } + +import LuxonAdapter from "@date-io/luxon"; +import DateFnsAdapter from "@date-io/date-fns"; +import MomentAdapter from "@date-io/moment"; +import DayJSAdapter from "@date-io/dayjs" + +function dateio() { + let taint = decodeURIComponent(window.location.hash.substring(1)); + + const dateFns = new DateFnsAdapter(); + const luxon = new LuxonAdapter(); + const moment = new MomentAdapter(); + const dayjs = new DayJSAdapter(); + + document.body.innerHTML = `Time is ${dateFns.formatByString(new Date(), taint)}`; // NOT OK + document.body.innerHTML = `Time is ${luxon.formatByString(luxon.date(), taint)}`; // NOT OK + document.body.innerHTML = `Time is ${moment.formatByString(moment.date(), taint)}`; // NOT OK + document.body.innerHTML = `Time is ${dayjs.formatByString(dayjs.date(), taint)}`; // NOT OK +} + +import { DateTime } from "luxon"; + +function luxon() { + let taint = decodeURIComponent(window.location.hash.substring(1)); + + document.body.innerHTML = `Time is ${DateTime.now().plus({years: 1}).toFormat(taint)}`; // NOT OK + document.body.innerHTML = `Time is ${new DateTime().setLocale('fr').toFormat(taint)}`; // NOT OK + document.body.innerHTML = `Time is ${DateTime.fromISO("2020-01-01").startOf('day').toFormat(taint)}`; // NOT OK +} + +function dateio2() { + let taint = decodeURIComponent(window.location.hash.substring(1)); + + const moment = new MomentAdapter(); + document.body.innerHTML = `Time is ${moment.addDays(moment.date("2020-06-21"), 1).format(taint)}`; // NOT OK + const luxon = new LuxonAdapter(); + document.body.innerHTML = `Time is ${luxon.endOfDay(luxon.date()).toFormat(taint)}`; // NOT OK + const dayjs = new DayJSAdapter(); + document.body.innerHTML = `Time is ${dayjs.setHours(dayjs.date(), 4).format(taint)}`; // NOT OK +} \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/dragAndDrop.ts b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/dragAndDrop.ts new file mode 100644 index 00000000000..487e51c8f8a --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/dragAndDrop.ts @@ -0,0 +1,89 @@ +$("#foo").on("drop", drop); + +function drop(e) { + const { dataTransfer } = e.originalEvent; + if (!dataTransfer) return; + + const text = dataTransfer.getData('text/plain'); + const html = dataTransfer.getData('text/html'); + if (!text && !html) return; + + e.preventDefault(); + + const div = document.createElement('div'); + if (html) { + div.innerHTML = html; // NOT OK + } else { + div.textContent = text; + } + document.body.append(div); +} + +export function install(el: HTMLElement): void { + el.addEventListener('drop', (e) => { + $("#id").html(e.dataTransfer.getData('text/html')); // NOT OK + }) +} + +document.addEventListener('drop', (e) => { + $("#id").html(e.dataTransfer.getData('text/html')); // NOT OK +}); + +$("#foo").bind('drop', (e) => { + $("#id").html(e.originalEvent.dataTransfer.getData('text/html')); // NOT OK +}); + +(function () { + let div = document.createElement("div"); + div.ondrop = function (e: DragEvent) { + const { dataTransfer } = e; + if (!dataTransfer) return; + + const text = dataTransfer.getData('text/plain'); + const html = dataTransfer.getData('text/html'); + if (!text && !html) return; + + e.preventDefault(); + + const div = document.createElement('div'); + if (html) { + div.innerHTML = html; // NOT OK + } else { + div.textContent = text; + } + document.body.append(div); + } +})(); + +async function getDropData(e: DragEvent): Promise> { + // Using a set to filter out duplicates. For some reason, dropping URLs duplicates them 3 times (for me) + const dropItems = new Set(); + + // First get all files in the drop event + if (e.dataTransfer.files.length > 0) { + // tslint:disable-next-line: prefer-for-of + for (let i = 0; i < e.dataTransfer.files.length; i++) { + const file = e.dataTransfer.files[i]; + } + } + + if (e.dataTransfer.types.includes('text/html')) { + const droppedHtml = e.dataTransfer.getData('text/html'); + const container = document.createElement('html'); + container.innerHTML = droppedHtml; + const imgs = container.getElementsByTagName('img'); + if (imgs.length === 1) { + const src = imgs[0].src; + dropItems.add(src); + } + } else if (e.dataTransfer.types.includes('text/plain')) { + const plainText = e.dataTransfer.getData('text/plain'); + // Check if text is an URL + if (/^https?:\/\//i.test(plainText)) { + dropItems.add(plainText); + } + } + + const imageItems = Array.from(dropItems); + return imageItems; + } \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/externs.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/externs.js index 7079f471978..0132d7ae7ca 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/externs.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/externs.js @@ -57,3 +57,13 @@ function Node() {} * @type {Node} */ Node.prototype.parentNode; + +/** + * @return {DomObjectStub} + */ +DomObjectStub.prototype.insertRow = function() {}; + +/** + * @return {DomObjectStub} + */ +DomObjectStub.prototype.insertCell = function() {}; diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/jquery.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/jquery.js index 928648ced0f..3bff577fbdf 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/jquery.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/jquery.js @@ -14,4 +14,22 @@ function test() { elm.innerHTML = decodeURIComponent(window.location.hash); // NOT OK elm.innerHTML = decodeURIComponent(window.location.search); // NOT OK elm.innerHTML = decodeURIComponent(window.location.toString()); // NOT OK + + let hash = window.location.hash; + $(hash); // OK - start with '#' + + $(hash.substring(1)); // NOT OK + $(hash.substring(1, 10)); // NOT OK + $(hash.substr(1)); // NOT OK + $(hash.slice(1)); // NOT OK + $(hash.substring(0, 10)); // OK + + $(hash.replace('#', '')); // NOT OK + $(window.location.search.replace('?', '')); // NOT OK + $(hash.replace('!', '')); // OK + $(hash.replace('blah', '')); // OK + + $(hash + 'blah'); // OK + $('blah' + hash); // OK - does not start with '<' + $('' + hash + ''); // NOT OK } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/trusted-types.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/trusted-types.js new file mode 100644 index 00000000000..cba48137122 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/trusted-types.js @@ -0,0 +1,10 @@ +(function() { + const policy1 = trustedTypes.createPolicy('x', { createHTML: x => x }); // NOT OK + policy1.createHTML(window.name); + + const policy2 = trustedTypes.createPolicy('x', { createHTML: x => 'safe' }); // OK + policy2.createHTML(window.name); + + const policy3 = trustedTypes.createPolicy('x', { createHTML: x => x }); // OK + policy3.createHTML('safe'); +})(); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/tst.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/tst.js index 44f88e0762b..3c609ddcc92 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/tst.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/tst.js @@ -430,4 +430,63 @@ function nonGlobalSanitizer() { $("#foo").html(target.replace(/[\s\S]*<\/metadata>/, '')); // NOT OK $("#foo").html(target.replace(/<|>/g, '')); // OK -} \ No newline at end of file +} + +function mootools(){ + var source = document.location.search; + + new Element("div"); // OK + new Element("div", {text: source}); // OK + new Element("div", {html: source}); // NOT OK + new Element("div").set("html", source); // NOT OK + new Element("div").set({"html": source}); // NOT OK + new Element("div").setProperty("html", source); // NOT OK + new Element("div").setProperties({"html": source}); // NOT OK + new Element("div").appendHtml(source); // NOT OK +} + + +const Convert = require('ansi-to-html'); +const ansiToHtml = new Convert(); + +function ansiToHTML() { + var source = document.location.search; + + $("#foo").html(source); // NOT OK + $("#foo").html(ansiToHtml.toHtml(source)); // NOT OK +} + +function domMethods() { + var source = document.location.search; + + let table = document.getElementById('mytable'); + table.innerHTML = source; // NOT OK + let row = table.insertRow(-1); + row.innerHTML = source; // NOT OK + let cell = row.insertCell(); + cell.innerHTML = source; // NOT OK +} + +function urlStuff() { + var url = document.location.search.substr(1); + + $("", {href: url}).appendTo("body"); // NOT OK + $("#foo").attr("href", url); // NOT OK + $("#foo").attr({href: url}); // NOT OK + $("", {src: url}).appendTo("body"); // NOT OK + $("", {href: win.location.href}).appendTo("body"); // OK + + $("", {src: "http://google.com/" + url}).appendTo("body"); // OK + + $("", {src: ["http://google.com", url].join("/")}).appendTo("body"); // OK + + if (url.startsWith("https://")) { + $("", {src: url}).appendTo("body"); // OK + } else { + $("", {src: url}).appendTo("body"); // NOT OK + } + + window.open(location.hash.substr(1)); // OK - any JavaScript is executed in another context + + navigation.navigate(location.hash.substr(1)); // NOT OK +} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/xmlRequest.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/xmlRequest.js index 91dca5e0c51..28f49bb71ca 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/xmlRequest.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/DomBasedXss/xmlRequest.js @@ -6,11 +6,19 @@ $(document).ready(function () { xhr.onreadystatechange = function () { if (xhr.readyState !== 4) { return } var json = JSON.parse(xhr.responseText) - $("#myThing").html(json.message); + $("#myThing").html(json.message); // caught with additional sources } try { xhr.send() } catch (error) { console.log(error) } -}) \ No newline at end of file +}); + +$(document).ready(async function () { + const got = require('got'); + const resp = await got.get("{{ some_url }}"); + const json = JSON.parse(resp.body); + $("#myThing").html(json.message); // caught with additional sources + +}); \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ExceptionXss/ajv.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ExceptionXss/ajv.js index 2ebbc46a4b3..36dd5181a1b 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ExceptionXss/ajv.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ExceptionXss/ajv.js @@ -11,3 +11,16 @@ app.post('/polldata', (req, res) => { res.send(ajv.errorsText()); // NOT OK } }); + +const joi = require("joi"); +const joiSchema = joi.object().keys({ + name: joi.string().required(), + age: joi.number().required() +}).with('name', 'age'); + +app.post('/votedata', (req, res) => { + const val = joiSchema.validate(req.body); + if (val.error) { + res.send(val.error); // NOT OK + } +}); \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/ReflectedXss.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/ReflectedXss.js index 6a85c0ec1b0..2b7c2057f0f 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/ReflectedXss.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/ReflectedXss.js @@ -101,4 +101,11 @@ app.get('/user/:id', function (req, res) { res.send(markdownIt.use(require('markdown-it-sanitizer')).render(req.body)); // OK - HTML is sanitized. res.send(markdownIt.use(require('markdown-it-abbr')).use(unknown).render(req.body)); // NOT OK -}); \ No newline at end of file +}); + +var Hapi = require('hapi'); +var hapi = new Hapi.Server(); +hapi.route({ + handler: function (request){ + return request.query.p; // NOT OK + }}); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/live-server.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/live-server.js new file mode 100644 index 00000000000..aed560fc076 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/live-server.js @@ -0,0 +1,18 @@ +var liveServer = require("live-server"); + +const middleware = [function(req, res, next) { + const tainted = req.url; + + res.end(`${tainted}`); // NOT OK +}]; + +middleware.push(function(req, res, next) { + const tainted = req.url; + + res.end(`${tainted}`); // NOT OK +}); + +var params = { + middleware +}; +liveServer.start(params); \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/tst2.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/tst2.js index 521b6b20a7c..60399a9b63d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/tst2.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/tst2.js @@ -22,3 +22,69 @@ app.get('/bar', function(req, res) { else res.send(p); // OK }); + + +const clone = require('clone'); + +app.get('/baz', function(req, res) { + let { p } = req.params; + + var obj = {}; + obj.p = p; + var other = clone(obj); + + res.send(p); // NOT OK + res.send(other.p); // NOT OK +}); + +const serializeJavaScript = require('serialize-javascript'); + +app.get('/baz', function(req, res) { + let { p } = req.params; + + var serialized = serializeJavaScript(p); + + res.send(serialized); // OK + + var unsafe = serializeJavaScript(p, {unsafe: true}); + + res.send(unsafe); // NOT OK +}); + +const fclone = require('fclone'); + +app.get('/baz', function(req, res) { + let { p } = req.params; + + var obj = {}; + obj.p = p; + var other = fclone(obj); + + res.send(p); // NOT OK + res.send(other.p); // NOT OK +}); + +const jc = require('json-cycle'); +app.get('/baz', function(req, res) { + let { p } = req.params; + + var obj = {}; + obj.p = p; + var other = jc.retrocycle(jc.decycle(obj)); + + res.send(p); // NOT OK + res.send(other.p); // NOT OK +}); + +const sortKeys = require('sort-keys'); + +app.get('/baz', function(req, res) { + let { p } = req.params; + + var obj = {}; + obj.p = p; + var other = sortKeys(obj); + + res.send(p); // NOT OK + res.send(other.p); // NOT OK +}); \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/tst3.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/tst3.js new file mode 100644 index 00000000000..c7d0fd91a4a --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/ReflectedXss/tst3.js @@ -0,0 +1,13 @@ +var express = require('express'); + +var app = express(); +app.enable('x-powered-by').disable('x-powered-by').get('/', function (req, res) { + let { p } = req.params; + res.send(p); // NOT OK +}); + +const prettier = require("prettier"); +app.post("foobar", function (reg, res) { + const code = prettier.format(reg.body, { semi: false, parser: "babel" }); + res.send(code); // NOT OK +}); \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/jquery-plugin.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/jquery-plugin.js index 07b25b558f9..6a133a747bd 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/jquery-plugin.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/jquery-plugin.js @@ -7,3 +7,9 @@ }(function ($) { $("" + $.trim("foo") + ""); // OK })); + +$.fn.myPlugin = function (stuff, options) { + $("#foo").html("" + options.foo + ""); // NOT OK + + $("#foo").html("" + stuff + ""); // NOT OK +} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib/src/MyNode.ts b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib/src/MyNode.ts new file mode 100644 index 00000000000..91e81238605 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib/src/MyNode.ts @@ -0,0 +1,4 @@ +export function trivialXss(s: string) { + const html = "" + s + ""; // NOT OK + document.querySelector("#html").innerHTML = html; +} \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib2/index.ts b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib2/index.ts new file mode 100644 index 00000000000..21bb420b71f --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib2/index.ts @@ -0,0 +1,4 @@ +export function trivialXss(s: string) { + const html = "" + s + ""; // NOT OK - this file is recognized as a main file. + document.querySelector("#html").innerHTML = html; +} \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib2/src/MyNode.ts b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib2/src/MyNode.ts new file mode 100644 index 00000000000..35908c88f16 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/lib2/src/MyNode.ts @@ -0,0 +1,4 @@ +export function trivialXss(s: string) { + const html = "" + s + ""; // OK - this file is not recognized as a main file. + document.querySelector("#html").innerHTML = html; +} \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/main.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/main.js index 1097e126feb..01d376a2f8b 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/main.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeHtmlConstruction/main.js @@ -75,3 +75,45 @@ module.exports.intentionalTemplate = function (obj) { const html = "" + obj.spanTemplate + ""; // OK document.querySelector("#template").innerHTML = html; } + +module.exports.types = function (val) { + if (typeof val === "string") { + $("#foo").html("" + val + ""); // NOT OK + } else if (typeof val === "number") { + $("#foo").html("" + val + ""); // OK + } else if (typeof val === "boolean") { + $("#foo").html("" + val + ""); // OK + } +} + +function createHTML(x) { + return "" + x + ""; // NOT OK +} + +module.exports.usesCreateHTML = function (x) { + $("#foo").html(createHTML(x)); +} + +const myMermaid = require('mermaid'); +module.exports.usesCreateHTML = function (x) { + myMermaid.render("id", x, function (svg) { // NOT OK + $("#foo").html(svg); + }); + + $("#foo").html(myMermaid.render("id", x)); // NOT OK + + mermaid.render("id", x, function (svg) {// NOT OK + $("#foo").html(svg); + }); + + $("#foo").html(mermaid.render("id", x)); // NOT OK + + mermaid.mermaidAPI.render("id", x, function (svg) {// NOT OK + $("#foo").html(svg); + }); +} + +module.exports.xssThroughMarkdown = function (s) { + const html = markdown.render(s); // NOT OK + document.querySelector("#markdown").innerHTML = html; +} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js index 51621fec90b..b695c57fab8 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js @@ -182,4 +182,14 @@ $(document).find(options.target); // OK }}); + $.fn.position = function( options ) { + if ( !options || !options.of ) { + return doSomethingElse( this, arguments ); + } + // extending options + options = $.extend( {}, options ); + + var target = $( options.of ); // NOT OK + console.log(target); + }; }); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/XssThroughDom/xss-through-dom.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/XssThroughDom/xss-through-dom.js index 656f233ca9e..7728722bd16 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/XssThroughDom/xss-through-dom.js +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/Xss/XssThroughDom/xss-through-dom.js @@ -89,4 +89,54 @@ $("section h1").each(function(){ $("nav ul").append("Section"); // OK }); + + $("#id").html($("#foo").find(".bla")[0].value); // NOT OK. + + for (var i = 0; i < foo.length; i++) { + $("#id").html($("#foo").find(".bla")[i].value); // NOT OK. + } +})(); + +class Super { + constructor() { + this.el = $("#id").get(0); + } +} + +class Sub extends Super { + constructor() { + super(); + $("#id").get(0).innerHTML = "foo"; // NOT OK. Attack: `` + } +} + +(function () { + const src = document.getElementById("#link").src; + $("#id").html(src); // NOT OK. + + $("#id").attr("src", src); // OK + + $("input.foo")[0].onchange = function (ev) { + $("#id").html(ev.target.files[0].name); // NOT OK. + + $("img#id").attr("src", URL.createObjectURL(ev.target.files[0])); // NOT OK + } +})(); + +(function () { + let elem = document.createElement('a'); + const wSelection = getSelection(); + const dSelection = document.getSelection(); + let linkText = wSelection.toString() || dSelection.toString() || ''; + elem.innerHTML = linkText; // NOT OK + $("#id").html(linkText); // NOT OK + elem.innerText = linkText; // OK +})(); + +const cashDom = require("cash-dom"); + +(function () { + const src = document.getElementById("#link").src; + cash("#id").html(src); // NOT OK. + cashDom("#id").html(src); // NOT OK })(); \ No newline at end of file diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/BadTagFilter/tst.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/BadTagFilter/tst.js new file mode 100644 index 00000000000..2b71107e512 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/BadTagFilter/tst.js @@ -0,0 +1,28 @@ +var filters = [ + /.*?<\/script>/i, // NOT OK - doesn't match newlines or `` + /.*?<\/script>/is, // NOT OK - doesn't match `` + /.*?<\/script[^>]*>/is, // OK + //is, // OK - we don't care regexps that only match comments + /)|([^\/\s>]+)[\S\s]*?>/, // NOT OK - doesn't match comments with the right capture groups + /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))/, // NOT OK - capture groups + /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|)/gi, // NOT OK - capture groups + /<(?:(?:!--([\w\W]*?)-->)|(?:!\[CDATA\[([\w\W]*?)\]\]>)|(?:!DOCTYPE([\w\W]*?)>)|(?:\?([^\s\/<>]+) ?([\w\W]*?)[?/]>)|(?:\/([A-Za-z][A-Za-z0-9\-_\:\.]*)>)|(?:([A-Za-z][A-Za-z0-9\-_\:\.]*)((?:\s+[^"'>]+(?:(?:"[^"]*")|(?:'[^']*')|[^>]*))*|\/|\s+)>))/g, // NOT OK - capture groups + /|<([^>]*?)>/g, // NOT OK - capture groups +] + +doFilters(filters) + +var strip = ']*)>([\\S\\s]*?)<\/script([^>]*)>'; // OK - it's used with the ignorecase flag +new RegExp(strip, 'gi'); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/DoubleEscaping/tst.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/DoubleEscaping/tst.js new file mode 100644 index 00000000000..76cfe80b238 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/DoubleEscaping/tst.js @@ -0,0 +1,96 @@ +function badEncode(s) { + return s.replace(/"/g, """) + .replace(/'/g, "'") + .replace(/&/g, "&"); +} + +function goodEncode(s) { + return s.replace(/&/g, "&") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + +function goodDecode(s) { + return s.replace(/"/g, "\"") + .replace(/'/g, "'") + .replace(/&/g, "&"); +} + +function badDecode(s) { + return s.replace(/&/g, "&") + .replace(/"/g, "\"") + .replace(/'/g, "'"); +} + +function cleverEncode(code) { + return code.replace(//g, '>').replace(/&(?![\w\#]+;)/g, '&'); +} + +function badDecode2(s) { + return s.replace(/&/g, "&") + .replace(/s?ome|thin*g/g, "else") + .replace(/'/g, "'"); +} + +function goodDecodeInLoop(ss) { + var res = []; + for (var s of ss) { + s = s.replace(/"/g, "\"") + .replace(/'/g, "'") + .replace(/&/g, "&"); + res.push(s); + } + return res; +} + +function badDecode3(s) { + s = s.replace(/&/g, "&"); + s = s.replace(/"/g, "\""); + return s.replace(/'/g, "'"); +} + +function badUnescape(s) { + return s.replace(/\\\\/g, '\\') + .replace(/\\'/g, '\'') + .replace(/\\"/g, '\"'); +} + +function badPercentEscape(s) { + s = s.replace(/&/g, '%26'); + s = s.replace(/%/g, '%25'); + return s; +} + +function badEncode(s) { + var indirect1 = /"/g; + var indirect2 = /'/g; + var indirect3 = /&/g; + return s.replace(indirect1, """) + .replace(indirect2, "'") + .replace(indirect3, "&"); +} + +function badEncodeWithReplacer(s) { + var repl = { + '"': """, + "'": "'", + "&": "&" + }; + return s.replace(/["']/g, (c) => repl[c]).replace(/&/g, "&"); +} + +// dubious, but out of scope for this query +function badRoundtrip(s) { + return s.replace(/\\\\/g, "\\").replace(/\\/g, "\\\\"); +} + +function testWithCapturedVar(x) { + var captured = x; + (function() { + captured = captured.replace(/\\/g, "\\\\"); + })(); +} + +function encodeDecodeEncode(s) { + return goodEncode(goodDecode(goodEncode(s))); +} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/IncompleteSanitization/UnsafeHtmlExpansion.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/IncompleteSanitization/UnsafeHtmlExpansion.js new file mode 100644 index 00000000000..9d45c9f8f49 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/IncompleteSanitization/UnsafeHtmlExpansion.js @@ -0,0 +1,39 @@ +(function(){ + let defaultPattern = /<(([\w:]+)[^>]*)\/>/gi; + let expanded = "<$1>"; + + // lib1 + html.replace( + /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + expanded + ); // NOT OK + html.replace(/<(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, expanded); // NOT OK + + // lib2 + html.replace( + /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + expanded + ); // NOT OK + html.replace(/<(([\w:]+)[^>]*)\/>/gi, expanded); // NOT OK + + // lib3 + html.replace( + /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, + expanded + ); // NOT OK + html.replace(/<(([\w:-]+)[^>]*)\/>/gi, expanded); // NOT OK + + html.replace(defaultPattern, expanded); // NOT OK + function getPattern() { + return defaultPattern; + } + html.replace(getPattern(), expanded); // NOT OK + + function getExpanded() { + return expanded; + } + html.replace(defaultPattern, getExpanded()); // NOT OK (but not tracking the expansion string) + html.replace(defaultPattern, something); // OK (possibly) + defaultPattern.match(something); // OK (possibly) + getPattern().match(something); // OK (possibly) +}); diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/IncompleteSanitization/tst-multi-character-sanitization.js b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/IncompleteSanitization/tst-multi-character-sanitization.js new file mode 100644 index 00000000000..43f650acce9 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/XssThroughDom/IncompleteSanitization/tst-multi-character-sanitization.js @@ -0,0 +1,155 @@ +// CVE-2019-10756 +(function(content) { + content = content.replace(/<.*cript.*\/scrip.*>/gi, ""); // NOT OK + content = content.replace(/ on\w+=".*"/g, ""); // NOT OK + content = content.replace(/ on\w+=\'.*\'/g, ""); // NOT OK + return content; +}); +(function(content) { + content = content.replace(/<.*cript.*/gi, ""); // NOT OK + content = content.replace(/.on\w+=.*".*"/g, ""); // NOT OK + content = content.replace(/.on\w+=.*\'.*\'/g, ""); // NOT OK + + return content; +}); + +// CVE-2020-7656 +(function(responseText) { + var rscript = /)<[^<]*)*<\/script>/gi; + responseText.replace(rscript, ""); // NOT OK + return responseText; +}); + +// CVE-2019-1010091 +(function(text) { + text = text.replace(//gm, ""); // NOT OK + x = x.replace(/\sng-[a-z-]+/, ""); // NOT OK + x = x.replace(/\sng-[a-z-]+/g, ""); // NOT OK (ng-attributes) + + x = x.replace(/()/g, "\n"); // OK: not a sanitizer + + x = x.replace(//g, ""); // OK [INCONSISTENCY] + x = x.replace(/