mirror of
https://github.com/github/codeql.git
synced 2025-12-22 19:56:32 +01:00
Merge branch 'main' into java/experimental/command-injection
This commit is contained in:
@@ -2,3 +2,4 @@ name: codeql-java-consistency-queries
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
codeql/java-all: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -4,3 +4,4 @@ groups:
|
||||
- examples
|
||||
dependencies:
|
||||
codeql/java-all: ${workspace}
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -54,6 +54,9 @@ android {
|
||||
versionName = "1.0"
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable("Instantiatable")
|
||||
}
|
||||
}
|
||||
|
||||
androidComponents {
|
||||
|
||||
@@ -13,6 +13,7 @@ xmlFiles
|
||||
| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml |
|
||||
| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml |
|
||||
| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml |
|
||||
|
||||
@@ -54,6 +54,9 @@ android {
|
||||
versionName = "1.0"
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable("Instantiatable")
|
||||
}
|
||||
}
|
||||
|
||||
androidComponents {
|
||||
|
||||
@@ -13,6 +13,7 @@ xmlFiles
|
||||
| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml |
|
||||
| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml |
|
||||
| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml |
|
||||
|
||||
@@ -55,4 +55,8 @@ android {
|
||||
}
|
||||
|
||||
variantFilter { variant -> if (variant.buildType.name == "debug") { setIgnore(true) } }
|
||||
|
||||
lintOptions {
|
||||
disable "Instantiatable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ xmlFiles
|
||||
| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml |
|
||||
| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml |
|
||||
| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml |
|
||||
|
||||
@@ -55,4 +55,8 @@ android {
|
||||
}
|
||||
|
||||
variantFilter { variant -> if (variant.buildType.name == "debug") { setIgnore(true) } }
|
||||
|
||||
lintOptions {
|
||||
disable "Instantiatable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ xmlFiles
|
||||
| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml |
|
||||
| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml |
|
||||
| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml |
|
||||
|
||||
@@ -2,3 +2,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -5,3 +5,4 @@ dependencies:
|
||||
codeql/java-queries: '*'
|
||||
dataExtensions:
|
||||
ext/*.model.yml
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -5,3 +5,4 @@ dependencies:
|
||||
codeql/java-queries: '*'
|
||||
dataExtensions:
|
||||
ext/*.model.yml
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -3,3 +3,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -3,3 +3,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -3,3 +3,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -2,3 +2,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
name: integrationtest-custom-plugin
|
||||
dependencies:
|
||||
codeql/java-all: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
dependencies:
|
||||
codeql/java-all: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -2,4 +2,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -1,3 +1,61 @@
|
||||
## 0.6.3
|
||||
|
||||
### New Features
|
||||
|
||||
* Kotlin versions up to 1.9.0 are now supported.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow through the block arguments of `kotlin.io.use` and `kotlin.with`.
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.alibaba.druid.sql
|
||||
* com.fasterxml.jackson.databind
|
||||
* com.jcraft.jsch
|
||||
* io.netty.handler.ssl
|
||||
* okhttp3
|
||||
* org.antlr.runtime
|
||||
* org.fusesource.leveldbjni
|
||||
* org.influxdb
|
||||
* org.springframework.core.io
|
||||
* org.yaml.snakeyaml
|
||||
* Deleted the deprecated `getRHS` predicate from the `LValue` class, use `getRhs` instead.
|
||||
* Deleted the deprecated `getCFGNode` predicate from the `SsaVariable` class, use `getCfgNode` instead.
|
||||
* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead.
|
||||
* Added models for the following packages:
|
||||
|
||||
* java.lang
|
||||
* java.nio.file
|
||||
* Added dataflow models for the Gson deserialization library.
|
||||
* Added models for the following packages:
|
||||
|
||||
* okhttp3
|
||||
* Added more dataflow models for the Play Framework.
|
||||
* Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks.
|
||||
* Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`.
|
||||
* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`.
|
||||
* Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname.
|
||||
* Changed the `android-widget` Java source kind to `remote`. Any custom data extensions that use the `android-widget` source kind will need to be updated accordingly in order to continue working.
|
||||
* Updated the following Java sink kind names. Any custom data extensions will need to be updated accordingly in order to continue working.
|
||||
* `sql` to `sql-injection`
|
||||
* `url-redirect` to `url-redirection`
|
||||
* `xpath` to `xpath-injection`
|
||||
* `ssti` to `template-injection`
|
||||
* `logging` to `log-injection`
|
||||
* `groovy` to `groovy-injection`
|
||||
* `jexl` to `jexl-injection`
|
||||
* `mvel` to `mvel-injection`
|
||||
* `xslt` to `xslt-injection`
|
||||
* `ldap` to `ldap-injection`
|
||||
* `pending-intent-sent` to `pending-intents`
|
||||
* `intent-start` to `intent-redirection`
|
||||
* `set-hostname-verifier` to `hostname-verification`
|
||||
* `header-splitting` to `response-splitting`
|
||||
* `xss` to `html-injection` and `js-injection`
|
||||
* `write-file` to `file-system-store`
|
||||
* `create-file` and `read-file` to `path-injection`
|
||||
* `open-url` and `jdbc-url` to `request-forgery`
|
||||
|
||||
## 0.6.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* The `ExecCallable` class in `ExternalProcess.qll` has been deprecated.
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Updated the following Java sink kind names. Any custom data extensions will need to be updated accordingly in order to continue working.
|
||||
* `sql` to `sql-injection`
|
||||
* `url-redirect` to `url-redirection`
|
||||
* `xpath` to `xpath-injection`
|
||||
* `ssti` to `template-injection`
|
||||
* `logging` to `log-injection`
|
||||
* `groovy` to `groovy-injection`
|
||||
* `jexl` to `jexl-injection`
|
||||
* `mvel` to `mvel-injection`
|
||||
* `xslt` to `xslt-injection`
|
||||
* `ldap` to `ldap-injection`
|
||||
* `pending-intent-sent` to `pending-intents`
|
||||
* `intent-start` to `intent-redirection`
|
||||
* `set-hostname-verifier` to `hostname-verification`
|
||||
* `header-splitting` to `response-splitting`
|
||||
* `xss` to `html-injection` and `js-injection`
|
||||
* `write-file` to `file-system-store`
|
||||
* `create-file` and `read-file` to `path-injection`
|
||||
* `open-url` and `jdbc-url` to `request-forgery`
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Changed the `android-widget` Java source kind to `remote`. Any custom data extensions that use the `android-widget` source kind will need to be updated accordingly in order to continue working.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`.
|
||||
4
java/ql/lib/change-notes/2023-05-22-stapler-models.md
Normal file
4
java/ql/lib/change-notes/2023-05-22-stapler-models.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added more models for the Stapler framework.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Kotlin versions up to 1.9.0 are now supported.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added more dataflow models for the Play Framework.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added dataflow models for the Gson deserialization library.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for the following packages:
|
||||
|
||||
* okhttp3
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for the following packages:
|
||||
|
||||
* java.lang
|
||||
* java.nio.file
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Deleted the deprecated `getRHS` predicate from the `LValue` class, use `getRhs` instead.
|
||||
* Deleted the deprecated `getCFGNode` predicate from the `SsaVariable` class, use `getCfgNode` instead.
|
||||
* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added flow through the block arguments of `kotlin.io.use` and `kotlin.with`.
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.alibaba.druid.sql
|
||||
* com.fasterxml.jackson.databind
|
||||
* com.jcraft.jsch
|
||||
* io.netty.handler.ssl
|
||||
* okhttp3
|
||||
* org.antlr.runtime
|
||||
* org.fusesource.leveldbjni
|
||||
* org.influxdb
|
||||
* org.springframework.core.io
|
||||
* org.yaml.snakeyaml
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added a missing summary model for the method `java.net.URL.toString`.
|
||||
57
java/ql/lib/change-notes/released/0.6.3.md
Normal file
57
java/ql/lib/change-notes/released/0.6.3.md
Normal file
@@ -0,0 +1,57 @@
|
||||
## 0.6.3
|
||||
|
||||
### New Features
|
||||
|
||||
* Kotlin versions up to 1.9.0 are now supported.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow through the block arguments of `kotlin.io.use` and `kotlin.with`.
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.alibaba.druid.sql
|
||||
* com.fasterxml.jackson.databind
|
||||
* com.jcraft.jsch
|
||||
* io.netty.handler.ssl
|
||||
* okhttp3
|
||||
* org.antlr.runtime
|
||||
* org.fusesource.leveldbjni
|
||||
* org.influxdb
|
||||
* org.springframework.core.io
|
||||
* org.yaml.snakeyaml
|
||||
* Deleted the deprecated `getRHS` predicate from the `LValue` class, use `getRhs` instead.
|
||||
* Deleted the deprecated `getCFGNode` predicate from the `SsaVariable` class, use `getCfgNode` instead.
|
||||
* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead.
|
||||
* Added models for the following packages:
|
||||
|
||||
* java.lang
|
||||
* java.nio.file
|
||||
* Added dataflow models for the Gson deserialization library.
|
||||
* Added models for the following packages:
|
||||
|
||||
* okhttp3
|
||||
* Added more dataflow models for the Play Framework.
|
||||
* Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks.
|
||||
* Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`.
|
||||
* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`.
|
||||
* Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname.
|
||||
* Changed the `android-widget` Java source kind to `remote`. Any custom data extensions that use the `android-widget` source kind will need to be updated accordingly in order to continue working.
|
||||
* Updated the following Java sink kind names. Any custom data extensions will need to be updated accordingly in order to continue working.
|
||||
* `sql` to `sql-injection`
|
||||
* `url-redirect` to `url-redirection`
|
||||
* `xpath` to `xpath-injection`
|
||||
* `ssti` to `template-injection`
|
||||
* `logging` to `log-injection`
|
||||
* `groovy` to `groovy-injection`
|
||||
* `jexl` to `jexl-injection`
|
||||
* `mvel` to `mvel-injection`
|
||||
* `xslt` to `xslt-injection`
|
||||
* `ldap` to `ldap-injection`
|
||||
* `pending-intent-sent` to `pending-intents`
|
||||
* `intent-start` to `intent-redirection`
|
||||
* `set-hostname-verifier` to `hostname-verification`
|
||||
* `header-splitting` to `response-splitting`
|
||||
* `xss` to `html-injection` and `js-injection`
|
||||
* `write-file` to `file-system-store`
|
||||
* `create-file` and `read-file` to `path-injection`
|
||||
* `open-url` and `jdbc-url` to `request-forgery`
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.2
|
||||
lastReleaseVersion: 0.6.3
|
||||
|
||||
@@ -1219,6 +1219,7 @@ ktSyntheticBody(
|
||||
int kind: int ref
|
||||
// 1: ENUM_VALUES
|
||||
// 2: ENUM_VALUEOF
|
||||
// 3: ENUM_ENTRIES
|
||||
)
|
||||
|
||||
ktLocalFunction(
|
||||
|
||||
6
java/ql/lib/ext/experimental/com.jcraft.jsch.model.yml
Normal file
6
java/ql/lib/ext/experimental/com.jcraft.jsch.model.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: experimentalSinkModel
|
||||
data:
|
||||
- ["com.jcraft.jsch", "ChannelExec", True, "setCommand", "", "", "Argument[0]", "command-injection", "manual", "jsch-os-injection"]
|
||||
1695
java/ql/lib/ext/generated/org.apache.commons.lang.model.yml
Normal file
1695
java/ql/lib/ext/generated/org.apache.commons.lang.model.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -8,30 +8,30 @@ extensions:
|
||||
- ["java.lang", "ClassLoader", True, "getSystemResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"]
|
||||
- ["java.lang", "ClassLoader", True, "getSystemResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"]
|
||||
- ["java.lang", "Module", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"]
|
||||
- ["java.lang", "ProcessBuilder", False, "command", "(List)", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["java.lang", "ProcessBuilder", False, "command", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "ProcessBuilder", False, "directory", "(File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "ProcessBuilder", False, "ProcessBuilder", "(List)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "ProcessBuilder", False, "ProcessBuilder", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String[],String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String[],String[],File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String[],String[],File)", "", "Argument[2]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String,String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String,String[],File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String,String[],File)", "", "Argument[2]", "command-injection", "ai-manual"]
|
||||
# These are potential vulnerabilities, but not for command-injection. No query for this kind of vulnerability currently exists.
|
||||
# - ["java.lang", "Runtime", False, "load", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", False, "loadLibrary", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# These are modeled in plain CodeQL. TODO: migrate them.
|
||||
# - ["java.lang", "ProcessBuilder", False, "command", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "ProcessBuilder", False, "directory", "(File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "ProcessBuilder", False, "ProcessBuilder", "(List)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "ProcessBuilder", False, "ProcessBuilder", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String,String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String[],String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String,String[],File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String,String[],File)", "", "Argument[2]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String[],String[],File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String[],String[],File)", "", "Argument[2]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "String", False, "matches", "(String)", "", "Argument[0]", "regex-use[f-1]", "manual"]
|
||||
- ["java.lang", "String", False, "replaceAll", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"]
|
||||
- ["java.lang", "String", False, "replaceFirst", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"]
|
||||
- ["java.lang", "String", False, "split", "(String)", "", "Argument[0]", "regex-use[-1]", "manual"]
|
||||
- ["java.lang", "String", False, "split", "(String,int)", "", "Argument[0]", "regex-use[-1]", "manual"]
|
||||
# These are modeled in plain CodeQL. TODO: migrate them.
|
||||
# - ["java.lang", "System", False, "load", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] # This is actually injecting a library.
|
||||
# - ["java.lang", "System", False, "loadLibrary", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] # This is actually injecting a library.
|
||||
# These are potential vulnerabilities, but not for command-injection. No query for this kind of vulnerability currently exists.
|
||||
# - ["java.lang", "System", False, "load", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "System", False, "loadLibrary", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "System$Logger", True, "log", "(Level,Object)", "", "Argument[1]", "log-injection", "manual"]
|
||||
- ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Object[])", "", "Argument[2..3]", "log-injection", "manual"]
|
||||
- ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Throwable)", "", "Argument[2]", "log-injection", "manual"]
|
||||
|
||||
@@ -45,7 +45,8 @@ extensions:
|
||||
- ["java.net", "URI", False, "toURL", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.net", "URL", False, "URL", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["java.net", "URL", False, "URL", "(URL,String)", "", "Argument[0]", "Argument[this]", "taint", "ai-manual"]
|
||||
- ["java.net", "URL", False, "URL", "(URL,String)", "", "Argument[1]", "Argument[this]", "taint", "ai-manual"] # @atorralba: review for consistency
|
||||
- ["java.net", "URL", False, "URL", "(URL,String)", "", "Argument[1]", "Argument[this]", "taint", "ai-manual"]
|
||||
- ["java.net", "URL", False, "toExternalForm", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.net", "URL", False, "toURI", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.net", "URL", False, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.net", "URLDecoder", False, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
|
||||
11
java/ql/lib/ext/org.apache.commons.exec.model.yml
Normal file
11
java/ql/lib/ext/org.apache.commons.exec.model.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "parse", "(String)", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "parse", "(String,Map)", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "addArguments", "(String)", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "addArguments", "(String,boolean)", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "addArguments", "(String[])", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "addArguments", "(String[],boolean)", "", "Argument[0]", "command-injection", "manual"]
|
||||
6
java/ql/lib/ext/org.kohsuke.stapler.bind.model.yml
Normal file
6
java/ql/lib/ext/org.kohsuke.stapler.bind.model.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["org.kohsuke.stapler.bind", "JavaScriptMethod", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
7
java/ql/lib/ext/org.kohsuke.stapler.json.model.yml
Normal file
7
java/ql/lib/ext/org.kohsuke.stapler.json.model.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["org.kohsuke.stapler.json", "SubmittedForm", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler.json", "JsonBody", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
@@ -4,4 +4,46 @@ extensions:
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "redirectTo", "(String)", "", "Argument[0]", "url-redirection", "ai-manual"]
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "redirectTo", "(int,String)", "", "Argument[1]", "url-redirection", "manual"]
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "staticResource", "(URL)", "", "Argument[0]", "request-forgery", "ai-manual"]
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "staticResource", "(URL,long)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "html", "(String)", "", "Argument[0]", "html-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "literalHtml", "(String)", "", "Argument[0]", "html-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "forward", "(Object,String,StaplerRequest)", "", "Argument[1]", "request-forgery", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "sendRedirect2", "(String)", "", "Argument[0]", "url-redirection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "sendRedirect", "(int,String)", "", "Argument[1]", "url-redirection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "sendRedirect", "(String)", "", "Argument[0]", "url-redirection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,URL)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,URL,long)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveLocalizedFile", "(StaplerRequest,URL)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveLocalizedFile", "(StaplerRequest,URL,long)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,long,long,String)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,long,int,String)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,long,String)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,int,String)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "reverseProxyTo", "(URL,StaplerRequest)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getRequestURIWithQueryString", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getRequestURLWithQueryString", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getReferer", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getOriginalRequestURI", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getSubmittedForm", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getFileItem", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindParametersToList", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindParameters", "", "", "Argument[0]", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindParameters", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindJSON", "", "", "Argument[0]", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindJSON", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindJSONToList", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getParameter", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getParameterMap", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getParameterNames", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getParameterValues", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getRestOfPath", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "QueryParameter", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "Header", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "DataBoundConstructor", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "DataBoundSetter", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
name: codeql/java-all
|
||||
version: 0.6.3-dev
|
||||
version: 0.6.4-dev
|
||||
groups: java
|
||||
dbscheme: config/semmlecode.dbscheme
|
||||
extractor: java
|
||||
library: true
|
||||
upgrades: upgrades
|
||||
dependencies:
|
||||
codeql/mad: ${workspace}
|
||||
codeql/regex: ${workspace}
|
||||
codeql/tutorial: ${workspace}
|
||||
codeql/typetracking: ${workspace}
|
||||
|
||||
@@ -199,18 +199,18 @@ class TypeFile extends Class {
|
||||
|
||||
// --- Standard methods ---
|
||||
/**
|
||||
* Any constructor of class `java.lang.ProcessBuilder`.
|
||||
* DEPRECATED: Any constructor of class `java.lang.ProcessBuilder`.
|
||||
*/
|
||||
class ProcessBuilderConstructor extends Constructor, ExecCallable {
|
||||
deprecated class ProcessBuilderConstructor extends Constructor, ExecCallable {
|
||||
ProcessBuilderConstructor() { this.getDeclaringType() instanceof TypeProcessBuilder }
|
||||
|
||||
override int getAnExecutedArgument() { result = 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* Any of the methods named `command` on class `java.lang.ProcessBuilder`.
|
||||
* DEPRECATED: Any of the methods named `command` on class `java.lang.ProcessBuilder`.
|
||||
*/
|
||||
class MethodProcessBuilderCommand extends Method, ExecCallable {
|
||||
deprecated class MethodProcessBuilderCommand extends Method, ExecCallable {
|
||||
MethodProcessBuilderCommand() {
|
||||
this.hasName("command") and
|
||||
this.getDeclaringType() instanceof TypeProcessBuilder
|
||||
@@ -220,9 +220,9 @@ class MethodProcessBuilderCommand extends Method, ExecCallable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Any method named `exec` on class `java.lang.Runtime`.
|
||||
* DEPRECATED: Any method named `exec` on class `java.lang.Runtime`.
|
||||
*/
|
||||
class MethodRuntimeExec extends Method, ExecCallable {
|
||||
deprecated class MethodRuntimeExec extends Method, ExecCallable {
|
||||
MethodRuntimeExec() {
|
||||
this.hasName("exec") and
|
||||
this.getDeclaringType() instanceof TypeRuntime
|
||||
|
||||
@@ -87,6 +87,7 @@ private import internal.FlowSummaryImplSpecific as FlowSummaryImplSpecific
|
||||
private import internal.AccessPathSyntax
|
||||
private import ExternalFlowExtensions as Extensions
|
||||
private import FlowSummary
|
||||
private import codeql.mad.ModelValidation as SharedModelVal
|
||||
|
||||
/**
|
||||
* A class for activating additional model rows.
|
||||
@@ -265,86 +266,17 @@ module ModelValidation {
|
||||
)
|
||||
}
|
||||
|
||||
private class OutdatedSinkKind extends string {
|
||||
OutdatedSinkKind() {
|
||||
this =
|
||||
[
|
||||
"sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt",
|
||||
"ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier",
|
||||
"header-splitting", "xss", "write-file", "create-file", "read-file", "open-url",
|
||||
"jdbc-url"
|
||||
]
|
||||
}
|
||||
private module KindValConfig implements SharedModelVal::KindValidationConfigSig {
|
||||
predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) }
|
||||
|
||||
private string replacementKind() {
|
||||
this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap"] and
|
||||
result = this + "-injection"
|
||||
or
|
||||
this = "url-redirect" and result = "url-redirection"
|
||||
or
|
||||
this = "ssti" and result = "template-injection"
|
||||
or
|
||||
this = "logging" and result = "log-injection"
|
||||
or
|
||||
this = "pending-intent-sent" and result = "pending-intents"
|
||||
or
|
||||
this = "intent-start" and result = "intent-redirection"
|
||||
or
|
||||
this = "set-hostname-verifier" and result = "hostname-verification"
|
||||
or
|
||||
this = "header-splitting" and result = "response-splitting"
|
||||
or
|
||||
this = "xss" and result = "html-injection\" or \"js-injection"
|
||||
or
|
||||
this = "write-file" and result = "file-content-store"
|
||||
or
|
||||
this = ["create-file", "read-file"] and result = "path-injection"
|
||||
or
|
||||
this = ["open-url", "jdbc-url"] and result = "request-forgery"
|
||||
}
|
||||
predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) }
|
||||
|
||||
string outdatedMessage() {
|
||||
result =
|
||||
"The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead."
|
||||
}
|
||||
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) }
|
||||
|
||||
predicate neutralKind(string kind) { neutralModel(_, _, _, _, kind, _) }
|
||||
}
|
||||
|
||||
private string getInvalidModelKind() {
|
||||
exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) |
|
||||
not kind = ["taint", "value"] and
|
||||
result = "Invalid kind \"" + kind + "\" in summary model."
|
||||
)
|
||||
or
|
||||
exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) |
|
||||
not kind =
|
||||
[
|
||||
"request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection",
|
||||
"mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection",
|
||||
"ognl-injection", "intent-redirection", "pending-intents", "url-redirection",
|
||||
"path-injection", "file-content-store", "hostname-verification", "response-splitting",
|
||||
"information-leak", "xslt-injection", "jexl-injection", "bean-validation",
|
||||
"template-injection", "fragment-injection", "command-injection"
|
||||
] and
|
||||
not kind.matches("regex-use%") and
|
||||
not kind.matches("qltest%") and
|
||||
msg = "Invalid kind \"" + kind + "\" in sink model." and
|
||||
// The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024.
|
||||
if kind instanceof OutdatedSinkKind
|
||||
then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage()
|
||||
else result = msg
|
||||
)
|
||||
or
|
||||
exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) |
|
||||
not kind = ["remote", "contentprovider", "android-external-storage-dir"] and
|
||||
not kind.matches("qltest%") and
|
||||
result = "Invalid kind \"" + kind + "\" in source model."
|
||||
)
|
||||
or
|
||||
exists(string kind | neutralModel(_, _, _, _, kind, _) |
|
||||
not kind = ["summary", "source", "sink"] and
|
||||
result = "Invalid kind \"" + kind + "\" in neutral model."
|
||||
)
|
||||
}
|
||||
private module KindVal = SharedModelVal::KindValidation<KindValConfig>;
|
||||
|
||||
private string getInvalidModelSignature() {
|
||||
exists(
|
||||
@@ -387,7 +319,7 @@ module ModelValidation {
|
||||
msg =
|
||||
[
|
||||
getInvalidModelSignature(), getInvalidModelInput(), getInvalidModelOutput(),
|
||||
getInvalidModelKind()
|
||||
KindVal::getInvalidModelKind()
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ abstract class RemoteFlowSource extends DataFlow::Node {
|
||||
*/
|
||||
private module FlowSources {
|
||||
private import semmle.code.java.frameworks.hudson.Hudson
|
||||
private import semmle.code.java.frameworks.stapler.Stapler
|
||||
}
|
||||
|
||||
private class ExternalRemoteFlowSource extends RemoteFlowSource {
|
||||
|
||||
@@ -23,6 +23,7 @@ private module Frameworks {
|
||||
private import semmle.code.java.frameworks.Properties
|
||||
private import semmle.code.java.frameworks.Protobuf
|
||||
private import semmle.code.java.frameworks.ratpack.RatpackExec
|
||||
private import semmle.code.java.frameworks.stapler.Stapler
|
||||
private import semmle.code.java.JDK
|
||||
}
|
||||
|
||||
|
||||
@@ -2021,7 +2021,8 @@ module Impl<FullStateConfigSig Config> {
|
||||
FlowCheckNode() {
|
||||
castNode(this.asNode()) or
|
||||
clearsContentCached(this.asNode(), _) or
|
||||
expectsContentCached(this.asNode(), _)
|
||||
expectsContentCached(this.asNode(), _) or
|
||||
neverSkipInPathGraph(this.asNode())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -242,6 +242,12 @@ class CastNode extends ExprNode {
|
||||
CastNode() { this.getExpr() instanceof CastingExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` should never be skipped over in the `PathGraph` and in path
|
||||
* explanations.
|
||||
*/
|
||||
predicate neverSkipInPathGraph(Node n) { none() }
|
||||
|
||||
private newtype TDataFlowCallable =
|
||||
TSrcCallable(Callable c) or
|
||||
TSummarizedCallable(SummarizedCallable c) or
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/** Definitions related to the Apache Commons Exec library. */
|
||||
|
||||
import semmle.code.java.Type
|
||||
import semmle.code.java.security.ExternalProcess
|
||||
|
||||
/** The class `org.apache.commons.exec.CommandLine`. */
|
||||
private class TypeCommandLine extends Class {
|
||||
TypeCommandLine() { this.hasQualifiedName("org.apache.commons.exec", "CommandLine") }
|
||||
}
|
||||
|
||||
/** The `parse()` method of the class `org.apache.commons.exec.CommandLine`. */
|
||||
private class MethodCommandLineParse extends Method, ExecCallable {
|
||||
MethodCommandLineParse() {
|
||||
this.getDeclaringType() instanceof TypeCommandLine and
|
||||
this.hasName("parse")
|
||||
}
|
||||
|
||||
override int getAnExecutedArgument() { result = 0 }
|
||||
}
|
||||
|
||||
/** The `addArguments()` method of the class `org.apache.commons.exec.CommandLine`. */
|
||||
private class MethodCommandLineAddArguments extends Method, ExecCallable {
|
||||
MethodCommandLineAddArguments() {
|
||||
this.getDeclaringType() instanceof TypeCommandLine and
|
||||
this.hasName("addArguments")
|
||||
}
|
||||
|
||||
override int getAnExecutedArgument() { result = 0 }
|
||||
}
|
||||
@@ -2,8 +2,17 @@
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.FlowSources
|
||||
private import semmle.code.java.frameworks.stapler.Stapler
|
||||
private import semmle.code.java.security.XSS
|
||||
|
||||
/** A method declared in a subtype of `hudson.model.Descriptor` that returns an `HttpResponse`. */
|
||||
class HudsonWebMethod extends Method {
|
||||
HudsonWebMethod() {
|
||||
this.getReturnType().(RefType).getASourceSupertype*() instanceof HttpResponse and
|
||||
this.getDeclaringType().getASourceSupertype*().hasQualifiedName("hudson.model", "Descriptor")
|
||||
}
|
||||
}
|
||||
|
||||
private class FilePathRead extends LocalUserInput {
|
||||
FilePathRead() {
|
||||
this.asExpr()
|
||||
|
||||
124
java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll
Normal file
124
java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll
Normal file
@@ -0,0 +1,124 @@
|
||||
/** Provides classes and predicates related to the Stapler framework. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.dataflow.FlowSources
|
||||
private import semmle.code.java.dataflow.FlowSteps
|
||||
private import semmle.code.java.dataflow.TypeFlow
|
||||
private import semmle.code.java.frameworks.hudson.Hudson
|
||||
private import semmle.code.java.frameworks.JavaxAnnotations
|
||||
|
||||
/**
|
||||
* A callable annotated with a Stapler `DataBound` annotation,
|
||||
* or that has the `@stapler-constructor` Javadoc annotation.
|
||||
*/
|
||||
class DataBoundAnnotated extends Callable {
|
||||
DataBoundAnnotated() {
|
||||
exists(Annotation an |
|
||||
an.getType()
|
||||
.hasQualifiedName("org.kohsuke.stapler", ["DataBoundConstructor", "DataBoundSetter"])
|
||||
|
|
||||
this = an.getAnnotatedElement()
|
||||
)
|
||||
or
|
||||
exists(Javadoc doc | doc.getAChild().getText().matches("%@stapler-constructor%") |
|
||||
doc.getCommentedElement() = this
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The interface `org.kohsuke.stapler.HttpResponse`. */
|
||||
class HttpResponse extends Interface {
|
||||
HttpResponse() { this.hasQualifiedName("org.kohsuke.stapler", "HttpResponse") }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remote flow source for parameters annotated with an annotation
|
||||
* that is itself annotated with `InjectedParameter`.
|
||||
*
|
||||
* Such parameters are populated with user-provided data by Stapler.
|
||||
*/
|
||||
private class InjectedParameterSource extends RemoteFlowSource {
|
||||
InjectedParameterSource() {
|
||||
this.asParameter().getAnAnnotation().getType() instanceof InjectedParameterAnnotatedType
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "Stapler injected parameter" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A dataflow step from the `HttpResponse` return value of a `HudsonWebMethod`
|
||||
* to the instance parameter of the `generateResponse` method of the appropriate subtype of `HttpResponse`.
|
||||
*
|
||||
* This models the rendering process of an `HttpResponse` by Stapler.
|
||||
*/
|
||||
private class HttpResponseGetDescriptionStep extends AdditionalValueStep {
|
||||
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(ReturnStmt s, GenerateResponseMethod m |
|
||||
s.getEnclosingCallable() instanceof HudsonWebMethod and
|
||||
boundOrStaticType(s.getResult(), m.getDeclaringType().getADescendant())
|
||||
|
|
||||
n1.asExpr() = s.getResult() and
|
||||
n2.(DataFlow::InstanceParameterNode).getCallable() = m
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A dataflow step from the post-update node of an instance access in a `DataBoundAnnotated` method
|
||||
* to the instance parameter of a `PostConstruct` method of the same type.
|
||||
*
|
||||
* This models the construction process of a `DataBound` object in Stapler.
|
||||
*/
|
||||
private class PostConstructDataBoundAdditionalStep extends AdditionalValueStep {
|
||||
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(PostConstructDataBoundMethod postConstruct, DataBoundAnnotated input |
|
||||
postConstruct.getDeclaringType() = input.getDeclaringType()
|
||||
|
|
||||
n1.(DataFlow::PostUpdateNode)
|
||||
.getPreUpdateNode()
|
||||
.(DataFlow::InstanceAccessNode)
|
||||
.getEnclosingCallable() = input and
|
||||
n2.(DataFlow::InstanceParameterNode).getCallable() = postConstruct
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** An annotation type annotated with the `InjectedParameter` annotation. */
|
||||
private class InjectedParameterAnnotatedType extends AnnotationType {
|
||||
InjectedParameterAnnotatedType() {
|
||||
this.getAnAnnotation().getType().hasQualifiedName("org.kohsuke.stapler", "InjectedParameter")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `generateResponse` method of `org.kohsuke.stapler.HttpResponse` or its subtypes. */
|
||||
private class GenerateResponseMethod extends Method {
|
||||
GenerateResponseMethod() {
|
||||
this.getDeclaringType().getASourceSupertype*() instanceof HttpResponse and
|
||||
this.hasName("generateResponse")
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if `t` is the static type of `e`, or an upper bound of the runtime type of `e`. */
|
||||
private predicate boundOrStaticType(Expr e, RefType t) {
|
||||
exprTypeFlow(e, t, false)
|
||||
or
|
||||
t = e.getType()
|
||||
}
|
||||
|
||||
/**
|
||||
* A method called after the construction of a `DataBound` object.
|
||||
*
|
||||
* That is, either the `bindResolve` method of a subtype of `org.kohsuke.stapler.DataBoundResolvable`,
|
||||
* or a method annotated with `javax.annotation.PostConstruct`.
|
||||
*/
|
||||
private class PostConstructDataBoundMethod extends Method {
|
||||
PostConstructDataBoundMethod() {
|
||||
this.getDeclaringType()
|
||||
.getASourceSupertype*()
|
||||
.hasQualifiedName("org.kohsuke.stapler", "DataBoundResolvable") and
|
||||
this.hasName("bindResolve")
|
||||
or
|
||||
this.getAnAnnotation() instanceof PostConstructAnnotation
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
import java
|
||||
private import semmle.code.java.dataflow.FlowSources
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
private import semmle.code.java.security.ExternalProcess
|
||||
private import semmle.code.java.security.CommandArguments
|
||||
private import semmle.code.java.security.ExternalProcess
|
||||
|
||||
/** A sink for command injection vulnerabilities. */
|
||||
abstract class CommandInjectionSink extends DataFlow::Node { }
|
||||
@@ -33,9 +33,7 @@ class CommandInjectionAdditionalTaintStep extends Unit {
|
||||
}
|
||||
|
||||
private class DefaultCommandInjectionSink extends CommandInjectionSink {
|
||||
DefaultCommandInjectionSink() {
|
||||
this.asExpr() instanceof ArgumentToExec or sinkNode(this, "command-injection")
|
||||
}
|
||||
DefaultCommandInjectionSink() { sinkNode(this, "command-injection") }
|
||||
}
|
||||
|
||||
private class DefaultCommandInjectionSanitizer extends CommandInjectionSanitizer {
|
||||
@@ -100,7 +98,7 @@ predicate execIsTainted(
|
||||
RemoteUserInputToArgumentToExecFlow::PathNode sink, Expr execArg
|
||||
) {
|
||||
RemoteUserInputToArgumentToExecFlow::flowPath(source, sink) and
|
||||
sink.getNode().asExpr() = execArg
|
||||
argumentToExec(execArg, sink.getNode())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,7 +110,7 @@ predicate execIsTainted(
|
||||
*/
|
||||
deprecated predicate execTainted(DataFlow::PathNode source, DataFlow::PathNode sink, Expr execArg) {
|
||||
exists(RemoteUserInputToArgumentToExecFlowConfig conf |
|
||||
conf.hasFlowPath(source, sink) and sink.getNode().asExpr() = execArg
|
||||
conf.hasFlowPath(source, sink) and argumentToExec(execArg, sink.getNode())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
/** Definitions related to external processes. */
|
||||
|
||||
import semmle.code.java.Member
|
||||
|
||||
private module Instances {
|
||||
private import semmle.code.java.JDK
|
||||
private import semmle.code.java.frameworks.apache.Exec
|
||||
}
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.security.CommandLineQuery
|
||||
|
||||
/**
|
||||
* A callable that executes a command.
|
||||
* DEPRECATED: A callable that executes a command.
|
||||
*/
|
||||
abstract class ExecCallable extends Callable {
|
||||
abstract deprecated class ExecCallable extends Callable {
|
||||
/**
|
||||
* Gets the index of an argument that will be part of the command that is executed.
|
||||
*/
|
||||
@@ -23,13 +20,19 @@ abstract class ExecCallable extends Callable {
|
||||
* to be executed.
|
||||
*/
|
||||
class ArgumentToExec extends Expr {
|
||||
ArgumentToExec() {
|
||||
exists(Call execCall, ExecCallable execCallable, int i |
|
||||
execCall.getArgument(pragma[only_bind_into](i)) = this and
|
||||
execCallable = execCall.getCallee() and
|
||||
i = execCallable.getAnExecutedArgument()
|
||||
)
|
||||
}
|
||||
ArgumentToExec() { argumentToExec(this, _) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `e` is an expression used as an argument to a call that executes an external command.
|
||||
* For calls to varargs method calls, this only includes the first argument, which will be the command
|
||||
* to be executed.
|
||||
*/
|
||||
predicate argumentToExec(Expr e, CommandInjectionSink s) {
|
||||
s.asExpr() = e
|
||||
or
|
||||
e.(Argument).isNthVararg(0) and
|
||||
s.(DataFlow::ImplicitVarargsArray).getCall() = e.(Argument).getCall()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,6 @@ private import semmle.code.java.dataflow.ExternalFlow
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.security.SensitiveActions
|
||||
import semmle.code.java.frameworks.android.Compose
|
||||
import DataFlow
|
||||
|
||||
/** A variable that may hold sensitive information, judging by its name. */
|
||||
class CredentialExpr extends Expr {
|
||||
@@ -45,7 +44,7 @@ deprecated class SensitiveLoggerConfiguration extends TaintTracking::Configurati
|
||||
sanitizer.getType() instanceof TypeType
|
||||
}
|
||||
|
||||
override predicate isSanitizerIn(Node node) { this.isSource(node) }
|
||||
override predicate isSanitizerIn(DataFlow::Node node) { this.isSource(node) }
|
||||
}
|
||||
|
||||
/** A data-flow configuration for identifying potentially-sensitive data flowing to a log output. */
|
||||
@@ -62,7 +61,7 @@ module SensitiveLoggerConfig implements DataFlow::ConfigSig {
|
||||
sanitizer.getType() instanceof TypeType
|
||||
}
|
||||
|
||||
predicate isBarrierIn(Node node) { isSource(node) }
|
||||
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
|
||||
}
|
||||
|
||||
module SensitiveLoggerFlow = TaintTracking::Global<SensitiveLoggerConfig>;
|
||||
|
||||
@@ -28,6 +28,20 @@ private class ObjectInputStreamReadObjectMethod extends Method {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A type extending `ObjectInputStream` that makes it safe to deserialize untrusted data.
|
||||
*
|
||||
* * See https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/serialization/ValidatingObjectInputStream.html
|
||||
* * See https://github.com/ikkisoft/SerialKiller
|
||||
*/
|
||||
private class SafeObjectInputStreamType extends RefType {
|
||||
SafeObjectInputStreamType() {
|
||||
this.getASourceSupertype*()
|
||||
.hasQualifiedName("org.apache.commons.io.serialization", "ValidatingObjectInputStream") or
|
||||
this.getASourceSupertype*().hasQualifiedName("org.nibblesec.tools", "SerialKiller")
|
||||
}
|
||||
}
|
||||
|
||||
private class XmlDecoderReadObjectMethod extends Method {
|
||||
XmlDecoderReadObjectMethod() {
|
||||
this.getDeclaringType().hasQualifiedName("java.beans", "XMLDecoder") and
|
||||
@@ -135,9 +149,7 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) {
|
||||
sink = ma.getQualifier() and
|
||||
not exists(DataFlow::ExprNode node |
|
||||
node.getExpr() = sink and
|
||||
node.getTypeBound()
|
||||
.(RefType)
|
||||
.hasQualifiedName("org.apache.commons.io.serialization", "ValidatingObjectInputStream")
|
||||
node.getTypeBound() instanceof SafeObjectInputStreamType
|
||||
)
|
||||
or
|
||||
m instanceof XmlDecoderReadObjectMethod and
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add ENUM_ENTRIES
|
||||
compatibility: full
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.6.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `java/summary/lines-of-code` query now only counts lines of Java code. The new `java/summary/lines-of-code-kotlin` counts lines of Kotlin code.
|
||||
|
||||
## 0.6.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -3,17 +3,15 @@
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Extracting files from a malicious zip archive (or another archive format)
|
||||
without validating that the destination file path
|
||||
is within the destination directory can cause files outside the destination directory to be
|
||||
overwritten, due to the possible presence of directory traversal elements (<code>..</code>) in
|
||||
archive paths.</p>
|
||||
<p>Extracting files from a malicious zip file, or similar type of archive,
|
||||
is at risk of directory traversal attacks if filenames from the archive are
|
||||
not properly validated.</p>
|
||||
|
||||
<p>Zip archives contain archive entries representing each file in the archive. These entries
|
||||
include a file path for the entry, but these file paths are not restricted and may contain
|
||||
unexpected special elements such as the directory traversal element (<code>..</code>). If these
|
||||
file paths are used to determine an output file to write the contents of the archive item to, then
|
||||
the file may be written to an unexpected location. This can result in sensitive information being
|
||||
file paths are used to create a filesystem path, then a file operation may happen in an
|
||||
unexpected location. This can result in sensitive information being
|
||||
revealed or deleted, or an attacker being able to influence behavior by modifying unexpected
|
||||
files.</p>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @name Arbitrary file write during archive extraction ("Zip Slip")
|
||||
* @description Extracting files from a malicious archive without validating that the
|
||||
* destination file path is within the destination directory can cause files outside
|
||||
* the destination directory to be overwritten.
|
||||
* @name Arbitrary file access during archive extraction ("Zip Slip")
|
||||
* @description Extracting files from a malicious ZIP file, or similar type of archive, without
|
||||
* validating that the destination file path is within the destination directory
|
||||
* can allow an attacker to unexpectedly gain access to resources.
|
||||
* @kind path-problem
|
||||
* @id java/zipslip
|
||||
* @problem.severity error
|
||||
|
||||
@@ -14,11 +14,14 @@
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.CommandLineQuery
|
||||
import semmle.code.java.security.ExternalProcess
|
||||
import LocalUserInputToArgumentToExecFlow::PathGraph
|
||||
|
||||
from
|
||||
LocalUserInputToArgumentToExecFlow::PathNode source,
|
||||
LocalUserInputToArgumentToExecFlow::PathNode sink
|
||||
where LocalUserInputToArgumentToExecFlow::flowPath(source, sink)
|
||||
select sink.getNode().asExpr(), source, sink, "This command line depends on a $@.",
|
||||
source.getNode(), "user-provided value"
|
||||
LocalUserInputToArgumentToExecFlow::PathNode sink, Expr e
|
||||
where
|
||||
LocalUserInputToArgumentToExecFlow::flowPath(source, sink) and
|
||||
argumentToExec(e, sink.getNode())
|
||||
select e, source, sink, "This command line depends on a $@.", source.getNode(),
|
||||
"user-provided value"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.CommandLineQuery
|
||||
import semmle.code.java.security.ExternalProcess
|
||||
|
||||
/**
|
||||
* Strings that are known to be sane by some simple local analysis. Such strings
|
||||
|
||||
@@ -59,13 +59,13 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
|
||||
e.getType() instanceof NumberType
|
||||
)
|
||||
or
|
||||
t instanceof AutomodelEndpointTypes::TaintedPathSinkType and
|
||||
t instanceof AutomodelEndpointTypes::PathInjectionSinkType and
|
||||
e instanceof PathSanitizer::PathInjectionSanitizer
|
||||
}
|
||||
|
||||
RelatedLocation asLocation(Endpoint e) { result = e.asExpr() }
|
||||
|
||||
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/3;
|
||||
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/2;
|
||||
|
||||
predicate isSink(Endpoint e, string kind) {
|
||||
exists(string package, string type, string name, string signature, string ext, string input |
|
||||
@@ -79,7 +79,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
|
||||
predicate isNeutral(Endpoint e) {
|
||||
exists(string package, string type, string name, string signature |
|
||||
sinkSpec(e, package, type, name, signature, _, _) and
|
||||
ExternalFlow::neutralModel(package, type, name, [signature, ""], _, _)
|
||||
ExternalFlow::neutralModel(package, type, name, [signature, ""], "sink", _)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -40,18 +40,18 @@ class NegativeSinkType extends SinkType {
|
||||
}
|
||||
|
||||
/** A sink relevant to the SQL injection query */
|
||||
class SqlSinkType extends SinkType {
|
||||
SqlSinkType() { this = "sql" }
|
||||
class SqlInjectionSinkType extends SinkType {
|
||||
SqlInjectionSinkType() { this = "sql-injection" }
|
||||
}
|
||||
|
||||
/** A sink relevant to the tainted path injection query. */
|
||||
class TaintedPathSinkType extends SinkType {
|
||||
TaintedPathSinkType() { this = "tainted-path" }
|
||||
class PathInjectionSinkType extends SinkType {
|
||||
PathInjectionSinkType() { this = "path-injection" }
|
||||
}
|
||||
|
||||
/** A sink relevant to the SSRF query. */
|
||||
class RequestForgerySinkType extends SinkType {
|
||||
RequestForgerySinkType() { this = "ssrf" }
|
||||
RequestForgerySinkType() { this = "request-forgery" }
|
||||
}
|
||||
|
||||
/** A sink relevant to the command injection query. */
|
||||
|
||||
@@ -48,7 +48,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
|
||||
|
||||
RelatedLocation asLocation(Endpoint e) { result = e.asParameter() }
|
||||
|
||||
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/3;
|
||||
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/2;
|
||||
|
||||
predicate isSink(Endpoint e, string kind) {
|
||||
exists(string package, string type, string name, string signature, string ext, string input |
|
||||
@@ -60,7 +60,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
|
||||
predicate isNeutral(Endpoint e) {
|
||||
exists(string package, string type, string name, string signature |
|
||||
sinkSpec(e, package, type, name, signature, _, _) and
|
||||
ExternalFlow::neutralModel(package, type, name, [signature, ""], _, _)
|
||||
ExternalFlow::neutralModel(package, type, name, [signature, ""], "sink", _)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,31 +27,17 @@ class DollarAtString extends string {
|
||||
* Holds for all combinations of MaD kinds (`kind`) and their human readable
|
||||
* descriptions.
|
||||
*/
|
||||
predicate isKnownKind(
|
||||
string kind, string humanReadableKind, AutomodelEndpointTypes::EndpointType type
|
||||
) {
|
||||
kind = "read-file" and
|
||||
humanReadableKind = "read file" and
|
||||
type instanceof AutomodelEndpointTypes::TaintedPathSinkType
|
||||
predicate isKnownKind(string kind, AutomodelEndpointTypes::EndpointType type) {
|
||||
kind = "path-injection" and
|
||||
type instanceof AutomodelEndpointTypes::PathInjectionSinkType
|
||||
or
|
||||
kind = "create-file" and
|
||||
humanReadableKind = "create file" and
|
||||
type instanceof AutomodelEndpointTypes::TaintedPathSinkType
|
||||
kind = "sql-injection" and
|
||||
type instanceof AutomodelEndpointTypes::SqlInjectionSinkType
|
||||
or
|
||||
kind = "sql" and
|
||||
humanReadableKind = "mad modeled sql" and
|
||||
type instanceof AutomodelEndpointTypes::SqlSinkType
|
||||
or
|
||||
kind = "open-url" and
|
||||
humanReadableKind = "open url" and
|
||||
type instanceof AutomodelEndpointTypes::RequestForgerySinkType
|
||||
or
|
||||
kind = "jdbc-url" and
|
||||
humanReadableKind = "jdbc url" and
|
||||
kind = "request-forgery" and
|
||||
type instanceof AutomodelEndpointTypes::RequestForgerySinkType
|
||||
or
|
||||
kind = "command-injection" and
|
||||
humanReadableKind = "command injection" and
|
||||
type instanceof AutomodelEndpointTypes::CommandInjectionSinkType
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ signature module CandidateSig {
|
||||
/**
|
||||
* Defines what MaD kinds are known, and what endpoint type they correspond to.
|
||||
*/
|
||||
predicate isKnownKind(string kind, string humanReadableLabel, EndpointType type);
|
||||
predicate isKnownKind(string kind, EndpointType type);
|
||||
|
||||
/**
|
||||
* Holds if `e` is a flow sanitizer, and has type `t`.
|
||||
@@ -276,7 +276,11 @@ module SharedCharacteristics<CandidateSig Candidate> {
|
||||
string madKind;
|
||||
Candidate::EndpointType endpointType;
|
||||
|
||||
KnownSinkCharacteristic() { Candidate::isKnownKind(madKind, this, endpointType) }
|
||||
KnownSinkCharacteristic() {
|
||||
Candidate::isKnownKind(madKind, endpointType) and
|
||||
// bind "this" to a unique string differing from that of the SinkType classes
|
||||
this = madKind + "-characteristic"
|
||||
}
|
||||
|
||||
override predicate appliesToEndpoint(Candidate::Endpoint e) { Candidate::isSink(e, madKind) }
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The query `java/unsafe-deserialization` has been updated to take into account `SerialKiller`, a library used to prevent deserialization of arbitrary classes.
|
||||
4
java/ql/src/change-notes/2023-06-16-zipslip-rename.md
Normal file
4
java/ql/src/change-notes/2023-06-16-zipslip-rename.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* The query "Arbitrary file write during archive extraction ("Zip Slip")" (`java/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")."
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* New models have been added for `org.apache.commons.lang`.
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 0.6.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `java/summary/lines-of-code` query now only counts lines of Java code. The new `java/summary/lines-of-code-kotlin` counts lines of Kotlin code.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.2
|
||||
lastReleaseVersion: 0.6.3
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
import java
|
||||
import semmle.code.java.security.CommandLineQuery
|
||||
import RemoteUserInputToArgumentToExecFlow::PathGraph
|
||||
import JSchOSInjection
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
private class ActivateModels extends ActiveExperimentalModels {
|
||||
ActivateModels() { this = "jsch-os-injection" }
|
||||
}
|
||||
|
||||
// This is a clone of query `java/command-line-injection` that also includes experimental sinks.
|
||||
from
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* Provides classes for JSch OS command injection detection
|
||||
*/
|
||||
|
||||
import java
|
||||
|
||||
/** The class `com.jcraft.jsch.ChannelExec`. */
|
||||
private class JSchChannelExec extends RefType {
|
||||
JSchChannelExec() { this.hasQualifiedName("com.jcraft.jsch", "ChannelExec") }
|
||||
}
|
||||
|
||||
/** A method to set an OS Command for the execution. */
|
||||
private class ChannelExecSetCommandMethod extends Method, ExecCallable {
|
||||
ChannelExecSetCommandMethod() {
|
||||
this.hasName("setCommand") and
|
||||
this.getDeclaringType() instanceof JSchChannelExec
|
||||
}
|
||||
|
||||
override int getAnExecutedArgument() { result = 0 }
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/java-queries
|
||||
version: 0.6.3-dev
|
||||
version: 0.6.4-dev
|
||||
groups:
|
||||
- java
|
||||
- queries
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
import java
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
* ```ql
|
||||
* import java
|
||||
* import TestUtilities.InlineFlowTest
|
||||
* import DefaultFlowTest
|
||||
* import PathGraph
|
||||
*
|
||||
* from PathNode source, PathNode sink
|
||||
* where flowPath(source, sink)
|
||||
* select sink, source, sink, "$@", source, source.toString()
|
||||
* ```
|
||||
*
|
||||
* To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files.
|
||||
@@ -18,22 +24,18 @@
|
||||
*
|
||||
* public void test() {
|
||||
* Object s = source();
|
||||
* sink(s); //$hasValueFlow
|
||||
* sink(s); // $ hasValueFlow
|
||||
* String t = "foo" + taint();
|
||||
* sink(t); //$hasTaintFlow
|
||||
* sink(t); // $ hasTaintFlow
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* If you're not interested in a specific flow type, you can disable either value or taint flow expectations as follows:
|
||||
* ```ql
|
||||
* class HasFlowTest extends InlineFlowTest {
|
||||
* override DataFlow::Configuration getTaintFlowConfig() { none() }
|
||||
*
|
||||
* override DataFlow::Configuration getValueFlowConfig() { none() }
|
||||
* }
|
||||
* ```
|
||||
* If you are only interested in value flow, then instead of importing `DefaultFlowTest`, you can import
|
||||
* `ValueFlowTest<DefaultFlowConfig>`. Similarly, if you are only interested in taint flow, then instead of
|
||||
* importing `DefaultFlowTest`, you can import `TaintFlowTest<DefaultFlowConfig>`. In both cases
|
||||
* `DefaultFlowConfig` can be replaced by another implementation of `DataFlow::ConfigSig`.
|
||||
*
|
||||
* If you need more fine-grained tuning, consider implementing a test using `InlineExpectationsTest`.
|
||||
*/
|
||||
@@ -43,57 +45,75 @@ import semmle.code.java.dataflow.ExternalFlow
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
private predicate defaultSource(DataFlow::Node src) {
|
||||
src.asExpr().(MethodAccess).getMethod().getName() = ["source", "taint"]
|
||||
private predicate defaultSource(DataFlow::Node source) {
|
||||
source.asExpr().(MethodAccess).getMethod().getName() = ["source", "taint"]
|
||||
}
|
||||
|
||||
private predicate defaultSink(DataFlow::Node sink) {
|
||||
exists(MethodAccess ma | ma.getMethod().hasName("sink") | sink.asExpr() = ma.getAnArgument())
|
||||
}
|
||||
|
||||
module DefaultFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node n) { defaultSource(n) }
|
||||
predicate isSource(DataFlow::Node source) { defaultSource(source) }
|
||||
|
||||
predicate isSink(DataFlow::Node n) {
|
||||
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
|
||||
}
|
||||
predicate isSink(DataFlow::Node sink) { defaultSink(sink) }
|
||||
|
||||
int fieldFlowBranchLimit() { result = 1000 }
|
||||
}
|
||||
|
||||
private module DefaultValueFlow = DataFlow::Global<DefaultFlowConfig>;
|
||||
private module NoFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { none() }
|
||||
|
||||
private module DefaultTaintFlow = TaintTracking::Global<DefaultFlowConfig>;
|
||||
predicate isSink(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
private string getSourceArgString(DataFlow::Node src) {
|
||||
defaultSource(src) and
|
||||
src.asExpr().(MethodAccess).getAnArgument().(StringLiteral).getValue() = result
|
||||
}
|
||||
|
||||
class InlineFlowTest extends InlineExpectationsTest {
|
||||
InlineFlowTest() { this = "HasFlowTest" }
|
||||
module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFlowConfig> {
|
||||
module ValueFlow = DataFlow::Global<ValueFlowConfig>;
|
||||
|
||||
override string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] }
|
||||
module TaintFlow = TaintTracking::Global<TaintFlowConfig>;
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasValueFlow" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink | this.hasValueFlow(src, sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
)
|
||||
or
|
||||
tag = "hasTaintFlow" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
this.hasTaintFlow(src, sink) and not this.hasValueFlow(src, sink)
|
||||
|
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
)
|
||||
private module InlineTest implements TestSig {
|
||||
string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasValueFlow" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink | ValueFlow::flow(src, sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
)
|
||||
or
|
||||
tag = "hasTaintFlow" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
TaintFlow::flow(src, sink) and not ValueFlow::flow(src, sink)
|
||||
|
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) {
|
||||
DefaultValueFlow::flow(src, sink)
|
||||
}
|
||||
import MakeTest<InlineTest>
|
||||
import DataFlow::MergePathGraph<ValueFlow::PathNode, TaintFlow::PathNode, ValueFlow::PathGraph, TaintFlow::PathGraph>
|
||||
|
||||
predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) {
|
||||
DefaultTaintFlow::flow(src, sink)
|
||||
predicate flowPath(PathNode source, PathNode sink) {
|
||||
ValueFlow::flowPath(source.asPathNode1(), sink.asPathNode1()) or
|
||||
TaintFlow::flowPath(source.asPathNode2(), sink.asPathNode2())
|
||||
}
|
||||
}
|
||||
|
||||
module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>;
|
||||
|
||||
module ValueFlowTest<DataFlow::ConfigSig ValueFlowConfig> {
|
||||
import FlowTest<ValueFlowConfig, NoFlowConfig>
|
||||
}
|
||||
|
||||
module TaintFlowTest<DataFlow::ConfigSig TaintFlowConfig> {
|
||||
import FlowTest<NoFlowConfig, TaintFlowConfig>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
import java
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
| test.kt:28:14:28:21 | getSecond(...) | Unexpected result: hasTaintFlow=a |
|
||||
| test.kt:35:14:35:27 | component1(...) | Unexpected result: hasTaintFlow=d |
|
||||
| test.kt:41:14:41:22 | getSecond(...) | Unexpected result: hasTaintFlow=e |
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
import java
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
import java
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -2,6 +2,7 @@ import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.FlowSteps
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
|
||||
class Model extends FluentMethod {
|
||||
Model() { this.getName() = "modelledFluentMethod" }
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
invalidModelRow
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import java
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import ModelValidation
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user