Merge branch 'main' into delOldDeps

This commit is contained in:
erik-krogh
2023-03-13 11:00:29 +01:00
979 changed files with 64507 additions and 195617 deletions

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "An Android build may have failed. Ensure the Code Scanning workflow installs required dependencies, and that the [Gradle and Android SDK versions are compatible](https://developer.android.com/studio/releases/gradle-plugin#updating-gradle). Suspicious output line: ` > Minimum supported Gradle version is 7.4. Current version is 7.3. If using the gradle wrapper, try editing the distributionUrl in <test-root-directory>/gradle/wrapper/gradle-wrapper.properties to gradle-7.4-all.zip`",
"markdownMessage": "An Android build may have failed. Ensure the Code Scanning workflow installs required dependencies, and that the [Gradle and Android SDK versions are compatible](https://developer.android.com/studio/releases/gradle-plugin#updating-gradle).\n\nSuspicious output line: ` > Minimum supported Gradle version is 7.4. Current version is 7.3. If using the gradle wrapper, try editing the distributionUrl in <test-root-directory>/gradle/wrapper/gradle-wrapper.properties to gradle-7.4-all.zip`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "An Android build may have failed. Ensure the Code Scanning workflow installs required dependencies, and that the [Gradle and Android SDK versions are compatible](https://developer.android.com/studio/releases/gradle-plugin#updating-gradle). Suspicious output line: `Caused by: java.lang.RuntimeException: Minimum supported Gradle version is 7.4. Current version is 7.3. If using the gradle wrapper, try editing the distributionUrl in <test-root-directory>/gradle/wrapper/gradle-wrapper.properties to gradle-7.4-all.zip`",
"markdownMessage": "An Android build may have failed. Ensure the Code Scanning workflow installs required dependencies, and that the [Gradle and Android SDK versions are compatible](https://developer.android.com/studio/releases/gradle-plugin#updating-gradle).\n\nSuspicious output line: `Caused by: java.lang.RuntimeException: Minimum supported Gradle version is 7.4. Current version is 7.3. If using the gradle wrapper, try editing the distributionUrl in <test-root-directory>/gradle/wrapper/gradle-wrapper.properties to gradle-7.4-all.zip`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies. Suspicious output line: `[ERROR] COMPILATION ERROR : `",
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies.\n\nSuspicious output line: `[ERROR] COMPILATION ERROR : `",
"severity": "error",
"source": {
"extractorName": "java",
@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies. Suspicious output line: `[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project maven-sample: Compilation failure`",
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies.\n\nSuspicious output line: `[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project maven-sample: Compilation failure`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -27,7 +27,7 @@
}
}
{
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies. Suspicious output line: `org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project maven-sample: Compilation failure`",
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies.\n\nSuspicious output line: `org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project maven-sample: Compilation failure`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "A dependency failed to download. Check that all dependencies are available, and [supply credentials for any private dependencies](https://github.com/Azure/actions-workflow-samples/blob/master/assets/create-secrets-for-GitHub-workflows.md#set-up-secrets-in-github-action-workflows). Suspicious output line: `Caused by: org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact junit:junit-nonesuch:jar:4.11 in central (https://repo.maven.apache.org/maven2)`",
"markdownMessage": "A dependency failed to download. Check that all dependencies are available, and [supply credentials for any private dependencies](https://github.com/Azure/actions-workflow-samples/blob/master/assets/create-secrets-for-GitHub-workflows.md#set-up-secrets-in-github-action-workflows).\n\nSuspicious output line: `Caused by: org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact junit:junit-nonesuch:jar:4.11 in central (https://repo.maven.apache.org/maven2)`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "Your project may need a different JDK version. Ensure your Code Scanning workflow file has [an appropriate `setup-java` step](https://github.com/actions/setup-java#eclipse-temurin). Suspicious output line: `> Could not target platform: 'Java SE 11' using tool chain: 'JDK 8 (1.8)'.`",
"markdownMessage": "Your project may need a different JDK version. Ensure your Code Scanning workflow file has [an appropriate `setup-java` step](https://github.com/actions/setup-java#eclipse-temurin).\n\nSuspicious output line: `> Could not target platform: 'Java SE 11' using tool chain: 'JDK 8 (1.8)'.`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "Your project may need a different JDK version. Ensure your Code Scanning workflow file has [an appropriate `setup-java` step](https://github.com/actions/setup-java#eclipse-temurin). Suspicious output line: `Caused by: java.lang.IllegalArgumentException: Could not target platform: 'Java SE 11' using tool chain: 'JDK 8 (1.8)'.`",
"markdownMessage": "Your project may need a different JDK version. Ensure your Code Scanning workflow file has [an appropriate `setup-java` step](https://github.com/actions/setup-java#eclipse-temurin).\n\nSuspicious output line: `Caused by: java.lang.IllegalArgumentException: Could not target platform: 'Java SE 11' using tool chain: 'JDK 8 (1.8)'.`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked). Suspicious output line: `Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked).\n\nSuspicious output line: `Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked). Suspicious output line: `Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked).\n\nSuspicious output line: `Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -27,7 +27,7 @@
}
}
{
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked). Suspicious output line: `Caused by: org.eclipse.aether.transfer.NoRepositoryConnectorException: Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked).\n\nSuspicious output line: `Caused by: org.eclipse.aether.transfer.NoRepositoryConnectorException: Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -41,7 +41,7 @@
}
}
{
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked). Suspicious output line: `[ERROR] Failed to execute goal on project maven-sample: Could not resolve dependencies for project com.example:maven-sample:jar:1.0-SNAPSHOT: Failed to collect dependencies at junit-nonesuch:junit-nonesuch:jar:4.11: Failed to read artifact descriptor for junit-nonesuch:junit-nonesuch:jar:4.11: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)] -> [Help 1]`",
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked).\n\nSuspicious output line: `[ERROR] Failed to execute goal on project maven-sample: Could not resolve dependencies for project com.example:maven-sample:jar:1.0-SNAPSHOT: Failed to collect dependencies at junit-nonesuch:junit-nonesuch:jar:4.11: Failed to read artifact descriptor for junit-nonesuch:junit-nonesuch:jar:4.11: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)] -> [Help 1]`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "Building using Maven was skipped because there were multiple sibling build directories containing build files: [./maven-project-1,./maven-project-2]. If you want to use one of these, please [manually supply a build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language)",
"markdownMessage": "Building using Maven was skipped because there were multiple sibling build directories containing build files: [./maven-project-1,./maven-project-2]. If you want to use one of these, please [manually supply a build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language).",
"severity": "warning",
"source": {
"extractorName": "java",
@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "If you want to use one of the candidate build systems and directories (see previous warnings), please [supply a manual a build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language)",
"markdownMessage": "If you want to use one of the candidate build systems and directories (see previous warnings), please [supply a manual a build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language).",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "Could not find a Gradle, Maven or Ant top-level project to build. Please [supply a manual build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language)",
"markdownMessage": "Could not find a Gradle, Maven or Ant top-level project to build. Please [supply a manual build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language).",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "Gradle project does not define a `testClasses` goal. [Supply a manual build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language) that builds the code that should be analyzed. Suspicious output line: `org.gradle.execution.TaskSelectionException: Task 'testClasses' not found in root project 'no-gradle-test-classes'.`",
"markdownMessage": "Gradle project does not define a `testClasses` goal. [Supply a manual build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language) that builds the code that should be analyzed.\n\nSuspicious output line: `org.gradle.execution.TaskSelectionException: Task 'testClasses' not found in root project 'no-gradle-test-classes'.`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,10 +1,10 @@
{
"markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 1.8.30",
"markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 1.8.30.",
"severity": "error",
"source": {
"extractorName": "java",
"id": "java/extractor-agent/kotlin-version-too-new",
"name": "Android build failure"
"name": "Kotlin version too new"
},
"visibility": {
"cliSummaryTable": true,

View File

@@ -1,3 +1,11 @@
## 0.5.4
### Minor Analysis Improvements
* Added new sinks for `java/hardcoded-credential-api-call` to identify the use of hardcoded secrets in the creation and verification of JWT tokens using `com.auth0.jwt`. These sinks are from [an experimental query submitted by @luchua](https://github.com/github/codeql/pull/9036).
* The Java extractor now supports builds against JDK 20.
* The query `java/hardcoded-credential-api-call` now recognizes methods that accept user and password from the SQLServerDataSource class of the Microsoft JDBC Driver for SQL Server.
## 0.5.3
### New Features

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The query `java/hardcoded-credential-api-call` now recognizes methods that accept user and password from the SQLServerDataSource class of the Microsoft JDBC Driver for SQL Server.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Added new sinks for `java/hardcoded-credential-api-call` to identify the use of hardcoded secrets in the creation and verification of JWT tokens using `com.auth0.jwt`. These sinks are from [an experimental query submitted by @luchua](https://github.com/github/codeql/pull/9036).

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The Java extractor now supports builds against JDK 20.

View File

@@ -0,0 +1,9 @@
---
category: majorAnalysis
---
* The main data flow and taint tracking APIs have been changed. The old APIs
remain in place for now and translate to the new through a
backwards-compatible wrapper. If multiple configurations are in scope
simultaneously, then this may affect results slightly. The new API is quite
similar to the old, but makes use of a configuration module instead of a
configuration class.

View File

@@ -0,0 +1,7 @@
## 0.5.4
### Minor Analysis Improvements
* Added new sinks for `java/hardcoded-credential-api-call` to identify the use of hardcoded secrets in the creation and verification of JWT tokens using `com.auth0.jwt`. These sinks are from [an experimental query submitted by @luchua](https://github.com/github/codeql/pull/9036).
* The Java extractor now supports builds against JDK 20.
* The query `java/hardcoded-credential-api-call` now recognizes methods that accept user and password from the SQLServerDataSource class of the Microsoft JDBC Driver for SQL Server.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.5.3
lastReleaseVersion: 0.5.4

View File

@@ -1,5 +1,5 @@
name: codeql/java-all
version: 0.5.4-dev
version: 0.5.5-dev
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java

View File

@@ -6,5 +6,6 @@
import java
module DataFlow {
import semmle.code.java.dataflow.internal.DataFlowImpl
import semmle.code.java.dataflow.internal.DataFlow
import semmle.code.java.dataflow.internal.DataFlowImpl1
}

View File

@@ -8,5 +8,6 @@ import semmle.code.java.dataflow.DataFlow2
import semmle.code.java.dataflow.internal.TaintTrackingUtil::StringBuilderVarModule
module TaintTracking {
import semmle.code.java.dataflow.internal.tainttracking1.TaintTracking
import semmle.code.java.dataflow.internal.tainttracking1.TaintTrackingImpl
}

View File

@@ -0,0 +1,245 @@
/**
* Provides an implementation of global (interprocedural) data flow. This file
* re-exports the local (intraprocedural) data flow analysis from
* `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed
* through the `Make` and `MakeWithState` modules.
*/
private import DataFlowImplCommon
private import DataFlowImplSpecific::Private
import DataFlowImplSpecific::Public
import DataFlowImplCommonPublic
private import DataFlowImpl
/** An input configuration for data flow. */
signature module ConfigSig {
/**
* Holds if `source` is a relevant data flow source.
*/
predicate isSource(Node source);
/**
* Holds if `sink` is a relevant data flow sink.
*/
predicate isSink(Node sink);
/**
* Holds if data flow through `node` is prohibited. This completely removes
* `node` from the data flow graph.
*/
default predicate isBarrier(Node node) { none() }
/** Holds if data flow into `node` is prohibited. */
default predicate isBarrierIn(Node node) { none() }
/** Holds if data flow out of `node` is prohibited. */
default predicate isBarrierOut(Node node) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
default predicate isAdditionalFlowStep(Node node1, Node node2) { none() }
/**
* Holds if an arbitrary number of implicit read steps of content `c` may be
* taken at `node`.
*/
default predicate allowImplicitRead(Node node, ContentSet c) { none() }
/**
* Gets the virtual dispatch branching limit when calculating field flow.
* This can be overridden to a smaller value to improve performance (a
* value of 0 disables field flow), or a larger value to get more results.
*/
default int fieldFlowBranchLimit() { result = 2 }
/**
* Gets a data flow configuration feature to add restrictions to the set of
* valid flow paths.
*
* - `FeatureHasSourceCallContext`:
* Assume that sources have some existing call context to disallow
* conflicting return-flow directly following the source.
* - `FeatureHasSinkCallContext`:
* Assume that sinks have some existing call context to disallow
* conflicting argument-to-parameter flow directly preceding the sink.
* - `FeatureEqualSourceSinkCallContext`:
* Implies both of the above and additionally ensures that the entire flow
* path preserves the call context.
*
* These features are generally not relevant for typical end-to-end data flow
* queries, but should only be used for constructing paths that need to
* somehow be pluggable in another path context.
*/
default FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
default predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
default predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if hidden nodes should be included in the data flow graph.
*
* This feature should only be used for debugging or when the data flow graph
* is not visualized (as it is in a `path-problem` query).
*/
default predicate includeHiddenNodes() { none() }
}
/** An input configuration for data flow using flow state. */
signature module StateConfigSig {
bindingset[this]
class FlowState;
/**
* Holds if `source` is a relevant data flow source with the given initial
* `state`.
*/
predicate isSource(Node source, FlowState state);
/**
* Holds if `sink` is a relevant data flow sink accepting `state`.
*/
predicate isSink(Node sink, FlowState state);
/**
* Holds if data flow through `node` is prohibited. This completely removes
* `node` from the data flow graph.
*/
default predicate isBarrier(Node node) { none() }
/**
* Holds if data flow through `node` is prohibited when the flow state is
* `state`.
*/
predicate isBarrier(Node node, FlowState state);
/** Holds if data flow into `node` is prohibited. */
default predicate isBarrierIn(Node node) { none() }
/** Holds if data flow out of `node` is prohibited. */
default predicate isBarrierOut(Node node) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
default predicate isAdditionalFlowStep(Node node1, Node node2) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
* This step is only applicable in `state1` and updates the flow state to `state2`.
*/
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2);
/**
* Holds if an arbitrary number of implicit read steps of content `c` may be
* taken at `node`.
*/
default predicate allowImplicitRead(Node node, ContentSet c) { none() }
/**
* Gets the virtual dispatch branching limit when calculating field flow.
* This can be overridden to a smaller value to improve performance (a
* value of 0 disables field flow), or a larger value to get more results.
*/
default int fieldFlowBranchLimit() { result = 2 }
/**
* Gets a data flow configuration feature to add restrictions to the set of
* valid flow paths.
*
* - `FeatureHasSourceCallContext`:
* Assume that sources have some existing call context to disallow
* conflicting return-flow directly following the source.
* - `FeatureHasSinkCallContext`:
* Assume that sinks have some existing call context to disallow
* conflicting argument-to-parameter flow directly preceding the sink.
* - `FeatureEqualSourceSinkCallContext`:
* Implies both of the above and additionally ensures that the entire flow
* path preserves the call context.
*
* These features are generally not relevant for typical end-to-end data flow
* queries, but should only be used for constructing paths that need to
* somehow be pluggable in another path context.
*/
default FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
default predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
default predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if hidden nodes should be included in the data flow graph.
*
* This feature should only be used for debugging or when the data flow graph
* is not visualized (as it is in a `path-problem` query).
*/
default predicate includeHiddenNodes() { none() }
}
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
* measured in approximate number of interprocedural steps.
*/
signature int explorationLimitSig();
/**
* The output of a data flow computation.
*/
signature module DataFlowSig {
/**
* A `Node` augmented with a call context (except for sinks) and an access path.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode;
/**
* Holds if data can flow from `source` to `sink`.
*
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink);
/**
* Holds if data can flow from `source` to `sink`.
*/
predicate hasFlow(Node source, Node sink);
/**
* Holds if data can flow from some source to `sink`.
*/
predicate hasFlowTo(Node sink);
/**
* Holds if data can flow from some source to `sink`.
*/
predicate hasFlowToExpr(DataFlowExpr sink);
}
/**
* Constructs a standard data flow computation.
*/
module Make<ConfigSig Config> implements DataFlowSig {
private module C implements FullStateConfigSig {
import DefaultState<Config>
import Config
}
import Impl<C>
}
/**
* Constructs a data flow computation using flow state.
*/
module MakeWithState<StateConfigSig Config> implements DataFlowSig {
private module C implements FullStateConfigSig {
import Config
}
import Impl<C>
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,396 @@
/**
* DEPRECATED: Use `Make` and `MakeWithState` instead.
*
* Provides a `Configuration` class backwards-compatible interface to the data
* flow library.
*/
private import DataFlowImplCommon
private import DataFlowImplSpecific::Private
import DataFlowImplSpecific::Public
private import DataFlowImpl
import DataFlowImplCommonPublic
import FlowStateString
/**
* A configuration of interprocedural data flow analysis. This defines
* sources, sinks, and any other configurable aspect of the analysis. Each
* use of the global data flow library must define its own unique extension
* of this abstract class. To create a configuration, extend this class with
* a subclass whose characteristic predicate is a unique singleton string.
* For example, write
*
* ```ql
* class MyAnalysisConfiguration extends DataFlow::Configuration {
* MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" }
* // Override `isSource` and `isSink`.
* // Optionally override `isBarrier`.
* // Optionally override `isAdditionalFlowStep`.
* }
* ```
* Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and
* the edges are those data-flow steps that preserve the value of the node
* along with any additional edges defined by `isAdditionalFlowStep`.
* Specifying nodes in `isBarrier` will remove those nodes from the graph, and
* specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going
* and/or out-going edges from those nodes, respectively.
*
* Then, to query whether there is flow between some `source` and `sink`,
* write
*
* ```ql
* exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink))
* ```
*
* Multiple configurations can coexist, but two classes extending
* `DataFlow::Configuration` should never depend on each other. One of them
* should instead depend on a `DataFlow2::Configuration`, a
* `DataFlow3::Configuration`, or a `DataFlow4::Configuration`.
*/
abstract class Configuration extends string {
bindingset[this]
Configuration() { any() }
/**
* Holds if `source` is a relevant data flow source.
*/
predicate isSource(Node source) { none() }
/**
* Holds if `source` is a relevant data flow source with the given initial
* `state`.
*/
predicate isSource(Node source, FlowState state) { none() }
/**
* Holds if `sink` is a relevant data flow sink.
*/
predicate isSink(Node sink) { none() }
/**
* Holds if `sink` is a relevant data flow sink accepting `state`.
*/
predicate isSink(Node sink, FlowState state) { none() }
/**
* Holds if data flow through `node` is prohibited. This completely removes
* `node` from the data flow graph.
*/
predicate isBarrier(Node node) { none() }
/**
* Holds if data flow through `node` is prohibited when the flow state is
* `state`.
*/
predicate isBarrier(Node node, FlowState state) { none() }
/** Holds if data flow into `node` is prohibited. */
predicate isBarrierIn(Node node) { none() }
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited when
* the flow state is `state`
*/
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
predicate isAdditionalFlowStep(Node node1, Node node2) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
* This step is only applicable in `state1` and updates the flow state to `state2`.
*/
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
none()
}
/**
* Holds if an arbitrary number of implicit read steps of content `c` may be
* taken at `node`.
*/
predicate allowImplicitRead(Node node, ContentSet c) { none() }
/**
* Gets the virtual dispatch branching limit when calculating field flow.
* This can be overridden to a smaller value to improve performance (a
* value of 0 disables field flow), or a larger value to get more results.
*/
int fieldFlowBranchLimit() { result = 2 }
/**
* Gets a data flow configuration feature to add restrictions to the set of
* valid flow paths.
*
* - `FeatureHasSourceCallContext`:
* Assume that sources have some existing call context to disallow
* conflicting return-flow directly following the source.
* - `FeatureHasSinkCallContext`:
* Assume that sinks have some existing call context to disallow
* conflicting argument-to-parameter flow directly preceding the sink.
* - `FeatureEqualSourceSinkCallContext`:
* Implies both of the above and additionally ensures that the entire flow
* path preserves the call context.
*
* These features are generally not relevant for typical end-to-end data flow
* queries, but should only be used for constructing paths that need to
* somehow be pluggable in another path context.
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* DEPRECATED: Use `FlowExploration<explorationLimit>` instead.
*
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
* measured in approximate number of interprocedural steps.
*/
deprecated int explorationLimit() { none() }
/**
* Holds if hidden nodes should be included in the data flow graph.
*
* This feature should only be used for debugging or when the data flow graph
* is not visualized (for example in a `path-problem` query).
*/
predicate includeHiddenNodes() { none() }
}
/**
* This class exists to prevent mutual recursion between the user-overridden
* member predicates of `Configuration` and the rest of the data-flow library.
* Good performance cannot be guaranteed in the presence of such recursion, so
* it should be replaced by using more than one copy of the data flow library.
*/
abstract private class ConfigurationRecursionPrevention extends Configuration {
bindingset[this]
ConfigurationRecursionPrevention() { any() }
override predicate hasFlow(Node source, Node sink) {
strictcount(Node n | this.isSource(n)) < 0
or
strictcount(Node n | this.isSource(n, _)) < 0
or
strictcount(Node n | this.isSink(n)) < 0
or
strictcount(Node n | this.isSink(n, _)) < 0
or
strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0
or
strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0
or
super.hasFlow(source, sink)
}
}
/** A bridge class to access the deprecated `isBarrierGuard`. */
private class BarrierGuardGuardedNodeBridge extends Unit {
abstract predicate guardedNode(Node n, Configuration config);
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
}
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
deprecated override predicate guardedNode(Node n, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g) and
n = g.getAGuardedNode()
)
}
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g, state) and
n = g.getAGuardedNode()
)
}
}
private FlowState relevantState(Configuration config) {
config.isSource(_, result) or
config.isSink(_, result) or
config.isBarrier(_, result) or
config.isAdditionalFlowStep(_, result, _, _) or
config.isAdditionalFlowStep(_, _, _, result)
}
private newtype TConfigState =
TMkConfigState(Configuration config, FlowState state) {
state = relevantState(config) or state instanceof FlowStateEmpty
}
private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) }
private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) }
private predicate singleConfiguration() { 1 = strictcount(Configuration c) }
private module Config implements FullStateConfigSig {
class FlowState = TConfigState;
predicate isSource(Node source, FlowState state) {
getConfig(state).isSource(source, getState(state))
or
getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty
}
predicate isSink(Node sink, FlowState state) {
getConfig(state).isSink(sink, getState(state))
or
getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty
}
predicate isBarrier(Node node) { none() }
predicate isBarrier(Node node, FlowState state) {
getConfig(state).isBarrier(node, getState(state)) or
getConfig(state).isBarrier(node) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getState(state), getConfig(state)) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getConfig(state))
}
predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) }
predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) }
predicate isAdditionalFlowStep(Node node1, Node node2) {
singleConfiguration() and
any(Configuration config).isAdditionalFlowStep(node1, node2)
}
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
getConfig(state2) = getConfig(state1)
or
not singleConfiguration() and
getConfig(state1).isAdditionalFlowStep(node1, node2) and
state2 = state1
}
predicate allowImplicitRead(Node node, ContentSet c) {
any(Configuration config).allowImplicitRead(node, c)
}
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) {
any(Configuration config).sourceGrouping(source, sourceGroup)
}
predicate sinkGrouping(Node sink, string sinkGroup) {
any(Configuration config).sinkGrouping(sink, sinkGroup)
}
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
}
private import Impl<Config> as I
import I
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof I::PathNode {
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { result = super.getNode() }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = getState(super.getState()) }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = getConfig(super.getState()) }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getASuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { super.isSourceGroup(group) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
}
private predicate hasFlow(Node source, Node sink, Configuration config) {
exists(PathNode source0, PathNode sink0 |
hasFlowPath(source0, sink0, config) and
source0.getNode() = source and
sink0.getNode() = sink
)
}
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
hasFlowPath(source, sink) and source.getConfiguration() = config
}
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }
predicate flowsTo = hasFlow/3;

View File

@@ -3,15 +3,18 @@ private import DataFlowImplSpecific::Public
import Cached
module DataFlowImplCommonPublic {
/** A state value to track during data flow. */
class FlowState = string;
/** Provides `FlowState = string`. */
module FlowStateString {
/** A state value to track during data flow. */
class FlowState = string;
/**
* The default state, which is used when the state is unspecified for a source
* or a sink.
*/
class FlowStateEmpty extends FlowState {
FlowStateEmpty() { this = "" }
/**
* The default state, which is used when the state is unspecified for a source
* or a sink.
*/
class FlowStateEmpty extends FlowState {
FlowStateEmpty() { this = "" }
}
}
private newtype TFlowFeature =

View File

@@ -478,3 +478,12 @@ predicate containerContent(Content c) {
c instanceof MapKeyContent or
c instanceof MapValueContent
}
/**
* Gets an additional term that is added to the `join` and `branch` computations to reflect
* an additional forward or backwards branching factor that is not taken into account
* when calculating the (virtual) dispatch cost.
*
* Argument `arg` is part of a path from a source to a sink, and `p` is the target parameter.
*/
int getAdditionalFlowIntoCallNodeTerm(ArgumentNode arg, ParameterNode p) { none() }

View File

@@ -0,0 +1,64 @@
/**
* Provides classes for performing local (intra-procedural) and
* global (inter-procedural) taint-tracking analyses.
*/
import TaintTrackingParameter::Public
private import TaintTrackingParameter::Private
private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> implements
DataFlowInternal::FullStateConfigSig
{
import Config
predicate isBarrier(DataFlow::Node node) {
Config::isBarrier(node) or defaultTaintSanitizer(node)
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
Config::isAdditionalFlowStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
Config::allowImplicitRead(node, c)
or
(
Config::isSink(node, _) or
Config::isAdditionalFlowStep(node, _) or
Config::isAdditionalFlowStep(node, _, _, _)
) and
defaultImplicitTaintRead(node, c)
}
}
/**
* Constructs a standard taint tracking computation.
*/
module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig {
private module Config0 implements DataFlowInternal::FullStateConfigSig {
import DataFlowInternal::DefaultState<Config>
import Config
}
private module C implements DataFlowInternal::FullStateConfigSig {
import AddTaintDefaults<Config0>
}
import DataFlowInternal::Impl<C>
}
/**
* Constructs a taint tracking computation using flow state.
*/
module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig {
private module Config0 implements DataFlowInternal::FullStateConfigSig {
import Config
}
private module C implements DataFlowInternal::FullStateConfigSig {
import AddTaintDefaults<Config0>
}
import DataFlowInternal::Impl<C>
}

View File

@@ -2,4 +2,5 @@ import semmle.code.java.dataflow.internal.TaintTrackingUtil as Public
module Private {
import semmle.code.java.dataflow.DataFlow::DataFlow as DataFlow
import semmle.code.java.dataflow.internal.DataFlowImpl as DataFlowInternal
}

View File

@@ -138,7 +138,8 @@ class ClassReflectivelyReadField extends ReflectivelyReadField {
* Consider all `JacksonSerializableField`s as reflectively read.
*/
class JacksonSerializableReflectivelyReadField extends ReflectivelyReadField,
JacksonSerializableField { }
JacksonSerializableField
{ }
/**
* A field that is used when applying Jackson mixins.

View File

@@ -94,7 +94,8 @@ abstract class ReflectivelyConstructedClass extends EntryPoint, Class {
/**
* Classes that are deserialized by Jackson are reflectively constructed.
*/
library class JacksonReflectivelyConstructedClass extends ReflectivelyConstructedClass instanceof JacksonDeserializableType {
library class JacksonReflectivelyConstructedClass extends ReflectivelyConstructedClass instanceof JacksonDeserializableType
{
override Callable getALiveCallable() {
// Constructors may be called by Jackson, if they are a no-arg, they have a suitable annotation,
// or inherit a suitable annotation through a mixin.
@@ -308,8 +309,8 @@ class FacesAccessibleMethodEntryPoint extends CallableEntryPoint {
* A Java Server Faces custom component, that is reflectively constructed by the framework when
* used in a view (JSP or facelet).
*/
class FacesComponentReflectivelyConstructedClass extends ReflectivelyConstructedClass instanceof FacesComponent {
}
class FacesComponentReflectivelyConstructedClass extends ReflectivelyConstructedClass instanceof FacesComponent
{ }
/**
* Entry point for EJB home interfaces.
@@ -459,5 +460,5 @@ class ArbitraryXmlEntryPoint extends ReflectivelyConstructedClass {
deprecated class ArbitraryXMLEntryPoint = ArbitraryXmlEntryPoint;
/** A Selenium PageObject, created by a call to PageFactory.initElements(..). */
class SeleniumPageObjectEntryPoint extends ReflectivelyConstructedClass instanceof SeleniumPageObject {
}
class SeleniumPageObjectEntryPoint extends ReflectivelyConstructedClass instanceof SeleniumPageObject
{ }

View File

@@ -33,8 +33,8 @@ class Struts1ActionEntryPoint extends EntryPoint, Class {
/**
* A struts 2 action class that is reflectively constructed.
*/
class Struts2ReflectivelyConstructedAction extends ReflectivelyConstructedClass instanceof Struts2ActionClass {
}
class Struts2ReflectivelyConstructedAction extends ReflectivelyConstructedClass instanceof Struts2ActionClass
{ }
/**
* A method called on a struts 2 action class when the action is activated.

View File

@@ -78,7 +78,8 @@ class JUnitCategory extends WhitelistedLiveClass {
/**
* A listener that will be reflectively constructed by TestNG.
*/
class TestNGReflectivelyConstructedListener extends ReflectivelyConstructedClass instanceof TestNGListenerImpl {
class TestNGReflectivelyConstructedListener extends ReflectivelyConstructedClass instanceof TestNGListenerImpl
{
// Consider any class that implements a TestNG listener interface to be live. Listeners can be
// specified on the command line, in `testng.xml` files and in Ant build files, so it is safest
// to assume that all such listeners are live.

View File

@@ -123,7 +123,8 @@ class StartServiceMethod extends Method {
/** Specifies that if an `Intent` is tainted, then so are its synthetic fields. */
private class IntentFieldsInheritTaint extends DataFlow::SyntheticFieldContent,
TaintInheritingContent {
TaintInheritingContent
{
IntentFieldsInheritTaint() { this.getField().matches("android.content.Intent.%") }
}

View File

@@ -35,6 +35,7 @@ private class SliceProviderLifecycleStep extends AdditionalValueStep {
}
private class SliceActionsInheritTaint extends DataFlow::SyntheticFieldContent,
TaintInheritingContent {
TaintInheritingContent
{
SliceActionsInheritTaint() { this.getField() = "androidx.slice.Slice.action" }
}

View File

@@ -11,7 +11,8 @@ private class ParseAsMethod extends Method {
}
}
private class TypeLiteralToParseAsFlowConfiguration extends DataFlowForSerializability::Configuration {
private class TypeLiteralToParseAsFlowConfiguration extends DataFlowForSerializability::Configuration
{
TypeLiteralToParseAsFlowConfiguration() {
this = "GoogleHttpClientApi::TypeLiteralToParseAsFlowConfiguration"
}

View File

@@ -91,7 +91,8 @@ private class FieldReferencedJacksonSerializableType extends JacksonSerializable
/** A type whose values may be deserialized by the Jackson JSON framework. */
abstract class JacksonDeserializableType extends Type { }
private class TypeLiteralToJacksonDatabindFlowConfiguration extends DataFlowForSerializability::Configuration {
private class TypeLiteralToJacksonDatabindFlowConfiguration extends DataFlowForSerializability::Configuration
{
TypeLiteralToJacksonDatabindFlowConfiguration() {
this = "TypeLiteralToJacksonDatabindFlowConfiguration"
}

View File

@@ -75,8 +75,8 @@ class ForbiddenSecurityConfigurationCallable extends ForbiddenCallable {
}
/** A method or constructor involving serialization that may not be called by an EJB. */
class ForbiddenSerializationCallable extends ForbiddenCallable instanceof ForbiddenSerializationMethod {
}
class ForbiddenSerializationCallable extends ForbiddenCallable instanceof ForbiddenSerializationMethod
{ }
/** A method or constructor involving network factory operations that may not be called by an EJB. */
class ForbiddenSetFactoryCallable extends ForbiddenCallable instanceof ForbiddenSetFactoryMethod { }

View File

@@ -115,7 +115,8 @@ private class IsWindowsFromApacheCommons extends IsWindowsGuard instanceof Field
IsWindowsFromApacheCommons() { isOsFromApacheCommons(this, "IS\\_OS\\_WINDOWS") }
}
private class IsSpecificWindowsVariantFromApacheCommons extends IsSpecificWindowsVariant instanceof FieldAccess {
private class IsSpecificWindowsVariantFromApacheCommons extends IsSpecificWindowsVariant instanceof FieldAccess
{
IsSpecificWindowsVariantFromApacheCommons() {
isOsFromApacheCommons(this, "IS\\_OS\\_WINDOWS\\_%")
}
@@ -125,7 +126,8 @@ private class IsUnixFromApacheCommons extends IsUnixGuard instanceof FieldAccess
IsUnixFromApacheCommons() { isOsFromApacheCommons(this, "IS\\_OS\\_UNIX") }
}
private class IsSpecificUnixVariantFromApacheCommons extends IsSpecificUnixVariant instanceof FieldAccess {
private class IsSpecificUnixVariantFromApacheCommons extends IsSpecificUnixVariant instanceof FieldAccess
{
IsSpecificUnixVariantFromApacheCommons() {
isOsFromApacheCommons(this,
[

View File

@@ -47,7 +47,8 @@ private class DefaultFragmentInjectionSink extends FragmentInjectionSink {
DefaultFragmentInjectionSink() { sinkNode(this, "fragment-injection") }
}
private class DefaultFragmentInjectionAdditionalTaintStep extends FragmentInjectionAdditionalTaintStep {
private class DefaultFragmentInjectionAdditionalTaintStep extends FragmentInjectionAdditionalTaintStep
{
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(ReflectiveClassIdentifierMethodAccess ma |
ma.getArgument(0) = n1.asExpr() and ma = n2.asExpr()

View File

@@ -45,7 +45,8 @@ class IntentUriPermissionManipulationAdditionalTaintStep extends Unit {
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
}
private class DefaultIntentUriPermissionManipulationSink extends IntentUriPermissionManipulationSink {
private class DefaultIntentUriPermissionManipulationSink extends IntentUriPermissionManipulationSink
{
DefaultIntentUriPermissionManipulationSink() {
exists(MethodAccess ma | ma.getMethod() instanceof ActivitySetResultMethod |
ma.getArgument(1) = this.asExpr()

View File

@@ -55,7 +55,8 @@ class JwtParserWithInsecureParseAdditionalFlowStep extends Unit {
}
/** A set of additional flow steps to consider when working with JWT parsing related data flows. */
private class DefaultJwtParserWithInsecureParseAdditionalFlowStep extends JwtParserWithInsecureParseAdditionalFlowStep {
private class DefaultJwtParserWithInsecureParseAdditionalFlowStep extends JwtParserWithInsecureParseAdditionalFlowStep
{
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
jwtParserStep(node1.asExpr(), node2.asExpr())
}

View File

@@ -34,7 +34,8 @@ private class DefaultRequestForgeryAdditionalTaintStep extends RequestForgeryAdd
}
}
private class TypePropertiesRequestForgeryAdditionalTaintStep extends RequestForgeryAdditionalTaintStep {
private class TypePropertiesRequestForgeryAdditionalTaintStep extends RequestForgeryAdditionalTaintStep
{
override predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ) {
exists(MethodAccess ma |
// Properties props = new Properties();

View File

@@ -8,9 +8,11 @@ import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.RequestForgery
/**
* DEPRECATED: Use `RequestForgeryConfiguration` module instead.
*
* A taint-tracking configuration characterising request-forgery risks.
*/
class RequestForgeryConfiguration extends TaintTracking::Configuration {
deprecated class RequestForgeryConfiguration extends TaintTracking::Configuration {
RequestForgeryConfiguration() { this = "Server-Side Request Forgery" }
override predicate isSource(DataFlow::Node source) {
@@ -29,3 +31,26 @@ class RequestForgeryConfiguration extends TaintTracking::Configuration {
override predicate isSanitizer(DataFlow::Node node) { node instanceof RequestForgerySanitizer }
}
/**
* A taint-tracking configuration characterising request-forgery risks.
*/
private module RequestForgeryConfiguration implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource and
// Exclude results of remote HTTP requests: fetching something else based on that result
// is no worse than following a redirect returned by the remote server, and typically
// we're requesting a resource via https which we trust to only send us to safe URLs.
not source.asExpr().(MethodAccess).getCallee() instanceof UrlConnectionGetInputStreamMethod
}
predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink }
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
any(RequestForgeryAdditionalTaintStep r).propagatesTaint(pred, succ)
}
predicate isBarrier(DataFlow::Node node) { node instanceof RequestForgerySanitizer }
}
module RequestForgeryFlow = TaintTracking::Make<RequestForgeryConfiguration>;

View File

@@ -25,8 +25,12 @@ private class TypeType extends RefType {
}
}
/** A data-flow configuration for identifying potentially-sensitive data flowing to a log output. */
class SensitiveLoggerConfiguration extends TaintTracking::Configuration {
/**
* DEPRECATED: Use `SensitiveLoggerConfiguration` module instead.
*
* A data-flow configuration for identifying potentially-sensitive data flowing to a log output.
*/
deprecated class SensitiveLoggerConfiguration extends TaintTracking::Configuration {
SensitiveLoggerConfiguration() { this = "SensitiveLoggerConfiguration" }
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CredentialExpr }
@@ -43,3 +47,22 @@ class SensitiveLoggerConfiguration extends TaintTracking::Configuration {
override predicate isSanitizerIn(Node node) { this.isSource(node) }
}
/** A data-flow configuration for identifying potentially-sensitive data flowing to a log output. */
private module SensitiveLoggerConfiguration implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CredentialExpr }
predicate isSink(DataFlow::Node sink) { sinkNode(sink, "logging") }
predicate isBarrier(DataFlow::Node sanitizer) {
sanitizer.asExpr() instanceof LiveLiteral or
sanitizer.getType() instanceof PrimitiveType or
sanitizer.getType() instanceof BoxedType or
sanitizer.getType() instanceof NumberType or
sanitizer.getType() instanceof TypeType
}
predicate isBarrierIn(Node node) { isSource(node) }
}
module SensitiveLoggerFlow = TaintTracking::Make<SensitiveLoggerConfiguration>;

View File

@@ -21,7 +21,8 @@ class SpelExpressionInjectionAdditionalTaintStep extends Unit {
}
/** A set of additional taint steps to consider when taint tracking SpEL related data flows. */
private class DefaultSpelExpressionInjectionAdditionalTaintStep extends SpelExpressionInjectionAdditionalTaintStep {
private class DefaultSpelExpressionInjectionAdditionalTaintStep extends SpelExpressionInjectionAdditionalTaintStep
{
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
expressionParsingStep(node1, node2)
}

View File

@@ -62,8 +62,8 @@ abstract class TemplateInjectionSanitizerWithState extends DataFlow::Node {
abstract predicate hasState(DataFlow::FlowState state);
}
private class DefaultTemplateInjectionSource extends TemplateInjectionSource instanceof RemoteFlowSource {
}
private class DefaultTemplateInjectionSource extends TemplateInjectionSource instanceof RemoteFlowSource
{ }
private class DefaultTemplateInjectionSink extends TemplateInjectionSink {
DefaultTemplateInjectionSink() { sinkNode(this, "ssti") }

View File

@@ -7,7 +7,7 @@ import semmle.code.java.frameworks.spring.SpringController
import semmle.code.java.frameworks.spring.SpringHttp
import semmle.code.java.frameworks.javaee.jsf.JSFRenderer
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking2
import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.dataflow.ExternalFlow
/** A sink that represent a method that outputs data without applying contextual output encoding. */
@@ -41,9 +41,9 @@ private class DefaultXssSink extends XssSink {
DefaultXssSink() {
sinkNode(this, "xss")
or
exists(XssVulnerableWriterSourceToWritingMethodFlowConfig writer, MethodAccess ma |
exists(MethodAccess ma |
ma.getMethod() instanceof WritingMethod and
writer.hasFlowToExpr(ma.getQualifier()) and
XssVulnerableWriterSourceToWritingMethodFlow::hasFlowToExpr(ma.getQualifier()) and
this.asExpr() = ma.getArgument(_)
)
}
@@ -60,22 +60,19 @@ private class DefaultXssSanitizer extends XssSanitizer {
}
/** A configuration that tracks data from a servlet writer to an output method. */
private class XssVulnerableWriterSourceToWritingMethodFlowConfig extends TaintTracking2::Configuration {
XssVulnerableWriterSourceToWritingMethodFlowConfig() {
this = "XSS::XssVulnerableWriterSourceToWritingMethodFlowConfig"
}
private module XssVulnerableWriterSourceToWritingMethodFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof XssVulnerableWriterSource }
override predicate isSource(DataFlow::Node src) {
src.asExpr() instanceof XssVulnerableWriterSource
}
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
sink.asExpr() = ma.getQualifier() and ma.getMethod() instanceof WritingMethod
)
}
}
private module XssVulnerableWriterSourceToWritingMethodFlow =
TaintTracking::Make<XssVulnerableWriterSourceToWritingMethodFlowConfig>;
/** A method that can be used to output data to an output stream or writer. */
private class WritingMethod extends Method {
WritingMethod() {

View File

@@ -198,7 +198,8 @@ private class DocumentBuilderConstruction extends MethodAccess {
}
}
private class SafeDocumentBuilderFactoryToDocumentBuilderConstructionFlowConfig extends DataFlow3::Configuration {
private class SafeDocumentBuilderFactoryToDocumentBuilderConstructionFlowConfig extends DataFlow3::Configuration
{
SafeDocumentBuilderFactoryToDocumentBuilderConstructionFlowConfig() {
this = "XmlParsers::SafeDocumentBuilderFactoryToDocumentBuilderConstructionFlowConfig"
}

View File

@@ -55,7 +55,8 @@ private predicate newTransformerOrTemplatesStep(DataFlow::Node n1, DataFlow::Nod
/**
* A data flow configuration for secure processing feature that is enabled on `TransformerFactory`.
*/
private class TransformerFactoryWithSecureProcessingFeatureFlowConfig extends DataFlow2::Configuration {
private class TransformerFactoryWithSecureProcessingFeatureFlowConfig extends DataFlow2::Configuration
{
TransformerFactoryWithSecureProcessingFeatureFlowConfig() {
this = "TransformerFactoryWithSecureProcessingFeatureFlowConfig"
}

View File

@@ -1,3 +1,7 @@
## 0.5.4
No user-facing changes.
## 0.5.3
### New Queries

View File

@@ -18,32 +18,33 @@ import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.security.PathCreation
import semmle.code.java.security.PathSanitizer
import DataFlow::PathGraph
import TaintedPathCommon
class TaintedPathConfig extends TaintTracking::Configuration {
TaintedPathConfig() { this = "TaintedPathConfig" }
module TaintedPathConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(PathCreation p).getAnInput()
or
sinkNode(sink, ["create-file", "read-file"])
}
override predicate isSanitizer(DataFlow::Node sanitizer) {
predicate isBarrier(DataFlow::Node sanitizer) {
sanitizer.getType() instanceof BoxedType or
sanitizer.getType() instanceof PrimitiveType or
sanitizer.getType() instanceof NumberType or
sanitizer instanceof PathInjectionSanitizer
}
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
any(TaintedPathAdditionalTaintStep s).step(n1, n2)
}
}
module TaintedPath = TaintTracking::Make<TaintedPathConfig>;
import TaintedPath::PathGraph
/**
* Gets the data-flow node at which to report a path ending at `sink`.
*
@@ -52,13 +53,13 @@ class TaintedPathConfig extends TaintTracking::Configuration {
* continue to report there; otherwise we report directly at `sink`.
*/
DataFlow::Node getReportingNode(DataFlow::Node sink) {
any(TaintedPathConfig c).hasFlowTo(sink) and
TaintedPath::hasFlowTo(sink) and
if exists(PathCreation pc | pc.getAnInput() = sink.asExpr())
then result.asExpr() = any(PathCreation pc | pc.getAnInput() = sink.asExpr())
else result = sink
}
from DataFlow::PathNode source, DataFlow::PathNode sink, TaintedPathConfig conf
where conf.hasFlowPath(source, sink)
from TaintedPath::PathNode source, TaintedPath::PathNode sink
where TaintedPath::hasFlowPath(source, sink)
select getReportingNode(sink.getNode()), source, sink, "This path depends on a $@.",
source.getNode(), "user-provided value"

View File

@@ -14,25 +14,26 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.XSS
import DataFlow::PathGraph
class XssConfig extends TaintTracking::Configuration {
XssConfig() { this = "XSSConfig" }
module XssConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink instanceof XssSink }
override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink }
predicate isBarrier(DataFlow::Node node) { node instanceof XssSanitizer }
override predicate isSanitizer(DataFlow::Node node) { node instanceof XssSanitizer }
predicate isBarrierOut(DataFlow::Node node) { node instanceof XssSinkBarrier }
override predicate isSanitizerOut(DataFlow::Node node) { node instanceof XssSinkBarrier }
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
any(XssAdditionalTaintStep s).step(node1, node2)
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, XssConfig conf
where conf.hasFlowPath(source, sink)
module XssFlow = TaintTracking::Make<XssConfig>;
import XssFlow::PathGraph
from XssFlow::PathNode source, XssFlow::PathNode sink
where XssFlow::hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to a $@.",
source.getNode(), "user-provided value"

View File

@@ -27,25 +27,29 @@ abstract private class InsecureNettyObjectCreation extends ClassInstanceExpr {
abstract string splittingType();
}
abstract private class RequestOrResponseSplittingInsecureNettyObjectCreation extends InsecureNettyObjectCreation {
abstract private class RequestOrResponseSplittingInsecureNettyObjectCreation extends InsecureNettyObjectCreation
{
override string splittingType() { result = "Request splitting or response splitting" }
}
/**
* Request splitting can allowing an attacker to inject/smuggle an additional HTTP request into the socket connection.
*/
abstract private class RequestSplittingInsecureNettyObjectCreation extends InsecureNettyObjectCreation {
abstract private class RequestSplittingInsecureNettyObjectCreation extends InsecureNettyObjectCreation
{
override string splittingType() { result = "Request splitting" }
}
/**
* Response splitting can lead to HTTP vulnerabilities like XSS and cache poisoning.
*/
abstract private class ResponseSplittingInsecureNettyObjectCreation extends InsecureNettyObjectCreation {
abstract private class ResponseSplittingInsecureNettyObjectCreation extends InsecureNettyObjectCreation
{
override string splittingType() { result = "Response splitting" }
}
private class InsecureDefaultHttpHeadersClassInstantiation extends RequestOrResponseSplittingInsecureNettyObjectCreation {
private class InsecureDefaultHttpHeadersClassInstantiation extends RequestOrResponseSplittingInsecureNettyObjectCreation
{
InsecureDefaultHttpHeadersClassInstantiation() {
this.getConstructedType()
.hasQualifiedName("io.netty.handler.codec.http",
@@ -54,21 +58,24 @@ private class InsecureDefaultHttpHeadersClassInstantiation extends RequestOrResp
}
}
private class InsecureDefaultHttpResponseClassInstantiation extends ResponseSplittingInsecureNettyObjectCreation {
private class InsecureDefaultHttpResponseClassInstantiation extends ResponseSplittingInsecureNettyObjectCreation
{
InsecureDefaultHttpResponseClassInstantiation() {
this.getConstructedType().hasQualifiedName("io.netty.handler.codec.http", "DefaultHttpResponse") and
vulnerableArgumentIndex = 2
}
}
private class InsecureDefaultHttpRequestClassInstantiation extends RequestSplittingInsecureNettyObjectCreation {
private class InsecureDefaultHttpRequestClassInstantiation extends RequestSplittingInsecureNettyObjectCreation
{
InsecureDefaultHttpRequestClassInstantiation() {
this.getConstructedType().hasQualifiedName("io.netty.handler.codec.http", "DefaultHttpRequest") and
vulnerableArgumentIndex = 3
}
}
private class InsecureDefaultFullHttpResponseClassInstantiation extends ResponseSplittingInsecureNettyObjectCreation {
private class InsecureDefaultFullHttpResponseClassInstantiation extends ResponseSplittingInsecureNettyObjectCreation
{
InsecureDefaultFullHttpResponseClassInstantiation() {
this.getConstructedType()
.hasQualifiedName("io.netty.handler.codec.http", "DefaultFullHttpResponse") and
@@ -76,7 +83,8 @@ private class InsecureDefaultFullHttpResponseClassInstantiation extends Response
}
}
private class InsecureDefaultFullHttpRequestClassInstantiation extends RequestSplittingInsecureNettyObjectCreation {
private class InsecureDefaultFullHttpRequestClassInstantiation extends RequestSplittingInsecureNettyObjectCreation
{
InsecureDefaultFullHttpRequestClassInstantiation() {
this.getConstructedType()
.hasQualifiedName("io.netty.handler.codec.http", "DefaultFullHttpRequest") and

View File

@@ -14,19 +14,16 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.ResponseSplitting
import DataFlow::PathGraph
class ResponseSplittingConfig extends TaintTracking::Configuration {
ResponseSplittingConfig() { this = "ResponseSplittingConfig" }
override predicate isSource(DataFlow::Node source) {
module ResponseSplittingConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource and
not source instanceof SafeHeaderSplittingSource
}
override predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink }
predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink }
override predicate isSanitizer(DataFlow::Node node) {
predicate isBarrier(DataFlow::Node node) {
node.getType() instanceof PrimitiveType
or
node.getType() instanceof BoxedType
@@ -45,8 +42,12 @@ class ResponseSplittingConfig extends TaintTracking::Configuration {
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, ResponseSplittingConfig conf
where conf.hasFlowPath(source, sink)
module ResponseSplitting = TaintTracking::Make<ResponseSplittingConfig>;
import ResponseSplitting::PathGraph
from ResponseSplitting::PathNode source, ResponseSplitting::PathNode sink
where ResponseSplitting::hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"This header depends on a $@, which may cause a response-splitting vulnerability.",
source.getNode(), "user-provided value"

View File

@@ -14,23 +14,24 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.ResponseSplitting
import DataFlow::PathGraph
class ResponseSplittingLocalConfig extends TaintTracking::Configuration {
ResponseSplittingLocalConfig() { this = "ResponseSplittingLocalConfig" }
module ResponseSplittingLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink }
override predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink }
override predicate isSanitizer(DataFlow::Node node) {
predicate isBarrier(DataFlow::Node node) {
node.getType() instanceof PrimitiveType or
node.getType() instanceof BoxedType
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, ResponseSplittingLocalConfig conf
where conf.hasFlowPath(source, sink)
module ResponseSplitting = TaintTracking::Make<ResponseSplittingLocalConfig>;
import ResponseSplitting::PathGraph
from ResponseSplitting::PathNode source, ResponseSplitting::PathNode sink
where ResponseSplitting::hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"This header depends on a $@, which may cause a response-splitting vulnerability.",
source.getNode(), "user-provided value"

View File

@@ -31,33 +31,27 @@ class PrintStackTraceMethod extends Method {
}
}
class ServletWriterSourceToPrintStackTraceMethodFlowConfig extends TaintTracking::Configuration {
ServletWriterSourceToPrintStackTraceMethodFlowConfig() {
this = "StackTraceExposure::ServletWriterSourceToPrintStackTraceMethodFlowConfig"
}
module ServletWriterSourceToPrintStackTraceMethodFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof XssVulnerableWriterSource }
override predicate isSource(DataFlow::Node src) {
src.asExpr() instanceof XssVulnerableWriterSource
}
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
sink.asExpr() = ma.getAnArgument() and ma.getMethod() instanceof PrintStackTraceMethod
)
}
}
module ServletWriterSourceToPrintStackTraceMethodFlow =
TaintTracking::Make<ServletWriterSourceToPrintStackTraceMethodFlowConfig>;
/**
* A call that uses `Throwable.printStackTrace()` on a stream that is connected
* to external output.
*/
predicate printsStackToWriter(MethodAccess call) {
exists(
ServletWriterSourceToPrintStackTraceMethodFlowConfig writerSource,
PrintStackTraceMethod printStackTrace
|
exists(PrintStackTraceMethod printStackTrace |
call.getMethod() = printStackTrace and
writerSource.hasFlowToExpr(call.getAnArgument())
ServletWriterSourceToPrintStackTraceMethodFlow::hasFlowToExpr(call.getAnArgument())
)
}
@@ -86,16 +80,15 @@ predicate stackTraceExpr(Expr exception, MethodAccess stackTraceString) {
)
}
class StackTraceStringToHttpResponseSinkFlowConfig extends TaintTracking::Configuration {
StackTraceStringToHttpResponseSinkFlowConfig() {
this = "StackTraceExposure::StackTraceStringToHttpResponseSinkFlowConfig"
}
module StackTraceStringToHttpResponseSinkFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { stackTraceExpr(_, src.asExpr()) }
override predicate isSource(DataFlow::Node src) { stackTraceExpr(_, src.asExpr()) }
override predicate isSink(DataFlow::Node sink) { sink instanceof InformationLeakSink }
predicate isSink(DataFlow::Node sink) { sink instanceof InformationLeakSink }
}
module StackTraceStringToHttpResponseSinkFlow =
TaintTracking::Make<StackTraceStringToHttpResponseSinkFlowConfig>;
/**
* A write of stack trace data to an external stream.
*/
@@ -109,9 +102,10 @@ predicate printsStackExternally(MethodAccess call, Expr stackTrace) {
* A stringified stack trace flows to an external sink.
*/
predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stackTrace) {
exists(MethodAccess stackTraceString, StackTraceStringToHttpResponseSinkFlowConfig conf |
exists(MethodAccess stackTraceString |
stackTraceExpr(stackTrace, stackTraceString) and
conf.hasFlow(DataFlow::exprNode(stackTraceString), externalExpr)
StackTraceStringToHttpResponseSinkFlow::hasFlow(DataFlow::exprNode(stackTraceString),
externalExpr)
)
}

View File

@@ -15,7 +15,6 @@ import java
import semmle.code.java.security.Encryption
import semmle.code.java.dataflow.TaintTracking
import DataFlow
import PathGraph
private class ShortStringLiteral extends StringLiteral {
ShortStringLiteral() { getValue().length() < 100 }
@@ -29,24 +28,26 @@ class BrokenAlgoLiteral extends ShortStringLiteral {
}
}
class InsecureCryptoConfiguration extends TaintTracking::Configuration {
InsecureCryptoConfiguration() { this = "BrokenCryptoAlgortihm::InsecureCryptoConfiguration" }
module InsecureCryptoConfiguration implements ConfigSig {
predicate isSource(Node n) { n.asExpr() instanceof BrokenAlgoLiteral }
override predicate isSource(Node n) { n.asExpr() instanceof BrokenAlgoLiteral }
predicate isSink(Node n) { exists(CryptoAlgoSpec c | n.asExpr() = c.getAlgoSpec()) }
override predicate isSink(Node n) { exists(CryptoAlgoSpec c | n.asExpr() = c.getAlgoSpec()) }
override predicate isSanitizer(DataFlow::Node node) {
predicate isBarrier(DataFlow::Node node) {
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
}
}
module InsecureCryptoFlow = TaintTracking::Make<InsecureCryptoConfiguration>;
import InsecureCryptoFlow::PathGraph
from
PathNode source, PathNode sink, CryptoAlgoSpec c, BrokenAlgoLiteral s,
InsecureCryptoConfiguration conf
InsecureCryptoFlow::PathNode source, InsecureCryptoFlow::PathNode sink, CryptoAlgoSpec c,
BrokenAlgoLiteral s
where
sink.getNode().asExpr() = c.getAlgoSpec() and
source.getNode().asExpr() = s and
conf.hasFlowPath(source, sink)
InsecureCryptoFlow::hasFlowPath(source, sink)
select c, source, sink, "Cryptographic algorithm $@ is weak and should not be used.", s,
s.getValue()

View File

@@ -16,7 +16,6 @@ import semmle.code.java.security.Encryption
import semmle.code.java.dataflow.TaintTracking
import DataFlow
import semmle.code.java.dispatch.VirtualDispatch
import PathGraph
private class ShortStringLiteral extends StringLiteral {
ShortStringLiteral() { this.getValue().length() < 100 }
@@ -51,26 +50,28 @@ class StringContainer extends RefType {
}
}
class InsecureCryptoConfiguration extends TaintTracking::Configuration {
InsecureCryptoConfiguration() { this = "InsecureCryptoConfiguration" }
module InsecureCryptoConfiguration implements ConfigSig {
predicate isSource(Node n) { n.asExpr() instanceof InsecureAlgoLiteral }
override predicate isSource(Node n) { n.asExpr() instanceof InsecureAlgoLiteral }
predicate isSink(Node n) { exists(CryptoAlgoSpec c | n.asExpr() = c.getAlgoSpec()) }
override predicate isSink(Node n) { exists(CryptoAlgoSpec c | n.asExpr() = c.getAlgoSpec()) }
override predicate isSanitizer(Node n) {
predicate isBarrier(Node n) {
objectToString(n.asExpr()) or
not n.getType().getErasure() instanceof StringContainer
}
}
module InsecureCryptoFlow = TaintTracking::Make<InsecureCryptoConfiguration>;
import InsecureCryptoFlow::PathGraph
from
PathNode source, PathNode sink, CryptoAlgoSpec c, InsecureAlgoLiteral s,
InsecureCryptoConfiguration conf
InsecureCryptoFlow::PathNode source, InsecureCryptoFlow::PathNode sink, CryptoAlgoSpec c,
InsecureAlgoLiteral s
where
sink.getNode().asExpr() = c.getAlgoSpec() and
source.getNode().asExpr() = s and
conf.hasFlowPath(source, sink)
InsecureCryptoFlow::hasFlowPath(source, sink)
select c, source, sink,
"Cryptographic algorithm $@ may not be secure, consider using a different algorithm.", s,
s.getValue()

View File

@@ -13,9 +13,9 @@
import java
import semmle.code.java.security.SensitiveLoggingQuery
import PathGraph
import SensitiveLoggerFlow::PathGraph
from SensitiveLoggerConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
from SensitiveLoggerFlow::PathNode source, SensitiveLoggerFlow::PathNode sink
where SensitiveLoggerFlow::hasFlowPath(source, sink)
select sink.getNode(), source, sink, "This $@ is written to a log file.", source.getNode(),
"potentially sensitive information"

View File

@@ -15,19 +15,16 @@
import java
import semmle.code.java.dataflow.FlowSources
import NumericCastCommon
import DataFlow::PathGraph
private class NumericCastFlowConfig extends TaintTracking::Configuration {
NumericCastFlowConfig() { this = "NumericCastTainted::RemoteUserInputToNumericNarrowingCastExpr" }
module NumericCastFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(NumericNarrowingCastExpr cast).getExpr() and
sink.asExpr() instanceof VarAccess
}
override predicate isSanitizer(DataFlow::Node node) {
predicate isBarrier(DataFlow::Node node) {
boundedRead(node.asExpr()) or
castCheck(node.asExpr()) or
node.getType() instanceof SmallType or
@@ -37,12 +34,14 @@ private class NumericCastFlowConfig extends TaintTracking::Configuration {
}
}
from
DataFlow::PathNode source, DataFlow::PathNode sink, NumericNarrowingCastExpr exp,
NumericCastFlowConfig conf
module NumericCastFlow = TaintTracking::Make<NumericCastFlowConfig>;
import NumericCastFlow::PathGraph
from NumericCastFlow::PathNode source, NumericCastFlow::PathNode sink, NumericNarrowingCastExpr exp
where
sink.getNode().asExpr() = exp.getExpr() and
conf.hasFlowPath(source, sink)
NumericCastFlow::hasFlowPath(source, sink)
select exp, source, sink,
"This cast to a narrower type depends on a $@, potentially causing truncation.", source.getNode(),
"user-provided value"

View File

@@ -15,20 +15,15 @@
import java
import semmle.code.java.dataflow.FlowSources
import NumericCastCommon
import DataFlow::PathGraph
private class NumericCastFlowConfig extends TaintTracking::Configuration {
NumericCastFlowConfig() {
this = "NumericCastTaintedLocal::LocalUserInputToNumericNarrowingCastExpr"
}
module NumericCastFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput }
override predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput }
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(NumericNarrowingCastExpr cast).getExpr()
}
override predicate isSanitizer(DataFlow::Node node) {
predicate isBarrier(DataFlow::Node node) {
boundedRead(node.asExpr()) or
castCheck(node.asExpr()) or
node.getType() instanceof SmallType or
@@ -37,13 +32,17 @@ private class NumericCastFlowConfig extends TaintTracking::Configuration {
}
}
module NumericCastFlow = TaintTracking::Make<NumericCastFlowConfig>;
import NumericCastFlow::PathGraph
from
DataFlow::PathNode source, DataFlow::PathNode sink, NumericNarrowingCastExpr exp,
VarAccess tainted, NumericCastFlowConfig conf
NumericCastFlow::PathNode source, NumericCastFlow::PathNode sink, NumericNarrowingCastExpr exp,
VarAccess tainted
where
exp.getExpr() = tainted and
sink.getNode().asExpr() = tainted and
conf.hasFlowPath(source, sink) and
NumericCastFlow::hasFlowPath(source, sink) and
not exists(RightShiftOp e | e.getShiftedVariable() = tainted.getVariable())
select exp, source, sink,
"This cast to a narrower type depends on a $@, potentially causing truncation.", source.getNode(),

View File

@@ -13,9 +13,9 @@
import java
import semmle.code.java.security.RequestForgeryConfig
import DataFlow::PathGraph
import RequestForgeryFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, RequestForgeryConfiguration conf
where conf.hasFlowPath(source, sink)
from RequestForgeryFlow::PathNode source, RequestForgeryFlow::PathNode sink
where RequestForgeryFlow::hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Potential server-side request forgery due to a $@.",
source.getNode(), "user-provided value"

View File

@@ -0,0 +1,3 @@
## 0.5.4
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.5.3
lastReleaseVersion: 0.5.4

View File

@@ -81,8 +81,8 @@ private class CompareSink extends ClientSuppliedIpUsedInSecurityCheckSink {
}
/** A data flow sink for sql operation. */
private class SqlOperationSink extends ClientSuppliedIpUsedInSecurityCheckSink instanceof QueryInjectionSink {
}
private class SqlOperationSink extends ClientSuppliedIpUsedInSecurityCheckSink instanceof QueryInjectionSink
{ }
/** A method that split string. */
class SplitMethod extends Method {

View File

@@ -1,5 +1,5 @@
name: codeql/java-queries
version: 0.5.4-dev
version: 0.5.5-dev
groups:
- java
- queries

View File

@@ -47,6 +47,20 @@ private predicate defaultSource(DataFlow::Node src) {
src.asExpr().(MethodAccess).getMethod().getName() = ["source", "taint"]
}
module DefaultFlowConf implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node n) { defaultSource(n) }
predicate isSink(DataFlow::Node n) {
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
}
int fieldFlowBranchLimit() { result = 1000 }
}
private module DefaultValueFlow = DataFlow::Make<DefaultFlowConf>;
private module DefaultTaintFlow = TaintTracking::Make<DefaultFlowConf>;
class DefaultValueFlowConf extends DataFlow::Configuration {
DefaultValueFlowConf() { this = "qltest:defaultValueFlowConf" }
@@ -76,6 +90,8 @@ private string getSourceArgString(DataFlow::Node src) {
src.asExpr().(MethodAccess).getAnArgument().(StringLiteral).getValue() = result
}
abstract class EnableLegacyConfiguration extends Unit { }
class InlineFlowTest extends InlineExpectationsTest {
InlineFlowTest() { this = "HasFlowTest" }
@@ -83,7 +99,7 @@ class InlineFlowTest extends InlineExpectationsTest {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasValueFlow" and
exists(DataFlow::Node src, DataFlow::Node sink | getValueFlowConfig().hasFlow(src, sink) |
exists(DataFlow::Node src, DataFlow::Node sink | hasValueFlow(src, sink) |
sink.getLocation() = location and
element = sink.toString() and
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
@@ -91,7 +107,7 @@ class InlineFlowTest extends InlineExpectationsTest {
or
tag = "hasTaintFlow" and
exists(DataFlow::Node src, DataFlow::Node sink |
getTaintFlowConfig().hasFlow(src, sink) and not getValueFlowConfig().hasFlow(src, sink)
hasTaintFlow(src, sink) and not hasValueFlow(src, sink)
|
sink.getLocation() = location and
element = sink.toString() and
@@ -99,6 +115,18 @@ class InlineFlowTest extends InlineExpectationsTest {
)
}
predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) {
if exists(EnableLegacyConfiguration e)
then getValueFlowConfig().hasFlow(src, sink)
else DefaultValueFlow::hasFlow(src, sink)
}
predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) {
if exists(EnableLegacyConfiguration e)
then getTaintFlowConfig().hasFlow(src, sink)
else DefaultTaintFlow::hasFlow(src, sink)
}
DataFlow::Configuration getValueFlowConfig() { result = any(DefaultValueFlowConf config) }
DataFlow::Configuration getTaintFlowConfig() { result = any(DefaultTaintFlowConf config) }

View File

@@ -1,7 +1,3 @@
import java
import semmle.code.java.dataflow.DataFlow
import TestUtilities.InlineFlowTest
class HasFlowTest extends InlineFlowTest {
override DataFlow::Configuration getTaintFlowConfig() { none() }
}

View File

@@ -42,31 +42,31 @@ public class Test {
public static void test1() {
Test t = new Test();
t.fluentNoop().fluentSet(source()).fluentNoop();
sink(t.get()); // $hasTaintFlow
sink(t.get()); // $hasValueFlow
}
public static void test2() {
Test t = new Test();
Test.identity(t).fluentNoop().fluentSet(source()).fluentNoop();
sink(t.get()); // $hasTaintFlow
sink(t.get()); // $hasValueFlow
}
public static void test3() {
Test t = new Test();
t.indirectlyFluentNoop().fluentSet(source()).fluentNoop();
sink(t.get()); // $hasTaintFlow
sink(t.get()); // $hasValueFlow
}
public static void testModel1() {
Test t = new Test();
t.indirectlyFluentNoop().modelledFluentMethod().fluentSet(source()).fluentNoop();
sink(t.get()); // $hasTaintFlow
sink(t.get()); // $hasValueFlow
}
public static void testModel2() {
Test t = new Test();
Test.modelledIdentity(t).indirectlyFluentNoop().modelledFluentMethod().fluentSet(source()).fluentNoop();
sink(t.get()); // $hasTaintFlow
sink(t.get()); // $hasValueFlow
}
}

View File

@@ -12,7 +12,3 @@ class IdentityModel extends ValuePreservingMethod {
override predicate returnsValue(int arg) { arg = 0 }
}
class HasFlowTest extends InlineFlowTest {
override DataFlow::Configuration getValueFlowConfig() { none() }
}

View File

@@ -14,54 +14,46 @@ predicate sink0(Node n) {
)
}
class Conf1 extends Configuration {
Conf1() { this = "inoutbarriers1" }
module Conf1 implements ConfigSig {
predicate isSource(Node n) { src0(n) }
override predicate isSource(Node n) { src0(n) }
override predicate isSink(Node n) { sink0(n) }
predicate isSink(Node n) { sink0(n) }
}
class Conf2 extends Configuration {
Conf2() { this = "inoutbarriers2" }
module Conf2 implements ConfigSig {
predicate isSource(Node n) { src0(n) }
override predicate isSource(Node n) { src0(n) }
predicate isSink(Node n) { sink0(n) }
override predicate isSink(Node n) { sink0(n) }
override predicate isBarrierIn(Node n) { src0(n) }
predicate isBarrierIn(Node n) { src0(n) }
}
class Conf3 extends Configuration {
Conf3() { this = "inoutbarriers3" }
module Conf3 implements ConfigSig {
predicate isSource(Node n) { src0(n) }
override predicate isSource(Node n) { src0(n) }
predicate isSink(Node n) { sink0(n) }
override predicate isSink(Node n) { sink0(n) }
override predicate isBarrierOut(Node n) { sink0(n) }
predicate isBarrierOut(Node n) { sink0(n) }
}
class Conf4 extends Configuration {
Conf4() { this = "inoutbarriers4" }
module Conf4 implements ConfigSig {
predicate isSource(Node n) { src0(n) }
override predicate isSource(Node n) { src0(n) }
predicate isSink(Node n) { sink0(n) }
override predicate isSink(Node n) { sink0(n) }
predicate isBarrierIn(Node n) { src0(n) }
override predicate isBarrierIn(Node n) { src0(n) }
override predicate isBarrierOut(Node n) { sink0(n) }
predicate isBarrierOut(Node n) { sink0(n) }
}
predicate flow(Node src, Node sink, string s) {
any(Conf1 c).hasFlow(src, sink) and s = "nobarrier"
Make<Conf1>::hasFlow(src, sink) and s = "nobarrier"
or
any(Conf2 c).hasFlow(src, sink) and s = "srcbarrier"
Make<Conf2>::hasFlow(src, sink) and s = "srcbarrier"
or
any(Conf3 c).hasFlow(src, sink) and s = "sinkbarrier"
Make<Conf3>::hasFlow(src, sink) and s = "sinkbarrier"
or
any(Conf4 c).hasFlow(src, sink) and s = "both"
Make<Conf4>::hasFlow(src, sink) and s = "both"
}
from Node src, Node sink, string s

View File

@@ -1,18 +1,19 @@
import java
import semmle.code.java.dataflow.DataFlow
import DataFlow
import PartialPathGraph
class Conf extends Configuration {
Conf() { this = "partial flow" }
module Config implements ConfigSig {
predicate isSource(Node n) { n.asExpr().(MethodAccess).getMethod().hasName("src") }
override predicate isSource(Node n) { n.asExpr().(MethodAccess).getMethod().hasName("src") }
override predicate isSink(Node n) { n.asExpr().(Argument).getCall().getCallee().hasName("sink") }
override int explorationLimit() { result = 10 }
predicate isSink(Node n) { n.asExpr().(Argument).getCall().getCallee().hasName("sink") }
}
from PartialPathNode n, int dist
where any(Conf c).hasPartialFlow(_, n, dist)
int explorationLimit() { result = 10 }
module PartialFlow = Make<Config>::FlowExploration<explorationLimit/0>;
import PartialFlow::PartialPathGraph
from PartialFlow::PartialPathNode n, int dist
where PartialFlow::hasPartialFlow(_, n, dist)
select dist, n

View File

@@ -1,18 +1,19 @@
import java
import semmle.code.java.dataflow.DataFlow
import DataFlow
import PartialPathGraph
class Conf extends Configuration {
Conf() { this = "partial flow" }
module Config implements ConfigSig {
predicate isSource(Node n) { n.asExpr().(MethodAccess).getMethod().hasName("src") }
override predicate isSource(Node n) { n.asExpr().(MethodAccess).getMethod().hasName("src") }
override predicate isSink(Node n) { n.asExpr().(Argument).getCall().getCallee().hasName("sink") }
override int explorationLimit() { result = 10 }
predicate isSink(Node n) { n.asExpr().(Argument).getCall().getCallee().hasName("sink") }
}
from PartialPathNode n, int dist
where any(Conf c).hasPartialFlowRev(n, _, dist)
int explorationLimit() { result = 10 }
module PartialFlow = Make<Config>::FlowExploration<explorationLimit/0>;
import PartialFlow::PartialPathGraph
from PartialFlow::PartialPathNode n, int dist
where PartialFlow::hasPartialFlowRev(n, _, dist)
select dist, n

View File

@@ -39,22 +39,26 @@ predicate step(Node n1, Node n2, string s1, string s2) {
predicate checkNode(Node n) { n.asExpr().(Argument).getCall().getCallee().hasName("check") }
class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest:state" }
module Conf implements DataFlow::StateConfigSig {
class FlowState = string;
override predicate isSource(Node n, FlowState s) { src(n, s) }
predicate isSource(Node n, FlowState s) { src(n, s) }
override predicate isSink(Node n, FlowState s) { sink(n, s) }
predicate isSink(Node n, FlowState s) { sink(n, s) }
override predicate isSanitizer(Node n, FlowState s) { bar(n, s) }
predicate isBarrier(Node n, FlowState s) { bar(n, s) }
override predicate isAdditionalTaintStep(Node n1, FlowState s1, Node n2, FlowState s2) {
predicate isAdditionalFlowStep(Node n1, FlowState s1, Node n2, FlowState s2) {
step(n1, n2, s1, s2)
}
override int explorationLimit() { result = 0 }
}
int explorationLimit() { result = 0 }
module Flow = TaintTracking::MakeWithState<Conf>;
module PartialFlow = Flow::FlowExploration<explorationLimit/0>;
class HasFlowTest extends InlineExpectationsTest {
HasFlowTest() { this = "HasFlowTest" }
@@ -62,16 +66,16 @@ class HasFlowTest extends InlineExpectationsTest {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "flow" and
exists(PathNode src, PathNode sink, Conf conf |
conf.hasFlowPath(src, sink) and
exists(Flow::PathNode src, Flow::PathNode sink |
Flow::hasFlowPath(src, sink) and
sink.getNode().getLocation() = location and
element = sink.toString() and
value = src.getState()
)
or
tag = "pFwd" and
exists(PartialPathNode src, PartialPathNode node, Conf conf |
conf.hasPartialFlow(src, node, _) and
exists(PartialFlow::PartialPathNode src, PartialFlow::PartialPathNode node |
PartialFlow::hasPartialFlow(src, node, _) and
checkNode(node.getNode()) and
node.getNode().getLocation() = location and
element = node.toString() and
@@ -79,8 +83,8 @@ class HasFlowTest extends InlineExpectationsTest {
)
or
tag = "pRev" and
exists(PartialPathNode node, PartialPathNode sink, Conf conf |
conf.hasPartialFlowRev(node, sink, _) and
exists(PartialFlow::PartialPathNode node, PartialFlow::PartialPathNode sink |
PartialFlow::hasPartialFlowRev(node, sink, _) and
checkNode(node.getNode()) and
node.getNode().getLocation() = location and
element = node.toString() and

View File

@@ -6,42 +6,44 @@ class A {
return "tainted";
}
public static void sink(Object o) { }
public static void test1() {
String bad = source(); // $ hasTaintFlow
String bad = source();
String good = "hi";
bad.formatted(good); // $ hasTaintFlow
good.formatted("a", bad, "b", good); // $ hasTaintFlow
String.format("%s%s", bad, good); // $ hasTaintFlow
String.format("%s", good);
String.format("%s %s %s %s %s %s %s %s %s %s ", "a", "a", "a", "a", "a", "a", "a", "a", "a", bad); // $ hasTaintFlow
sink(bad.formatted(good)); // $ hasTaintFlow
sink(good.formatted("a", bad, "b", good)); // $ hasTaintFlow
sink(String.format("%s%s", bad, good)); // $ hasTaintFlow
sink(String.format("%s", good));
sink(String.format("%s %s %s %s %s %s %s %s %s %s ", "a", "a", "a", "a", "a", "a", "a", "a", "a", bad)); // $ hasTaintFlow
}
public static void test2() {
String bad = source(); // $ hasTaintFlow
String bad = source();
Formatter f = new Formatter();
f.toString();
f.format("%s", bad); // $ hasTaintFlow
f.toString(); // $ hasTaintFlow
sink(f.toString());
sink(f.format("%s", bad)); // $ hasTaintFlow
sink(f.toString()); // $ hasTaintFlow
}
public static void test3() {
String bad = source(); // $ hasTaintFlow
String bad = source();
StringBuilder sb = new StringBuilder();
Formatter f = new Formatter(sb);
sb.toString(); // $ hasTaintFlow false positive
f.format("%s", bad); // $ hasTaintFlow
sb.toString(); // $ hasTaintFlow
sink(sb.toString()); // $ SPURIOUS: hasTaintFlow
sink(f.format("%s", bad)); // $ hasTaintFlow
sink(sb.toString()); // $ hasTaintFlow
}
public static void test4() {
String bad = source(); // $ hasTaintFlow
String bad = source();
StringBuilder sb = new StringBuilder();
sb.append(bad); // $ hasTaintFlow
sink(sb.append(bad)); // $ hasTaintFlow
new Formatter(sb).format("ok").toString(); // $ hasTaintFlow
sink(new Formatter(sb).format("ok").toString()); // $ hasTaintFlow
}
}
}

View File

@@ -1,8 +1,2 @@
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking
import TestUtilities.InlineFlowTest
class TaintFlowConf extends DefaultTaintFlowConf {
override predicate isSink(DataFlow::Node n) { n instanceof DataFlow::ExprNode }
}

View File

@@ -3,6 +3,10 @@ import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class TaintFlowConf extends DefaultTaintFlowConf {
override predicate isSource(DataFlow::Node n) {
super.isSource(n)

View File

@@ -2,6 +2,10 @@ import java
import semmle.code.java.dataflow.FlowSources
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class ProviderTaintFlowConf extends DefaultTaintFlowConf {
override predicate isSource(DataFlow::Node n) { n instanceof RemoteFlowSource }
}

View File

@@ -3,6 +3,10 @@ import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSources
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class Conf extends TaintTracking::Configuration {
Conf() { this = "test:AndroidExternalFlowConf" }

View File

@@ -2,6 +2,10 @@ import java
import TestUtilities.InlineFlowTest
import semmle.code.java.dataflow.FlowSources
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class SliceValueFlowConf extends DefaultValueFlowConf {
override predicate isSource(DataFlow::Node source) {
super.isSource(source) or source instanceof RemoteFlowSource

View File

@@ -2,6 +2,10 @@ import java
import semmle.code.java.dataflow.FlowSources
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class SourceValueFlowConf extends DefaultValueFlowConf {
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
}

View File

@@ -5,6 +5,10 @@ import semmle.code.java.security.XSS
import semmle.code.java.security.UrlRedirect
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest:frameworks:apache-http" }

View File

@@ -1,6 +1,10 @@
import java
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class FlowConf extends DefaultValueFlowConf {
override predicate isSink(DataFlow::Node n) { super.isSink(n) or sinkNode(n, "open-url") }
}

View File

@@ -3,6 +3,10 @@ import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest:frameworks:rabbitmq" }

View File

@@ -1,6 +1,10 @@
import java
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class FlowConf extends DefaultValueFlowConf {
override predicate isSink(DataFlow::Node n) { super.isSink(n) or sinkNode(n, "open-url") }
}

View File

@@ -2,6 +2,10 @@ import java
import semmle.code.java.dataflow.FlowSources
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class ValueFlowConf extends DataFlow::Configuration {
ValueFlowConf() { this = "ValueFlowConf" }

View File

@@ -2,6 +2,10 @@ import java
import semmle.code.java.security.PathSanitizer
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class PathSanitizerConf extends DefaultTaintFlowConf {
override predicate isSanitizer(DataFlow::Node sanitizer) {
sanitizer instanceof PathInjectionSanitizer

View File

@@ -2,6 +2,10 @@ import java
import TestUtilities.InlineFlowTest
import semmle.code.java.security.PartialPathTraversalQuery
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class TestRemoteSource extends RemoteFlowSource {
TestRemoteSource() { this.asParameter().hasName(["dir", "path"]) }

View File

@@ -2,6 +2,10 @@ import java
import semmle.code.java.security.LogInjectionQuery
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
private class TestSource extends RemoteFlowSource {
TestSource() { this.asExpr().(MethodAccess).getMethod().hasName("source") }

View File

@@ -2,6 +2,10 @@ import java
import TestUtilities.InlineFlowTest
import semmle.code.java.security.IntentUriPermissionManipulationQuery
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class IntentUriPermissionManipulationTest extends InlineFlowTest {
override DataFlow::Configuration getValueFlowConfig() { none() }

View File

@@ -2,6 +2,10 @@ import java
import semmle.code.java.security.InsecureTrustManagerQuery
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class InsecureTrustManagerTest extends InlineFlowTest {
override DataFlow::Configuration getValueFlowConfig() {
result = any(InsecureTrustManagerConfiguration c)

View File

@@ -2,6 +2,10 @@ import java
import TestUtilities.InlineFlowTest
import semmle.code.java.security.UnsafeContentUriResolutionQuery
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class Test extends InlineFlowTest {
override DataFlow::Configuration getValueFlowConfig() { none() }

View File

@@ -2,6 +2,10 @@ import java
import semmle.code.java.security.FragmentInjectionQuery
import TestUtilities.InlineFlowTest
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class Test extends InlineFlowTest {
override DataFlow::Configuration getValueFlowConfig() { none() }

View File

@@ -2,6 +2,10 @@ import java
import TestUtilities.InlineFlowTest
import semmle.code.java.security.WebviewDubuggingEnabledQuery
class EnableLegacy extends EnableLegacyConfiguration {
EnableLegacy() { exists(this) }
}
class HasFlowTest extends InlineFlowTest {
override DataFlow::Configuration getTaintFlowConfig() { none() }

View File

@@ -3,9 +3,9 @@ import TestUtilities.InlineFlowTest
import semmle.code.java.security.SensitiveLoggingQuery
class HasFlowTest extends InlineFlowTest {
override DataFlow::Configuration getTaintFlowConfig() {
result instanceof SensitiveLoggerConfiguration
override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) {
SensitiveLoggerFlow::hasFlow(src, sink)
}
override DataFlow::Configuration getValueFlowConfig() { none() }
override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() }
}

Some files were not shown because too many files have changed in this diff Show More