mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
Merge branch 'main' into java/update-mad-decls-after-triage-2023-12-21T14-39-02
This commit is contained in:
@@ -1,3 +1,42 @@
|
||||
## 0.8.6
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* Imports of the old dataflow libraries (e.g. `semmle.code.java.dataflow.DataFlow2`) have been deprecated in the libraries under the `semmle.code.java.security` namespace.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added the `Map#replace` and `Map#replaceAll` methods to the `MapMutator` class in `semmle.code.java.Maps`.
|
||||
* Taint tracking now understands Kotlin's `Array.get` and `Array.set` methods.
|
||||
* Added a sink model for the `createRelative` method of the `org.springframework.core.io.Resource` interface.
|
||||
* Added source models for methods of the `org.springframework.web.util.UrlPathHelper` class and removed their taint flow models.
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.google.common.io
|
||||
* hudson
|
||||
* hudson.console
|
||||
* java.lang
|
||||
* java.net
|
||||
* java.util.logging
|
||||
* javax.imageio.stream
|
||||
* org.apache.commons.io
|
||||
* org.apache.hadoop.hive.ql.exec
|
||||
* org.apache.hadoop.hive.ql.metadata
|
||||
* org.apache.tools.ant.taskdefs
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.alibaba.druid.sql.repository
|
||||
* jakarta.persistence
|
||||
* jakarta.persistence.criteria
|
||||
* liquibase.database.jvm
|
||||
* liquibase.statement.core
|
||||
* org.apache.ibatis.mapping
|
||||
* org.keycloak.models.map.storage
|
||||
|
||||
## 0.8.5
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.8.4
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.alibaba.druid.sql.repository
|
||||
* jakarta.persistence
|
||||
* jakarta.persistence.criteria
|
||||
* liquibase.database.jvm
|
||||
* liquibase.statement.core
|
||||
* org.apache.ibatis.mapping
|
||||
* org.keycloak.models.map.storage
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.google.common.io
|
||||
* hudson
|
||||
* hudson.console
|
||||
* java.lang
|
||||
* java.net
|
||||
* java.util.logging
|
||||
* javax.imageio.stream
|
||||
* org.apache.commons.io
|
||||
* org.apache.hadoop.hive.ql.exec
|
||||
* org.apache.hadoop.hive.ql.metadata
|
||||
* org.apache.tools.ant.taskdefs
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added a sink model for the `createRelative` method of the `org.springframework.core.io.Resource` interface.
|
||||
* Added source models for methods of the `org.springframework.web.util.UrlPathHelper` class and removed their taint flow models.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Taint tracking now understands Kotlin's `Array.get` and `Array.set` methods.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* Imports of the old dataflow libraries (e.g. `semmle.code.java.dataflow.DataFlow2`) have been deprecated in the libraries under the `semmle.code.java.security` namespace.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added the `Map#replace` and `Map#replaceAll` methods to the `MapMutator` class in `semmle.code.java.Maps`.
|
||||
11
java/ql/lib/change-notes/2024-01-02-gson-model-updates.md
Normal file
11
java/ql/lib/change-notes/2024-01-02-gson-model-updates.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added taint tracking for the following GSON methods:
|
||||
* `com.google.gson.stream.JsonReader` constructor
|
||||
* `com.google.gson.stream.JsonWriter` constructor
|
||||
* `com.google.gson.JsonObject.getAsJsonArray`
|
||||
* `com.google.gson.JsonObject.getAsJsonObject`
|
||||
* `com.google.gson.JsonObject.getAsJsonPrimitive`
|
||||
* `com.google.gson.JsonParser.parseReader`
|
||||
* `com.google.gson.JsonParser.parseString`
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* Fixed regular expressions containing flags not being parsed correctly in some cases.
|
||||
4
java/ql/lib/change-notes/2024-01-10-new-jdk-models.md
Normal file
4
java/ql/lib/change-notes/2024-01-10-new-jdk-models.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved models for `java.lang.Throwable` and `java.lang.Exception`, and the `valueOf` method of `java.lang.String`.
|
||||
3
java/ql/lib/change-notes/released/0.8.5.md
Normal file
3
java/ql/lib/change-notes/released/0.8.5.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.8.5
|
||||
|
||||
No user-facing changes.
|
||||
34
java/ql/lib/change-notes/released/0.8.6.md
Normal file
34
java/ql/lib/change-notes/released/0.8.6.md
Normal file
@@ -0,0 +1,34 @@
|
||||
## 0.8.6
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* Imports of the old dataflow libraries (e.g. `semmle.code.java.dataflow.DataFlow2`) have been deprecated in the libraries under the `semmle.code.java.security` namespace.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added the `Map#replace` and `Map#replaceAll` methods to the `MapMutator` class in `semmle.code.java.Maps`.
|
||||
* Taint tracking now understands Kotlin's `Array.get` and `Array.set` methods.
|
||||
* Added a sink model for the `createRelative` method of the `org.springframework.core.io.Resource` interface.
|
||||
* Added source models for methods of the `org.springframework.web.util.UrlPathHelper` class and removed their taint flow models.
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.google.common.io
|
||||
* hudson
|
||||
* hudson.console
|
||||
* java.lang
|
||||
* java.net
|
||||
* java.util.logging
|
||||
* javax.imageio.stream
|
||||
* org.apache.commons.io
|
||||
* org.apache.hadoop.hive.ql.exec
|
||||
* org.apache.hadoop.hive.ql.metadata
|
||||
* org.apache.tools.ant.taskdefs
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.alibaba.druid.sql.repository
|
||||
* jakarta.persistence
|
||||
* jakarta.persistence.criteria
|
||||
* liquibase.database.jvm
|
||||
* liquibase.statement.core
|
||||
* org.apache.ibatis.mapping
|
||||
* org.keycloak.models.map.storage
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.8.4
|
||||
lastReleaseVersion: 0.8.6
|
||||
|
||||
@@ -19,6 +19,8 @@ extensions:
|
||||
- ["com.google.gson", "Gson", False, "newJsonWriter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["com.google.gson.stream", "JsonReader", False, "nextName", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["com.google.gson.stream", "JsonReader", False, "nextString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["com.google.gson.stream", "JsonReader", False, "JsonReader", "(Reader)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["com.google.gson.stream", "JsonWriter", False, "JsonWriter", "(Writer)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["com.google.gson", "JsonElement", True, "getAsByte", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["com.google.gson", "JsonElement", True, "getAsCharacter", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["com.google.gson", "JsonElement", True, "getAsJsonArray", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
@@ -44,6 +46,12 @@ extensions:
|
||||
- ["com.google.gson", "JsonObject", True, "entrySet", "", "", "Argument[this].MapKey", "ReturnValue.Element.MapKey", "value", "manual"]
|
||||
- ["com.google.gson", "JsonObject", True, "entrySet", "", "", "Argument[this].MapValue", "ReturnValue.Element.MapValue", "value", "manual"]
|
||||
- ["com.google.gson", "JsonObject", True, "get", "", "", "Argument[this].MapValue", "ReturnValue", "value", "manual"]
|
||||
- ["com.google.gson", "JsonObject", True, "getAsJsonArray", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["com.google.gson", "JsonObject", True, "getAsJsonObject", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["com.google.gson", "JsonObject", True, "getAsJsonPrimitive", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["com.google.gson", "JsonObject", True, "keySet", "", "", "Argument[this].MapKey", "ReturnValue.Element", "value", "manual"]
|
||||
- ["com.google.gson", "JsonParser", True, "parseReader", "(JsonReader)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["com.google.gson", "JsonParser", True, "parseReader", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["com.google.gson", "JsonParser", True, "parseString", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["com.google.gson", "JsonPrimitive", True, "JsonPrimitive", "(Character)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["com.google.gson", "JsonPrimitive", True, "JsonPrimitive", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
|
||||
@@ -32,8 +32,11 @@ extensions:
|
||||
- ["hudson", "FilePath", True, "write", "(String,String)", "", "Argument[0]", "file-content-store", "manual"]
|
||||
- ["hudson", "Launcher$ProcStarter", False, "cmds", "", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["hudson", "Launcher$ProcStarter", False, "cmdAsSingleString", "", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["hudson", "Launcher$ProcStarter", False, "envs", "(String[])", "", "Argument[0]", "environment-injection", "manual"]
|
||||
- ["hudson", "Launcher", True, "launch", "", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["hudson", "Launcher", True, "decorateByEnv", "(String[])", "", "Argument[0]", "environment-injection", "manual"]
|
||||
- ["hudson", "Launcher", True, "launchChannel", "", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["hudson", "Launcher", True, "launchChannel", "", "", "Argument[3]", "environment-injection", "manual"]
|
||||
- ["hudson", "XmlFile", False, "XmlFile", "(XStream,File)", "", "Argument[1]", "path-injection", "ai-manual"]
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
|
||||
@@ -22,6 +22,8 @@ extensions:
|
||||
- ["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"]
|
||||
# All implementations of `java.lang.Runtime::exec` take the environment variables as their second argument.
|
||||
- ["java.lang", "Runtime", True, "exec", "", "", "Argument[1]", "environment-injection", "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"]
|
||||
@@ -77,6 +79,8 @@ extensions:
|
||||
- ["java.lang", "Exception", False, "Exception", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"]
|
||||
- ["java.lang", "Exception", False, "Exception", "(String,Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"]
|
||||
- ["java.lang", "Exception", False, "Exception", "(String,Throwable)", "", "Argument[1]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"]
|
||||
- ["java.lang", "Exception", False, "Exception", "(Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"]
|
||||
- ["java.lang", "Exception", False, "Exception", "(Throwable)", "", "Argument[0].SyntheticField[java.lang.Throwable.message]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "taint", "manual"]
|
||||
- ["java.lang", "IllegalArgumentException", False, "IllegalArgumentException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"]
|
||||
- ["java.lang", "IllegalStateException", False, "IllegalStateException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"]
|
||||
- ["java.lang", "IndexOutOfBoundsException", False, "IndexOutOfBoundsException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"]
|
||||
@@ -129,6 +133,7 @@ extensions:
|
||||
- ["java.lang", "String", False, "valueOf", "(char)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.lang", "String", False, "valueOf", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.lang", "String", False, "valueOf", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.lang", "String", False, "valueOf", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.lang", "StringBuffer", True, "StringBuffer", "(CharSequence)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["java.lang", "StringBuffer", True, "StringBuffer", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["java.lang", "StringBuilder", True, "StringBuilder", "", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
@@ -139,11 +144,17 @@ extensions:
|
||||
- ["java.lang", "ThreadLocal", True, "get", "()", "", "Argument[this].SyntheticField[java.lang.ThreadLocal.value]", "ReturnValue", "value", "manual"]
|
||||
- ["java.lang", "ThreadLocal", True, "set", "(Object)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.ThreadLocal.value]", "value", "manual"]
|
||||
- ["java.lang", "ThreadLocal", False, "withInitial", "(Supplier)", "", "Argument[0].ReturnValue", "ReturnValue.SyntheticField[java.lang.ThreadLocal.value]", "value", "manual"]
|
||||
- ["java.lang", "Throwable", False, "Throwable", "(Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"]
|
||||
- ["java.lang", "Throwable", False, "Throwable", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"]
|
||||
- ["java.lang", "Throwable", False, "Throwable", "(String,Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"]
|
||||
- ["java.lang", "Throwable", False, "Throwable", "(String,Throwable)", "", "Argument[1]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"]
|
||||
- ["java.lang", "Throwable", False, "Throwable", "(Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"]
|
||||
- ["java.lang", "Throwable", False, "Throwable", "(Throwable)", "", "Argument[0].SyntheticField[java.lang.Throwable.message]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "taint", "manual"]
|
||||
- ["java.lang", "Throwable", True, "getCause", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "ReturnValue", "value", "manual"]
|
||||
- ["java.lang", "Throwable", True, "getMessage", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"]
|
||||
- ["java.lang", "Throwable", True, "getLocalizedMessage", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"]
|
||||
- ["java.lang", "Throwable", True, "initCause", "(Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"]
|
||||
- ["java.lang", "Throwable", True, "initCause", "(Throwable)", "", "Argument[0]", "ReturnValue.SyntheticField[java.lang.Throwable.cause]", "value", "manual"]
|
||||
- ["java.lang", "Throwable", True, "initCause", "(Throwable)", "", "Argument[this]", "ReturnValue", "value", "manual"]
|
||||
- ["java.lang", "Throwable", True, "toString", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.lang", "UnsupportedOperationException", False, "UnsupportedOperationException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"]
|
||||
- addsTo:
|
||||
@@ -200,6 +211,7 @@ extensions:
|
||||
- ["java.lang", "String", "length", "()", "summary", "manual"]
|
||||
- ["java.lang", "String", "startsWith", "(String)", "summary", "manual"]
|
||||
- ["java.lang", "String", "valueOf", "(boolean)", "summary", "manual"]
|
||||
- ["java.lang", "String", "valueOf", "(Object)", "summary", "manual"]
|
||||
- ["java.lang", "System", "currentTimeMillis", "()", "summary", "manual"]
|
||||
- ["java.lang", "System", "exit", "(int)", "summary", "manual"]
|
||||
- ["java.lang", "System", "getenv", "(String)", "summary", "manual"]
|
||||
@@ -211,6 +223,14 @@ extensions:
|
||||
- ["java.lang", "Thread", "interrupt", "()", "summary", "manual"]
|
||||
- ["java.lang", "Thread", "sleep", "(long)", "summary", "manual"]
|
||||
- ["java.lang", "Thread", "start", "()", "summary", "manual"]
|
||||
- ["java.lang", "Throwable", "addSuppressed", "(Throwable)", "summary", "manual"]
|
||||
- ["java.lang", "Throwable", "fillInStackTrace", "()", "summary", "manual"]
|
||||
- ["java.lang", "Throwable", "getStackTrace", "()", "summary", "manual"]
|
||||
- ["java.lang", "Throwable", "getSuppressed", "()", "summary", "manual"]
|
||||
- ["java.lang", "Throwable", "printStackTrace", "()", "summary", "manual"]
|
||||
- ["java.lang", "Throwable", "printStackTrace", "(PrintStream)", "summary", "manual"]
|
||||
- ["java.lang", "Throwable", "printStackTrace", "(PrintWriter)", "summary", "manual"]
|
||||
- ["java.lang", "Throwable", "setStackTrace", "(StackTraceElement[])", "summary", "manual"]
|
||||
# The below APIs have numeric flow and are currently being stored as neutral models.
|
||||
# These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future.
|
||||
- ["java.lang", "Double", "doubleToLongBits", "(double)", "summary", "manual"] # taint-numeric
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["org.apache.commons.exec.environment", "EnvironmentUtils", True, "addVariableToEnvironment", "(Map,String)", "", "Argument[0]", "environment-injection", "manual"]
|
||||
@@ -0,0 +1,6 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["org.apache.commons.exec.launcher", "CommandLauncher", True, "exec", "", "", "Argument[1]", "environment-injection", "manual"]
|
||||
@@ -9,3 +9,5 @@ extensions:
|
||||
- ["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"]
|
||||
- ["org.apache.commons.exec", "Executor", True, "execute", "(CommandLine,Map)", "", "Argument[1]", "environment-injection", "manual"]
|
||||
- ["org.apache.commons.exec", "Executor", True, "execute", "(CommandLine,Map,ExecuteResultHandler)", "", "Argument[1]", "environment-injection", "manual"]
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["org.pac4j.jwt.config.encryption", "SecretEncryptionConfiguration", True, "SecretEncryptionConfiguration", "", "", "Argument[0]", "credentials-key", "manual"]
|
||||
- ["org.pac4j.jwt.config.encryption", "SecretEncryptionConfiguration", True, "setSecret", "", "", "Argument[0]", "credentials-key", "manual"]
|
||||
- ["org.pac4j.jwt.config.encryption", "SecretEncryptionConfiguration", True, "setSecretBase64", "", "", "Argument[0]", "credentials-key", "manual"]
|
||||
- ["org.pac4j.jwt.config.encryption", "SecretEncryptionConfiguration", True, "setSecretBytes", "", "", "Argument[0]", "credentials-key", "manual"]
|
||||
9
java/ql/lib/ext/org.pac4j.jwt.config.signature.model.yml
Normal file
9
java/ql/lib/ext/org.pac4j.jwt.config.signature.model.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["org.pac4j.jwt.config.signature", "SecretSignatureConfiguration", True, "SecretEncryptionConfiguration", "", "", "Argument[0]", "credentials-key", "manual"]
|
||||
- ["org.pac4j.jwt.config.signature", "SecretSignatureConfiguration", True, "setSecret", "", "", "Argument[0]", "credentials-key", "manual"]
|
||||
- ["org.pac4j.jwt.config.signature", "SecretSignatureConfiguration", True, "setSecretBase64", "", "", "Argument[0]", "credentials-key", "manual"]
|
||||
- ["org.pac4j.jwt.config.signature", "SecretSignatureConfiguration", True, "setSecretBytes", "", "", "Argument[0]", "credentials-key", "manual"]
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/java-all
|
||||
version: 0.8.5-dev
|
||||
version: 0.8.7-dev
|
||||
groups: java
|
||||
dbscheme: config/semmlecode.dbscheme
|
||||
extractor: java
|
||||
|
||||
@@ -528,6 +528,10 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
|
||||
exists(Provenance provenance |
|
||||
summaryElement(this, input, output, kind, provenance) and
|
||||
provenance.isGenerated()
|
||||
) and
|
||||
not exists(Provenance provenance |
|
||||
neutralElement(this, "summary", provenance) and
|
||||
provenance.isManual()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -116,10 +116,10 @@ private module DispatchImpl {
|
||||
/**
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context. This is the case if the
|
||||
* qualifier is a parameter of the enclosing callable `c`.
|
||||
* qualifier is a parameter of the enclosing callable of `call`.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) {
|
||||
mayBenefitFromCallContext(call.asCall(), c.asCallable(), _)
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call) {
|
||||
mayBenefitFromCallContext(call.asCall(), _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,4 +18,8 @@ module JavaDataFlow implements InputSig {
|
||||
import Public
|
||||
|
||||
Node exprNode(DataFlowExpr e) { result = Public::exprNode(e) }
|
||||
|
||||
predicate mayBenefitFromCallContext = Private::mayBenefitFromCallContext/1;
|
||||
|
||||
predicate viableImplInCallContext = Private::viableImplInCallContext/2;
|
||||
}
|
||||
|
||||
23
java/ql/lib/semmle/code/java/frameworks/Netty.qll
Normal file
23
java/ql/lib/semmle/code/java/frameworks/Netty.qll
Normal file
@@ -0,0 +1,23 @@
|
||||
/** Provides definitions related to the Netty framework. */
|
||||
|
||||
import java
|
||||
|
||||
/** The interface `Cookie` in the packages `io.netty.handler.codec.http` and `io.netty.handler.codec.http.cookie`. */
|
||||
class NettyCookie extends Interface {
|
||||
NettyCookie() { this.hasQualifiedName("io.netty.handler.codec.http" + [".cookie", ""], "Cookie") }
|
||||
}
|
||||
|
||||
/** The class `DefaultCookie` in the packages `io.netty.handler.codec.http` and `io.netty.handler.codec.http.cookie`. */
|
||||
class NettyDefaultCookie extends Class {
|
||||
NettyDefaultCookie() {
|
||||
this.hasQualifiedName("io.netty.handler.codec.http" + [".cookie", ""], "DefaultCookie")
|
||||
}
|
||||
}
|
||||
|
||||
/** The method `setValue` of the interface `Cookie` or a class implementing it. */
|
||||
class NettySetCookieValueMethod extends Method {
|
||||
NettySetCookieValueMethod() {
|
||||
this.getDeclaringType*() instanceof NettyCookie and
|
||||
this.hasName("setValue")
|
||||
}
|
||||
}
|
||||
29
java/ql/lib/semmle/code/java/frameworks/OpenSaml.qll
Normal file
29
java/ql/lib/semmle/code/java/frameworks/OpenSaml.qll
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Provides classes and predicates for working with the OpenSAML libraries.
|
||||
*/
|
||||
|
||||
import java
|
||||
private import semmle.code.java.security.InsecureRandomnessQuery
|
||||
|
||||
/** The interface `org.opensaml.saml.saml2.core.RequestAbstractType`. */
|
||||
class SamlRequestAbstractType extends Interface {
|
||||
SamlRequestAbstractType() {
|
||||
this.hasQualifiedName("org.opensaml.saml.saml2.core", "RequestAbstractType")
|
||||
}
|
||||
}
|
||||
|
||||
/** The method `setID` of the interface `RequestAbstractType`. */
|
||||
class SamlRequestSetIdMethod extends Method {
|
||||
SamlRequestSetIdMethod() {
|
||||
this.getDeclaringType() instanceof SamlRequestAbstractType and
|
||||
this.hasName("setID")
|
||||
}
|
||||
}
|
||||
|
||||
private class SamlRequestSetIdSink extends InsecureRandomnessSink {
|
||||
SamlRequestSetIdSink() {
|
||||
exists(MethodCall c | c.getMethod() instanceof SamlRequestSetIdMethod |
|
||||
c.getArgument(0) = this.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -244,7 +244,7 @@ class TypeCookie extends Class {
|
||||
}
|
||||
|
||||
/**
|
||||
* The method `getValue(String)` declared in `javax.servlet.http.Cookie`.
|
||||
* The method `getValue()` declared in `javax.servlet.http.Cookie`.
|
||||
*/
|
||||
class CookieGetValueMethod extends Method {
|
||||
CookieGetValueMethod() {
|
||||
@@ -254,6 +254,16 @@ class CookieGetValueMethod extends Method {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The method `setValue(String)` declared in `javax.servlet.http.Cookie`.
|
||||
*/
|
||||
class CookieSetValueMethod extends Method {
|
||||
CookieSetValueMethod() {
|
||||
this.getDeclaringType() instanceof TypeCookie and
|
||||
this.hasName("setValue")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The method `getName()` declared in `javax.servlet.http.Cookie`.
|
||||
*/
|
||||
|
||||
@@ -479,7 +479,7 @@ abstract class RegexString extends StringLiteral {
|
||||
private predicate flagGroupStartNoModes(int start, int end) {
|
||||
this.isGroupStart(start) and
|
||||
this.getChar(start + 1) = "?" and
|
||||
this.getChar(start + 2) in ["i", "m", "s", "u", "x", "U"] and
|
||||
this.getChar(start + 2) in ["-", "i", "d", "m", "s", "u", "x", "U"] and
|
||||
end = start + 2
|
||||
}
|
||||
|
||||
@@ -491,7 +491,7 @@ abstract class RegexString extends StringLiteral {
|
||||
this.flagGroupStartNoModes(start, pos)
|
||||
or
|
||||
this.modeCharacter(start, pos - 1) and
|
||||
this.getChar(pos) in ["i", "m", "s", "u", "x", "U"]
|
||||
this.getChar(pos) in ["-", "i", "d", "m", "s", "u", "x", "U"]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -499,7 +499,10 @@ abstract class RegexString extends StringLiteral {
|
||||
*/
|
||||
private predicate flagGroupStart(int start, int end) {
|
||||
this.flagGroupStartNoModes(start, _) and
|
||||
end = max(int i | this.modeCharacter(start, i) | i + 1)
|
||||
// Check if this is a capturing group with flags, and therefore the `:` should be excluded
|
||||
exists(int maybeEnd | maybeEnd = max(int i | this.modeCharacter(start, i) | i + 1) |
|
||||
if this.getChar(maybeEnd) = ":" then end = maybeEnd + 1 else end = maybeEnd
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -510,9 +513,15 @@ abstract class RegexString extends StringLiteral {
|
||||
* ```
|
||||
*/
|
||||
private predicate flag(string c) {
|
||||
exists(int pos |
|
||||
this.modeCharacter(_, pos) and
|
||||
this.getChar(pos) = c
|
||||
exists(int start, int pos |
|
||||
this.modeCharacter(start, pos) and
|
||||
this.getChar(pos) = c and
|
||||
// Ignore if flag is disabled; use `<=` to also exclude `-` itself
|
||||
// This does not properly handle the (contrived) case where a flag is both enabled and
|
||||
// disabled, e.g. `(?i-i)a+`, in which case the flag seems to acts as if it was disabled
|
||||
not exists(int minusPos |
|
||||
this.modeCharacter(start, minusPos) and this.getChar(minusPos) = "-" and minusPos <= pos
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -524,6 +533,8 @@ abstract class RegexString extends StringLiteral {
|
||||
exists(string c | this.flag(c) |
|
||||
c = "i" and result = "IGNORECASE"
|
||||
or
|
||||
c = "d" and result = "UNIXLINES"
|
||||
or
|
||||
c = "m" and result = "MULTILINE"
|
||||
or
|
||||
c = "s" and result = "DOTALL"
|
||||
@@ -930,13 +941,13 @@ class Regex extends RegexString {
|
||||
|
||||
/**
|
||||
* Gets a mode (if any) of this regular expression. Can be any of:
|
||||
* DEBUG
|
||||
* IGNORECASE
|
||||
* MULTILINE
|
||||
* DOTALL
|
||||
* UNICODE
|
||||
* VERBOSE
|
||||
* UNICODECLASS
|
||||
* - IGNORECASE
|
||||
* - UNIXLINES
|
||||
* - MULTILINE
|
||||
* - DOTALL
|
||||
* - UNICODE
|
||||
* - VERBOSE
|
||||
* - UNICODECLASS
|
||||
*/
|
||||
string getAMode() {
|
||||
result != "None" and
|
||||
@@ -946,7 +957,7 @@ class Regex extends RegexString {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this regex is used to match against a full string,
|
||||
* Holds if this regex is used to match against a full string,
|
||||
* as though it was implicitly surrounded by ^ and $.
|
||||
*/
|
||||
predicate matchesFullString() { matches_full_string = true }
|
||||
|
||||
32
java/ql/lib/semmle/code/java/security/Cookies.qll
Normal file
32
java/ql/lib/semmle/code/java/security/Cookies.qll
Normal file
@@ -0,0 +1,32 @@
|
||||
/** Provides definitions to reason about HTTP cookies. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.frameworks.Netty
|
||||
private import semmle.code.java.frameworks.Servlets
|
||||
|
||||
/** An expression setting the value of a cookie. */
|
||||
abstract class SetCookieValue extends Expr { }
|
||||
|
||||
private class ServletSetCookieValue extends SetCookieValue {
|
||||
ServletSetCookieValue() {
|
||||
exists(Call c |
|
||||
c.(ClassInstanceExpr).getConstructedType() instanceof TypeCookie and
|
||||
this = c.getArgument(1)
|
||||
or
|
||||
c.(MethodCall).getMethod() instanceof CookieSetValueMethod and
|
||||
this = c.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class NettySetCookieValue extends SetCookieValue {
|
||||
NettySetCookieValue() {
|
||||
exists(Call c |
|
||||
c.(ClassInstanceExpr).getConstructedType() instanceof NettyDefaultCookie and
|
||||
this = c.getArgument(1)
|
||||
or
|
||||
c.(MethodCall).getMethod() instanceof NettySetCookieValueMethod and
|
||||
this = c.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
/** Provides classes and predicates for reasoning about insecure randomness. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.frameworks.OpenSaml
|
||||
private import semmle.code.java.frameworks.Servlets
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
private import semmle.code.java.dataflow.TaintTracking
|
||||
private import semmle.code.java.security.Cookies
|
||||
private import semmle.code.java.security.RandomQuery
|
||||
private import semmle.code.java.security.SensitiveActions
|
||||
private import semmle.code.java.security.SensitiveApi
|
||||
private import semmle.code.java.dataflow.TaintTracking
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
private import semmle.code.java.security.RandomQuery
|
||||
|
||||
/**
|
||||
* A node representing a source of insecure randomness.
|
||||
@@ -18,7 +20,7 @@ abstract class InsecureRandomnessSource extends DataFlow::Node { }
|
||||
private class RandomMethodSource extends InsecureRandomnessSource {
|
||||
RandomMethodSource() {
|
||||
exists(RandomDataSource s | this.asExpr() = s.getOutput() |
|
||||
not s.getQualifier().getType() instanceof SafeRandomImplementation
|
||||
not s.getSourceOfRandomness() instanceof SafeRandomImplementation
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -40,7 +42,7 @@ private class TypeHadoopOsSecureRandom extends SafeRandomImplementation {
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing an operation which should not use a Insecurely random value.
|
||||
* A node representing an operation which should not use an insecurely random value.
|
||||
*/
|
||||
abstract class InsecureRandomnessSink extends DataFlow::Node { }
|
||||
|
||||
@@ -48,16 +50,7 @@ abstract class InsecureRandomnessSink extends DataFlow::Node { }
|
||||
* A node which sets the value of a cookie.
|
||||
*/
|
||||
private class CookieSink extends InsecureRandomnessSink {
|
||||
CookieSink() {
|
||||
exists(Call c |
|
||||
c.(ClassInstanceExpr).getConstructedType() instanceof TypeCookie and
|
||||
this.asExpr() = c.getArgument(1)
|
||||
or
|
||||
c.(MethodCall).getMethod().getDeclaringType() instanceof TypeCookie and
|
||||
c.(MethodCall).getMethod().hasName("setValue") and
|
||||
this.asExpr() = c.getArgument(0)
|
||||
)
|
||||
}
|
||||
CookieSink() { this.asExpr() instanceof SetCookieValue }
|
||||
}
|
||||
|
||||
private class SensitiveActionSink extends InsecureRandomnessSink {
|
||||
@@ -76,6 +69,8 @@ module InsecureRandomnessConfig implements DataFlow::ConfigSig {
|
||||
|
||||
predicate isBarrierIn(DataFlow::Node n) { isSource(n) }
|
||||
|
||||
predicate isBarrierOut(DataFlow::Node n) { isSink(n) }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
n1.asExpr() = n2.asExpr().(BinaryExpr).getAnOperand()
|
||||
or
|
||||
@@ -88,6 +83,17 @@ module InsecureRandomnessConfig implements DataFlow::ConfigSig {
|
||||
n1.asExpr() = mc.getArgument(0) and
|
||||
n2.asExpr() = mc
|
||||
)
|
||||
or
|
||||
// TODO: Once we have a default sanitizer for UUIDs, we can convert these to global summaries.
|
||||
exists(Call c |
|
||||
c.(ClassInstanceExpr).getConstructedType().hasQualifiedName("java.util", "UUID") and
|
||||
n1.asExpr() = c.getAnArgument() and
|
||||
n2.asExpr() = c
|
||||
or
|
||||
c.(MethodCall).getMethod().hasQualifiedName("java.util", "UUID", "toString") and
|
||||
n1.asExpr() = c.getQualifier() and
|
||||
n2.asExpr() = c
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,12 @@ private import semmle.code.java.dataflow.RangeUtils
|
||||
private import semmle.code.java.dispatch.VirtualDispatch
|
||||
private import semmle.code.java.frameworks.Properties
|
||||
|
||||
/** A reference to an insecure cryptographic algorithm. */
|
||||
abstract class InsecureAlgorithm extends Expr {
|
||||
/** Gets the string representation of this insecure cryptographic algorithm. */
|
||||
abstract string getStringValue();
|
||||
}
|
||||
|
||||
private class ShortStringLiteral extends StringLiteral {
|
||||
ShortStringLiteral() { this.getValue().length() < 100 }
|
||||
}
|
||||
@@ -17,16 +23,34 @@ private class ShortStringLiteral extends StringLiteral {
|
||||
/**
|
||||
* A string literal that may refer to an insecure cryptographic algorithm.
|
||||
*/
|
||||
class InsecureAlgoLiteral extends ShortStringLiteral {
|
||||
class InsecureAlgoLiteral extends InsecureAlgorithm, ShortStringLiteral {
|
||||
InsecureAlgoLiteral() {
|
||||
// Algorithm identifiers should be at least two characters.
|
||||
this.getValue().length() > 1 and
|
||||
exists(string s | s = this.getValue() |
|
||||
// Algorithm identifiers should be at least two characters.
|
||||
s.length() > 1 and
|
||||
not s.regexpMatch(getSecureAlgorithmRegex()) and
|
||||
// Exclude results covered by another query.
|
||||
not s.regexpMatch(getInsecureAlgorithmRegex())
|
||||
)
|
||||
}
|
||||
|
||||
override string getStringValue() { result = this.getValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A property access that may refer to an insecure cryptographic algorithm.
|
||||
*/
|
||||
class InsecureAlgoProperty extends InsecureAlgorithm, PropertiesGetPropertyMethodCall {
|
||||
string value;
|
||||
|
||||
InsecureAlgoProperty() {
|
||||
value = this.getPropertyValue() and
|
||||
// Since properties pairs are not included in the java/weak-cryptographic-algorithm,
|
||||
// the check for values from properties files can be less strict than `InsecureAlgoLiteral`.
|
||||
not value.regexpMatch(getSecureAlgorithmRegex())
|
||||
}
|
||||
|
||||
override string getStringValue() { result = value }
|
||||
}
|
||||
|
||||
private predicate objectToString(MethodCall ma) {
|
||||
@@ -41,15 +65,7 @@ private predicate objectToString(MethodCall ma) {
|
||||
* A taint-tracking configuration to reason about the use of potentially insecure cryptographic algorithms.
|
||||
*/
|
||||
module InsecureCryptoConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node n) {
|
||||
n.asExpr() instanceof InsecureAlgoLiteral
|
||||
or
|
||||
exists(PropertiesGetPropertyMethodCall mc | n.asExpr() = mc |
|
||||
// Since properties pairs are not included in the java/weak-crypto-algorithm,
|
||||
// The check for values from properties files can be less strict than `InsecureAlgoLiteral`.
|
||||
not mc.getPropertyValue().regexpMatch(getSecureAlgorithmRegex())
|
||||
)
|
||||
}
|
||||
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof InsecureAlgorithm }
|
||||
|
||||
predicate isSink(DataFlow::Node n) { exists(CryptoAlgoSpec c | n.asExpr() = c.getAlgoSpec()) }
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.TypeFlow
|
||||
|
||||
/**
|
||||
* A method access that returns random data or writes random data to an argument.
|
||||
@@ -43,6 +44,9 @@ abstract class RandomDataSource extends MethodCall {
|
||||
* in the case where it writes random data to that argument.
|
||||
*/
|
||||
abstract Expr getOutput();
|
||||
|
||||
/** Gets the type of the source of randomness used by this call. */
|
||||
RefType getSourceOfRandomness() { boundOrStaticType(this.getQualifier(), result) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,4 +171,18 @@ class ApacheCommonsRandomStringSource extends RandomDataSource {
|
||||
}
|
||||
|
||||
override Expr getOutput() { result = this }
|
||||
|
||||
override RefType getSourceOfRandomness() {
|
||||
if
|
||||
this.getMethod().hasStringSignature("random(int, int, int, boolean, boolean, char[], Random)")
|
||||
then boundOrStaticType(this.getArgument(6), result)
|
||||
else result.hasQualifiedName("java.util", "Random")
|
||||
}
|
||||
}
|
||||
|
||||
/** 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()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/** Modules to reason about the tainting of environment variables */
|
||||
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
private import semmle.code.java.dataflow.FlowSources
|
||||
private import semmle.code.java.Maps
|
||||
private import semmle.code.java.JDK
|
||||
|
||||
private module ProcessBuilderEnvironmentConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(MethodCall mc | mc = source.asExpr() |
|
||||
mc.getMethod().hasQualifiedName("java.lang", "ProcessBuilder", "environment")
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(MapMutation mm).getQualifier() }
|
||||
}
|
||||
|
||||
private module ProcessBuilderEnvironmentFlow = DataFlow::Global<ProcessBuilderEnvironmentConfig>;
|
||||
|
||||
/**
|
||||
* A node that acts as a sanitizer in configurations related to environment variable injection.
|
||||
*/
|
||||
abstract class ExecTaintedEnvironmentSanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration that tracks flow from unvalidated data to an environment variable for a subprocess.
|
||||
*/
|
||||
module ExecTaintedEnvironmentConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource }
|
||||
|
||||
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof ExecTaintedEnvironmentSanitizer }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sinkNode(sink, "environment-injection")
|
||||
or
|
||||
// sink is a key or value added to a `ProcessBuilder::environment` map.
|
||||
exists(MapMutation mm | mm.getAnArgument() = sink.asExpr() |
|
||||
ProcessBuilderEnvironmentFlow::flowToExpr(mm.getQualifier())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Taint-tracking flow for unvalidated data to an environment variable for a subprocess.
|
||||
*/
|
||||
module ExecTaintedEnvironmentFlow = TaintTracking::Global<ExecTaintedEnvironmentConfig>;
|
||||
Reference in New Issue
Block a user