mirror of
https://github.com/github/codeql.git
synced 2026-05-02 12:15:17 +02:00
Java: Convert security queries to path-problems.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name Uncontrolled data used in path expression
|
||||
* @description Accessing paths influenced by users can allow an attacker to access unexpected resources.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/path-injection
|
||||
@@ -15,6 +15,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import PathsCommon
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class TaintedPathConfig extends TaintTracking::Configuration {
|
||||
TaintedPathConfig() { this = "TaintedPathConfig" }
|
||||
@@ -30,8 +31,9 @@ class TaintedPathConfig extends TaintTracking::Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
from RemoteUserInput u, PathCreation p, Expr e, TaintedPathConfig conf
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, PathCreation p, TaintedPathConfig conf
|
||||
where
|
||||
e = p.getInput() and
|
||||
conf.hasFlow(u, DataFlow::exprNode(e))
|
||||
select p, "$@ flows to here and is used in a path.", u, "User-provided value"
|
||||
sink.getNode().asExpr() = p.getInput() and
|
||||
conf.hasFlowPath(source, sink)
|
||||
select p, source, sink, "$@ flows to here and is used in a path.", source.getNode(),
|
||||
"User-provided value"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name Local-user-controlled data in path expression
|
||||
* @description Accessing paths influenced by users can allow an attacker to access unexpected resources.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/path-injection-local
|
||||
@@ -15,6 +15,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import PathsCommon
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class TaintedPathLocalConfig extends TaintTracking::Configuration {
|
||||
TaintedPathLocalConfig() { this = "TaintedPathLocalConfig" }
|
||||
@@ -24,9 +25,13 @@ class TaintedPathLocalConfig extends TaintTracking::Configuration {
|
||||
override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(PathCreation p).getInput() }
|
||||
}
|
||||
|
||||
from LocalUserInput u, PathCreation p, Expr e, TaintedPathLocalConfig conf
|
||||
from
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, PathCreation p, Expr e,
|
||||
TaintedPathLocalConfig conf
|
||||
where
|
||||
e = sink.getNode().asExpr() and
|
||||
e = p.getInput() and
|
||||
conf.hasFlow(u, DataFlow::exprNode(e)) and
|
||||
conf.hasFlowPath(source, sink) and
|
||||
not guarded(e)
|
||||
select p, "$@ flows to here and is used in a path.", u, "User-provided value"
|
||||
select p, source, sink, "$@ flows to here and is used in a path.", source.getNode(),
|
||||
"User-provided value"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @description Extracting files from a malicious archive without validating that the
|
||||
* destination file path is within the destination directory can cause files outside
|
||||
* the destination directory to be overwritten.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @id java/zipslip
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
@@ -16,6 +16,7 @@ import semmle.code.java.controlflow.Guards
|
||||
import semmle.code.java.dataflow.SSA
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import DataFlow
|
||||
import PathGraph
|
||||
|
||||
/**
|
||||
* A method that returns the name of an archive entry.
|
||||
@@ -170,7 +171,8 @@ class ZipSlipConfiguration extends TaintTracking::Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
from Node source, Node sink
|
||||
where any(ZipSlipConfiguration c).hasFlow(source, sink)
|
||||
select source, "Unsanitized archive entry, which may contain '..', is used in a $@.", sink,
|
||||
from PathNode source, PathNode sink
|
||||
where any(ZipSlipConfiguration c).hasFlowPath(source, sink)
|
||||
select source.getNode(), source, sink,
|
||||
"Unsanitized archive entry, which may contain '..', is used in a $@.", sink.getNode(),
|
||||
"file system operation"
|
||||
|
||||
@@ -20,8 +20,8 @@ private class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking::C
|
||||
* so that it can be excluded from `ExecUnescaped.ql` to avoid
|
||||
* reporting overlapping results.
|
||||
*/
|
||||
predicate execTainted(RemoteUserInput source, ArgumentToExec execArg) {
|
||||
predicate execTainted(DataFlow::PathNode source, DataFlow::PathNode sink, ArgumentToExec execArg) {
|
||||
exists(RemoteUserInputToArgumentToExecFlowConfig conf |
|
||||
conf.hasFlow(source, DataFlow::exprNode(execArg))
|
||||
conf.hasFlowPath(source, sink) and sink.getNode() = DataFlow::exprNode(execArg)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Uncontrolled command line
|
||||
* @description Using externally controlled strings in a command line is vulnerable to malicious
|
||||
* changes in the strings.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/command-line-injection
|
||||
@@ -15,7 +15,9 @@ import semmle.code.java.Expr
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.security.ExternalProcess
|
||||
import ExecCommon
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from StringArgumentToExec execArg, RemoteUserInput origin
|
||||
where execTainted(origin, execArg)
|
||||
select execArg, "$@ flows to here and is used in a command.", origin, "User-provided value"
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, StringArgumentToExec execArg
|
||||
where execTainted(source, sink, execArg)
|
||||
select execArg, source, sink, "$@ flows to here and is used in a command.", source.getNode(),
|
||||
"User-provided value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Local-user-controlled command line
|
||||
* @description Using externally controlled strings in a command line is vulnerable to malicious
|
||||
* changes in the strings.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/command-line-injection-local
|
||||
@@ -14,6 +14,7 @@
|
||||
import semmle.code.java.Expr
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.security.ExternalProcess
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class LocalUserInputToArgumentToExecFlowConfig extends TaintTracking::Configuration {
|
||||
LocalUserInputToArgumentToExecFlowConfig() { this = "LocalUserInputToArgumentToExecFlowConfig" }
|
||||
@@ -28,6 +29,8 @@ class LocalUserInputToArgumentToExecFlowConfig extends TaintTracking::Configurat
|
||||
}
|
||||
|
||||
from
|
||||
StringArgumentToExec execArg, LocalUserInput origin, LocalUserInputToArgumentToExecFlowConfig conf
|
||||
where conf.hasFlow(origin, DataFlow::exprNode(execArg))
|
||||
select execArg, "$@ flows to here and is used in a command.", origin, "User-provided value"
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, StringArgumentToExec execArg,
|
||||
LocalUserInputToArgumentToExecFlowConfig conf
|
||||
where conf.hasFlowPath(source, sink) and sink.getNode().asExpr() = execArg
|
||||
select execArg, source, sink, "$@ flows to here and is used in a command.", source.getNode(),
|
||||
"User-provided value"
|
||||
|
||||
@@ -47,5 +47,5 @@ predicate builtFromUncontrolledConcat(Expr expr) {
|
||||
from StringArgumentToExec argument
|
||||
where
|
||||
builtFromUncontrolledConcat(argument) and
|
||||
not execTainted(_, argument)
|
||||
not execTainted(_, _, argument)
|
||||
select argument, "Command line is built with string concatenation."
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Cross-site scripting
|
||||
* @description Writing user input directly to a web page
|
||||
* allows for a cross-site scripting vulnerability.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/xss
|
||||
@@ -13,6 +13,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.security.XSS
|
||||
import DataFlow2::PathGraph
|
||||
|
||||
class XSSConfig extends TaintTracking::Configuration2 {
|
||||
XSSConfig() { this = "XSSConfig" }
|
||||
@@ -26,6 +27,7 @@ class XSSConfig extends TaintTracking::Configuration2 {
|
||||
}
|
||||
}
|
||||
|
||||
from XssSink sink, RemoteUserInput source, XSSConfig conf
|
||||
where conf.hasFlow(source, sink)
|
||||
select sink, "Cross-site scripting vulnerability due to $@.", source, "user-provided value"
|
||||
from DataFlow2::PathNode source, DataFlow2::PathNode sink, XSSConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.",
|
||||
source.getNode(), "user-provided value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Cross-site scripting from local source
|
||||
* @description Writing user input directly to a web page
|
||||
* allows for a cross-site scripting vulnerability.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/xss-local
|
||||
@@ -13,6 +13,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.security.XSS
|
||||
import DataFlow2::PathGraph
|
||||
|
||||
class XSSLocalConfig extends TaintTracking::Configuration2 {
|
||||
XSSLocalConfig() { this = "XSSLocalConfig" }
|
||||
@@ -22,6 +23,7 @@ class XSSLocalConfig extends TaintTracking::Configuration2 {
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink }
|
||||
}
|
||||
|
||||
from XssSink sink, LocalUserInput source, XSSLocalConfig conf
|
||||
where conf.hasFlow(source, sink)
|
||||
select sink, "Cross-site scripting vulnerability due to $@.", source, "user-provided value"
|
||||
from DataFlow2::PathNode source, DataFlow2::PathNode sink, XSSLocalConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.",
|
||||
source.getNode(), "user-provided value"
|
||||
|
||||
@@ -62,6 +62,8 @@ private class QueryInjectionFlowConfig extends TaintTracking::Configuration {
|
||||
* Implementation of `SqlTainted.ql`. This is extracted to a QLL so that it
|
||||
* can be excluded from `SqlUnescaped.ql` to avoid overlapping results.
|
||||
*/
|
||||
predicate queryTaintedBy(QueryInjectionSink query, RemoteUserInput source) {
|
||||
exists(QueryInjectionFlowConfig conf | conf.hasFlow(source, query))
|
||||
predicate queryTaintedBy(
|
||||
QueryInjectionSink query, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
) {
|
||||
exists(QueryInjectionFlowConfig conf | conf.hasFlowPath(source, sink) and sink.getNode() = query)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Query built from user-controlled sources
|
||||
* @description Building a SQL or Java Persistence query from user-controlled sources is vulnerable to insertion of
|
||||
* malicious code by the user.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/sql-injection
|
||||
@@ -13,7 +13,8 @@
|
||||
import semmle.code.java.Expr
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import SqlInjectionLib
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from QueryInjectionSink query, RemoteUserInput source
|
||||
where queryTaintedBy(query, source)
|
||||
select query, "Query might include code from $@.", source, "this user input"
|
||||
from QueryInjectionSink query, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where queryTaintedBy(query, source, sink)
|
||||
select query, source, sink, "Query might include code from $@.", source.getNode(), "this user input"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Query built from local-user-controlled sources
|
||||
* @description Building a SQL or Java Persistence query from user-controlled sources is vulnerable to insertion of
|
||||
* malicious code by the user.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/sql-injection-local
|
||||
@@ -13,6 +13,7 @@
|
||||
import semmle.code.java.Expr
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import SqlInjectionLib
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class LocalUserInputToQueryInjectionFlowConfig extends TaintTracking::Configuration {
|
||||
LocalUserInputToQueryInjectionFlowConfig() { this = "LocalUserInputToQueryInjectionFlowConfig" }
|
||||
@@ -26,6 +27,8 @@ class LocalUserInputToQueryInjectionFlowConfig extends TaintTracking::Configurat
|
||||
}
|
||||
}
|
||||
|
||||
from QueryInjectionSink query, LocalUserInput source, LocalUserInputToQueryInjectionFlowConfig conf
|
||||
where conf.hasFlow(source, query)
|
||||
select query, "Query might include code from $@.", source, "this user input"
|
||||
from
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, LocalUserInputToQueryInjectionFlowConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Query might include code from $@.", source.getNode(),
|
||||
"this user input"
|
||||
|
||||
@@ -46,6 +46,6 @@ where
|
||||
conf.hasFlow(DataFlow::exprNode(sbv.getToStringCall()), query)
|
||||
)
|
||||
) and
|
||||
not queryTaintedBy(query, _)
|
||||
not queryTaintedBy(query, _, _)
|
||||
select query, "Query might not neutralize special characters in $@.", uncontrolled,
|
||||
"this expression"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name HTTP response splitting
|
||||
* @description Writing user input directly to an HTTP header
|
||||
* makes code vulnerable to attack by header splitting.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/http-response-splitting
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
import java
|
||||
import ResponseSplitting
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class ResponseSplittingConfig extends TaintTracking::Configuration {
|
||||
ResponseSplittingConfig() { this = "ResponseSplittingConfig" }
|
||||
@@ -24,6 +25,7 @@ class ResponseSplittingConfig extends TaintTracking::Configuration {
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink }
|
||||
}
|
||||
|
||||
from HeaderSplittingSink sink, RemoteUserInput source, ResponseSplittingConfig conf
|
||||
where conf.hasFlow(source, sink)
|
||||
select sink, "Response-splitting vulnerability due to this $@.", source, "user-provided value"
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, ResponseSplittingConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Response-splitting vulnerability due to this $@.",
|
||||
source.getNode(), "user-provided value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name HTTP response splitting from local source
|
||||
* @description Writing user input directly to an HTTP header
|
||||
* makes code vulnerable to attack by header splitting.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/http-response-splitting-local
|
||||
@@ -13,6 +13,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import ResponseSplitting
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class ResponseSplittingLocalConfig extends TaintTracking::Configuration {
|
||||
ResponseSplittingLocalConfig() { this = "ResponseSplittingLocalConfig" }
|
||||
@@ -22,6 +23,7 @@ class ResponseSplittingLocalConfig extends TaintTracking::Configuration {
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink }
|
||||
}
|
||||
|
||||
from HeaderSplittingSink sink, LocalUserInput source, ResponseSplittingLocalConfig conf
|
||||
where conf.hasFlow(source, sink)
|
||||
select sink, "Response-splitting vulnerability due to this $@.", source, "user-provided value"
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, ResponseSplittingLocalConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Response-splitting vulnerability due to this $@.",
|
||||
source.getNode(), "user-provided value"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name Improper validation of user-provided size used for array construction
|
||||
* @description Using unvalidated external input as the argument to a construction of an array can lead to index out of bound exceptions.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @id java/improper-validation-of-array-construction
|
||||
@@ -12,6 +12,7 @@
|
||||
import java
|
||||
import ArraySizing
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "RemoteUserInputTocanThrowOutOfBoundsDueToEmptyArrayConfig" }
|
||||
@@ -24,11 +25,12 @@ class Conf extends TaintTracking::Configuration {
|
||||
}
|
||||
|
||||
from
|
||||
RemoteUserInput source, Expr sizeExpr, ArrayCreationExpr arrayCreation,
|
||||
CheckableArrayAccess arrayAccess
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, Expr sizeExpr,
|
||||
ArrayCreationExpr arrayCreation, CheckableArrayAccess arrayAccess
|
||||
where
|
||||
arrayAccess.canThrowOutOfBoundsDueToEmptyArray(sizeExpr, arrayCreation) and
|
||||
any(Conf conf).hasFlow(source, DataFlow::exprNode(sizeExpr))
|
||||
select arrayAccess.getIndexExpr(),
|
||||
sizeExpr = sink.getNode().asExpr() and
|
||||
any(Conf conf).hasFlowPath(source, sink)
|
||||
select arrayAccess.getIndexExpr(), source, sink,
|
||||
"The $@ is accessed here, but the array is initialized using $@ which may be zero.",
|
||||
arrayCreation, "array", source, "User-provided value"
|
||||
arrayCreation, "array", source.getNode(), "User-provided value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Improper validation of code-specified size used for array construction
|
||||
* @description Using a code-specified value that may be zero as the argument to
|
||||
* a construction of an array can lead to index out of bound exceptions.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/improper-validation-of-array-construction-code-specified
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
import java
|
||||
import ArraySizing
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class BoundedFlowSourceConf extends DataFlow::Configuration {
|
||||
BoundedFlowSourceConf() { this = "BoundedFlowSource" }
|
||||
@@ -28,11 +29,13 @@ class BoundedFlowSourceConf extends DataFlow::Configuration {
|
||||
}
|
||||
|
||||
from
|
||||
BoundedFlowSource source, Expr sizeExpr, ArrayCreationExpr arrayCreation,
|
||||
CheckableArrayAccess arrayAccess
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, BoundedFlowSource boundedsource,
|
||||
Expr sizeExpr, ArrayCreationExpr arrayCreation, CheckableArrayAccess arrayAccess
|
||||
where
|
||||
arrayAccess.canThrowOutOfBoundsDueToEmptyArray(sizeExpr, arrayCreation) and
|
||||
any(BoundedFlowSourceConf conf).hasFlow(source, DataFlow::exprNode(sizeExpr))
|
||||
select arrayAccess.getIndexExpr(),
|
||||
sizeExpr = sink.getNode().asExpr() and
|
||||
boundedsource = source.getNode() and
|
||||
any(BoundedFlowSourceConf conf).hasFlowPath(source, sink)
|
||||
select arrayAccess.getIndexExpr(), source, sink,
|
||||
"The $@ is accessed here, but the array is initialized using $@ which may be zero.",
|
||||
arrayCreation, "array", source, source.getDescription().toLowerCase()
|
||||
arrayCreation, "array", boundedsource, boundedsource.getDescription().toLowerCase()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Improper validation of local user-provided size used for array construction
|
||||
* @description Using unvalidated local input as the argument to
|
||||
* a construction of an array can lead to index out of bound exceptions.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/improper-validation-of-array-construction-local
|
||||
@@ -13,6 +13,7 @@
|
||||
import java
|
||||
import ArraySizing
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "LocalUserInputTocanThrowOutOfBoundsDueToEmptyArrayConfig" }
|
||||
@@ -25,11 +26,12 @@ class Conf extends TaintTracking::Configuration {
|
||||
}
|
||||
|
||||
from
|
||||
LocalUserInput source, Expr sizeExpr, ArrayCreationExpr arrayCreation,
|
||||
CheckableArrayAccess arrayAccess
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, Expr sizeExpr,
|
||||
ArrayCreationExpr arrayCreation, CheckableArrayAccess arrayAccess
|
||||
where
|
||||
arrayAccess.canThrowOutOfBoundsDueToEmptyArray(sizeExpr, arrayCreation) and
|
||||
any(Conf conf).hasFlow(source, DataFlow::exprNode(sizeExpr))
|
||||
select arrayAccess.getIndexExpr(),
|
||||
sizeExpr = sink.getNode().asExpr() and
|
||||
any(Conf conf).hasFlowPath(source, sink)
|
||||
select arrayAccess.getIndexExpr(), source, sink,
|
||||
"The $@ is accessed here, but the array is initialized using $@ which may be zero.",
|
||||
arrayCreation, "array", source, "User-provided value"
|
||||
arrayCreation, "array", source.getNode(), "User-provided value"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name Improper validation of user-provided array index
|
||||
* @description Using external input as an index to an array, without proper validation, can lead to index out of bound exceptions.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @id java/improper-validation-of-array-index
|
||||
@@ -12,6 +12,7 @@
|
||||
import java
|
||||
import ArraySizing
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "RemoteUserInputTocanThrowOutOfBoundsDueToEmptyArrayConfig" }
|
||||
@@ -25,10 +26,10 @@ class Conf extends TaintTracking::Configuration {
|
||||
override predicate isSanitizer(DataFlow::Node node) { node.getType() instanceof BooleanType }
|
||||
}
|
||||
|
||||
from RemoteUserInput source, Expr index, CheckableArrayAccess arrayAccess
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, CheckableArrayAccess arrayAccess
|
||||
where
|
||||
arrayAccess.canThrowOutOfBounds(index) and
|
||||
any(Conf conf).hasFlow(source, DataFlow::exprNode(index))
|
||||
select arrayAccess.getIndexExpr(),
|
||||
"$@ flows to here and is used as an index causing an ArrayIndexOutOfBoundsException.", source,
|
||||
"User-provided value"
|
||||
arrayAccess.canThrowOutOfBounds(sink.getNode().asExpr()) and
|
||||
any(Conf conf).hasFlowPath(source, sink)
|
||||
select arrayAccess.getIndexExpr(), source, sink,
|
||||
"$@ flows to here and is used as an index causing an ArrayIndexOutOfBoundsException.",
|
||||
source.getNode(), "User-provided value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Improper validation of code-specified array index
|
||||
* @description Using a code-specified value as an index to an array, without
|
||||
* proper validation, can lead to index out of bound exceptions.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/improper-validation-of-array-index-code-specified
|
||||
@@ -13,6 +13,7 @@
|
||||
import java
|
||||
import ArraySizing
|
||||
import BoundingChecks
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class BoundedFlowSourceConf extends DataFlow::Configuration {
|
||||
BoundedFlowSourceConf() { this = "BoundedFlowSource" }
|
||||
@@ -24,34 +25,34 @@ class BoundedFlowSourceConf extends DataFlow::Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
from BoundedFlowSource source, Expr index, CheckableArrayAccess arrayAccess
|
||||
from
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, BoundedFlowSource boundedsource,
|
||||
CheckableArrayAccess arrayAccess
|
||||
where
|
||||
arrayAccess.canThrowOutOfBounds(index) and
|
||||
any(BoundedFlowSourceConf conf).hasFlow(source, DataFlow::exprNode(index)) and
|
||||
source != DataFlow::exprNode(index) and
|
||||
arrayAccess.canThrowOutOfBounds(sink.getNode().asExpr()) and
|
||||
boundedsource = source.getNode() and
|
||||
any(BoundedFlowSourceConf conf).hasFlowPath(source, sink) and
|
||||
boundedsource != sink.getNode() and
|
||||
not (
|
||||
(
|
||||
// The input has a lower bound.
|
||||
source.lowerBound() >= 0
|
||||
boundedsource.lowerBound() >= 0
|
||||
or
|
||||
// There is a condition dominating this expression ensuring that the index is >= 0.
|
||||
lowerBound(arrayAccess.getIndexExpr()) >= 0
|
||||
) and
|
||||
(
|
||||
// The input has an upper bound, and the array has a fixed size, and that fixed size is less.
|
||||
source.upperBound() < fixedArraySize(arrayAccess)
|
||||
boundedsource.upperBound() < fixedArraySize(arrayAccess)
|
||||
or
|
||||
// There is a condition dominating this expression that ensures the index is less than the length.
|
||||
lessthanLength(arrayAccess)
|
||||
)
|
||||
) and
|
||||
/*
|
||||
* Exclude cases where the array is assigned multiple times. The checks for bounded flow sources
|
||||
* can use fixed sizes for arrays, but this doesn't work well when the array is initialized to zero
|
||||
* and subsequently reassigned or grown.
|
||||
*/
|
||||
|
||||
// Exclude cases where the array is assigned multiple times. The checks for bounded flow sources
|
||||
// can use fixed sizes for arrays, but this doesn't work well when the array is initialized to zero
|
||||
// and subsequently reassigned or grown.
|
||||
count(arrayAccess.getArray().(VarAccess).getVariable().getAnAssignedValue()) = 1
|
||||
select arrayAccess.getIndexExpr(),
|
||||
select arrayAccess.getIndexExpr(), source, sink,
|
||||
"$@ flows to the index used in this array access, and may cause the operation to throw an ArrayIndexOutOfBoundsException.",
|
||||
source, source.getDescription()
|
||||
boundedsource, boundedsource.getDescription()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Improper validation of local user-provided array index
|
||||
* @description Using local user input as an index to an array, without
|
||||
* proper validation, can lead to index out of bound exceptions.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/improper-validation-of-array-index-local
|
||||
@@ -13,6 +13,7 @@
|
||||
import java
|
||||
import ArraySizing
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "LocalUserInputTocanThrowOutOfBoundsDueToEmptyArrayConfig" }
|
||||
@@ -24,10 +25,10 @@ class Conf extends TaintTracking::Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
from LocalUserInput source, Expr index, CheckableArrayAccess arrayAccess
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, CheckableArrayAccess arrayAccess
|
||||
where
|
||||
arrayAccess.canThrowOutOfBounds(index) and
|
||||
any(Conf conf).hasFlow(source, DataFlow::exprNode(index))
|
||||
select arrayAccess.getIndexExpr(),
|
||||
"$@ flows to here and is used as an index causing an ArrayIndexOutOfBoundsException.", source,
|
||||
"User-provided value"
|
||||
arrayAccess.canThrowOutOfBounds(sink.getNode().asExpr()) and
|
||||
any(Conf conf).hasFlowPath(source, sink)
|
||||
select arrayAccess.getIndexExpr(), source, sink,
|
||||
"$@ flows to here and is used as an index causing an ArrayIndexOutOfBoundsException.",
|
||||
source.getNode(), "User-provided value"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name Use of externally-controlled format string
|
||||
* @description Using external input in format strings can lead to exceptions or information leaks.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/tainted-format-string
|
||||
@@ -12,6 +12,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.StringFormat
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class ExternallyControlledFormatStringConfig extends TaintTracking::Configuration {
|
||||
ExternallyControlledFormatStringConfig() { this = "ExternallyControlledFormatStringConfig" }
|
||||
@@ -27,7 +28,9 @@ class ExternallyControlledFormatStringConfig extends TaintTracking::Configuratio
|
||||
}
|
||||
}
|
||||
|
||||
from RemoteUserInput source, StringFormat formatCall, ExternallyControlledFormatStringConfig conf
|
||||
where conf.hasFlow(source, DataFlow::exprNode(formatCall.getFormatArgument()))
|
||||
select formatCall.getFormatArgument(), "$@ flows to here and is used in a format string.", source,
|
||||
"User-provided value"
|
||||
from
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, StringFormat formatCall,
|
||||
ExternallyControlledFormatStringConfig conf
|
||||
where conf.hasFlowPath(source, sink) and sink.getNode().asExpr() = formatCall.getFormatArgument()
|
||||
select formatCall.getFormatArgument(), source, sink,
|
||||
"$@ flows to here and is used in a format string.", source.getNode(), "User-provided value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name User-controlled data in arithmetic expression
|
||||
* @description Arithmetic operations on user-controlled data that is not validated can cause
|
||||
* overflows.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @id java/tainted-arithmetic
|
||||
@@ -14,6 +14,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import ArithmeticCommon
|
||||
import DataFlow::PathGraph
|
||||
|
||||
predicate sink(ArithExpr exp, VarAccess tainted, string effect) {
|
||||
exp.getAnOperand() = tainted and
|
||||
@@ -39,10 +40,11 @@ class RemoteUserInputConfig extends TaintTracking::Configuration {
|
||||
}
|
||||
|
||||
from
|
||||
ArithExpr exp, VarAccess tainted, RemoteUserInput origin, string effect,
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, ArithExpr exp, string effect,
|
||||
RemoteUserInputConfig conf
|
||||
where
|
||||
conf.hasFlow(origin, DataFlow::exprNode(tainted)) and
|
||||
sink(exp, tainted, effect)
|
||||
select exp, "$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".",
|
||||
origin, "User-provided value"
|
||||
conf.hasFlowPath(source, sink) and
|
||||
sink(exp, sink.getNode().asExpr(), effect)
|
||||
select exp, source, sink,
|
||||
"$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".",
|
||||
source.getNode(), "User-provided value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Local-user-controlled data in arithmetic expression
|
||||
* @description Arithmetic operations on user-controlled data that is not validated can cause
|
||||
* overflows.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/tainted-arithmetic-local
|
||||
@@ -14,6 +14,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import ArithmeticCommon
|
||||
import DataFlow::PathGraph
|
||||
|
||||
predicate sink(ArithExpr exp, VarAccess tainted, string effect) {
|
||||
exp.getAnOperand() = tainted and
|
||||
@@ -38,9 +39,10 @@ class ArithmeticTaintedLocalFlowConfig extends TaintTracking::Configuration {
|
||||
override predicate isSanitizer(DataFlow::Node n) { n.getType() instanceof BooleanType }
|
||||
}
|
||||
|
||||
from ArithExpr exp, VarAccess tainted, LocalUserInput origin, string effect
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, ArithExpr exp, string effect
|
||||
where
|
||||
any(ArithmeticTaintedLocalFlowConfig conf).hasFlow(origin, DataFlow::exprNode(tainted)) and
|
||||
sink(exp, tainted, effect)
|
||||
select exp, "$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".",
|
||||
origin, "User-provided value"
|
||||
any(ArithmeticTaintedLocalFlowConfig conf).hasFlowPath(source, sink) and
|
||||
sink(exp, sink.getNode().asExpr(), effect)
|
||||
select exp, source, sink,
|
||||
"$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".",
|
||||
source.getNode(), "User-provided value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Uncontrolled data in arithmetic expression
|
||||
* @description Arithmetic operations on uncontrolled data that is not validated can cause
|
||||
* overflows.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @id java/uncontrolled-arithmetic
|
||||
@@ -15,6 +15,7 @@ import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.security.SecurityTests
|
||||
import ArithmeticCommon
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class TaintSource extends DataFlow::ExprNode {
|
||||
TaintSource() {
|
||||
@@ -68,10 +69,11 @@ class ArithmeticUncontrolledFlowConfig extends TaintTracking::Configuration {
|
||||
}
|
||||
|
||||
from
|
||||
ArithExpr exp, VarAccess tainted, TaintSource origin, string effect,
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, ArithExpr exp, string effect,
|
||||
ArithmeticUncontrolledFlowConfig conf
|
||||
where
|
||||
conf.hasFlow(origin, DataFlow::exprNode(tainted)) and
|
||||
sink(exp, tainted, effect)
|
||||
select exp, "$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".",
|
||||
origin, "Uncontrolled value"
|
||||
conf.hasFlowPath(source, sink) and
|
||||
sink(exp, sink.getNode().asExpr(), effect)
|
||||
select exp, source, sink,
|
||||
"$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".",
|
||||
source.getNode(), "Uncontrolled value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Use of extreme values in arithmetic expression
|
||||
* @description If a variable is assigned the maximum or minimum value for that variable's type and
|
||||
* is then used in an arithmetic expression, this may result in an overflow.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/extreme-value-arithmetic
|
||||
@@ -15,6 +15,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import ArithmeticCommon
|
||||
import DataFlow::PathGraph
|
||||
|
||||
abstract class ExtremeValueField extends Field {
|
||||
ExtremeValueField() { getType() instanceof IntegralType }
|
||||
@@ -53,24 +54,27 @@ predicate sink(ArithExpr exp, VarAccess use) {
|
||||
}
|
||||
|
||||
predicate query(
|
||||
ArithExpr exp, Variable v, ExtremeValueField f, VarAccess use, ExtremeSource s, Type t
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, ArithExpr exp, Variable v,
|
||||
ExtremeValueField f, VarAccess use, ExtremeSource s, Type t
|
||||
) {
|
||||
// `use` is the use of `v` in `exp`.
|
||||
use = exp.getAnOperand() and
|
||||
use = v.getAnAccess() and
|
||||
// An extreme field flows to `use`.
|
||||
f = s.getVariable() and
|
||||
any(ExtremeSourceFlowConfig conf).hasFlow(DataFlow::exprNode(s), DataFlow::exprNode(use)) and
|
||||
any(ExtremeSourceFlowConfig conf).hasFlowPath(source, sink) and
|
||||
s = source.getNode().asExpr() and
|
||||
use = sink.getNode().asExpr() and
|
||||
t = s.getType() and
|
||||
// Division isn't a problem in this case.
|
||||
not exp instanceof DivExpr
|
||||
}
|
||||
|
||||
from
|
||||
ArithExpr exp, Variable v, ExtremeValueField f, VarAccess use, ExtremeSource s, string effect,
|
||||
Type t
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, ArithExpr exp, Variable v,
|
||||
ExtremeValueField f, VarAccess use, ExtremeSource s, string effect, Type t
|
||||
where
|
||||
query(exp, v, f, use, s, t) and
|
||||
query(source, sink, exp, v, f, use, s, t) and
|
||||
// We're not guarded against the appropriate kind of flow error.
|
||||
(
|
||||
f instanceof MinValueField and not guardedAgainstUnderflow(exp, use) and effect = "underflow"
|
||||
@@ -81,6 +85,6 @@ where
|
||||
// unless there is an enclosing cast down to a narrower type.
|
||||
narrowerThanOrEqualTo(exp, t) and
|
||||
not overflowIrrelevant(exp)
|
||||
select exp,
|
||||
select exp, source, sink,
|
||||
"Variable " + v.getName() + " is assigned an extreme value $@, and may cause an " + effect + ".",
|
||||
s, f.getName()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name Failure to use HTTPS URLs
|
||||
* @description Non-HTTPS connections can be intercepted by third parties.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/non-https-url
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class HTTPString extends StringLiteral {
|
||||
HTTPString() {
|
||||
@@ -73,8 +74,10 @@ class HTTPStringToURLOpenMethodFlowConfig extends TaintTracking::Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
from MethodAccess m, HTTPString s
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, MethodAccess m, HTTPString s
|
||||
where
|
||||
any(HTTPStringToURLOpenMethodFlowConfig c)
|
||||
.hasFlow(DataFlow::exprNode(s), DataFlow::exprNode(m.getQualifier()))
|
||||
select m, "URL may have been constructed with HTTP protocol, using $@.", s, "this source"
|
||||
source.getNode().asExpr() = s and
|
||||
sink.getNode().asExpr() = m.getQualifier() and
|
||||
any(HTTPStringToURLOpenMethodFlowConfig c).hasFlowPath(source, sink)
|
||||
select m, source, sink, "URL may have been constructed with HTTP protocol, using $@.", s,
|
||||
"this source"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name Use of a broken or risky cryptographic algorithm
|
||||
* @description Using broken or weak cryptographic algorithms can allow an attacker to compromise security.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @id java/weak-cryptographic-algorithm
|
||||
@@ -13,6 +13,7 @@ import java
|
||||
import semmle.code.java.security.Encryption
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import DataFlow
|
||||
import PathGraph
|
||||
|
||||
private class ShortStringLiteral extends StringLiteral {
|
||||
ShortStringLiteral() { getLiteral().length() < 100 }
|
||||
@@ -38,8 +39,12 @@ class InsecureCryptoConfiguration extends TaintTracking::Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
from CryptoAlgoSpec c, Expr a, BrokenAlgoLiteral s, InsecureCryptoConfiguration conf
|
||||
from
|
||||
PathNode source, PathNode sink, CryptoAlgoSpec c, BrokenAlgoLiteral s,
|
||||
InsecureCryptoConfiguration conf
|
||||
where
|
||||
a = c.getAlgoSpec() and
|
||||
conf.hasFlow(exprNode(s), exprNode(a))
|
||||
select c, "Cryptographic algorithm $@ is weak and should not be used.", s, s.getLiteral()
|
||||
sink.getNode().asExpr() = c.getAlgoSpec() and
|
||||
source.getNode().asExpr() = s and
|
||||
conf.hasFlowPath(source, sink)
|
||||
select c, source, sink, "Cryptographic algorithm $@ is weak and should not be used.", s,
|
||||
s.getLiteral()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name Use of a potentially broken or risky cryptographic algorithm
|
||||
* @description Using broken or weak cryptographic algorithms can allow an attacker to compromise security.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @id java/potentially-weak-cryptographic-algorithm
|
||||
@@ -14,6 +14,7 @@ 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() { getLiteral().length() < 100 }
|
||||
@@ -63,9 +64,13 @@ class InsecureCryptoConfiguration extends TaintTracking::Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
from CryptoAlgoSpec c, Expr a, InsecureAlgoLiteral s, InsecureCryptoConfiguration conf
|
||||
from
|
||||
PathNode source, PathNode sink, CryptoAlgoSpec c, InsecureAlgoLiteral s,
|
||||
InsecureCryptoConfiguration conf
|
||||
where
|
||||
a = c.getAlgoSpec() and
|
||||
conf.hasFlow(exprNode(s), exprNode(a))
|
||||
select c, "Cryptographic algorithm $@ may not be secure, consider using a different algorithm.", s,
|
||||
sink.getNode().asExpr() = c.getAlgoSpec() and
|
||||
source.getNode().asExpr() = s and
|
||||
conf.hasFlowPath(source, sink)
|
||||
select c, source, sink,
|
||||
"Cryptographic algorithm $@ may not be secure, consider using a different algorithm.", s,
|
||||
s.getLiteral()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Deserialization of user-controlled data
|
||||
* @description Deserializing user-controlled data may allow attackers to
|
||||
* execute arbitrary code.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/unsafe-deserialization
|
||||
@@ -13,6 +13,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import UnsafeDeserialization
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class UnsafeDeserializationConfig extends TaintTracking::Configuration {
|
||||
UnsafeDeserializationConfig() { this = "UnsafeDeserializationConfig" }
|
||||
@@ -22,6 +23,7 @@ class UnsafeDeserializationConfig extends TaintTracking::Configuration {
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserializationSink }
|
||||
}
|
||||
|
||||
from UnsafeDeserializationSink sink, RemoteUserInput source, UnsafeDeserializationConfig conf
|
||||
where conf.hasFlow(source, sink)
|
||||
select sink.getMethodAccess(), "Unsafe deserialization of $@.", source, "user input"
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, UnsafeDeserializationConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode().(UnsafeDeserializationSink).getMethodAccess(), source, sink,
|
||||
"Unsafe deserialization of $@.", source.getNode(), "user input"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name URL redirection from remote source
|
||||
* @description URL redirection based on unvalidated user-input
|
||||
* may cause redirection to malicious web sites.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/unvalidated-url-redirection
|
||||
@@ -13,6 +13,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import UrlRedirect
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class UrlRedirectConfig extends TaintTracking::Configuration {
|
||||
UrlRedirectConfig() { this = "UrlRedirectConfig" }
|
||||
@@ -22,6 +23,7 @@ class UrlRedirectConfig extends TaintTracking::Configuration {
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof UrlRedirectSink }
|
||||
}
|
||||
|
||||
from UrlRedirectSink sink, RemoteUserInput source, UrlRedirectConfig conf
|
||||
where conf.hasFlow(source, sink)
|
||||
select sink, "Potentially untrusted URL redirection due to $@.", source, "user-provided value"
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, UrlRedirectConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Potentially untrusted URL redirection due to $@.",
|
||||
source.getNode(), "user-provided value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name URL redirection from local source
|
||||
* @description URL redirection based on unvalidated user-input
|
||||
* may cause redirection to malicious web sites.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/unvalidated-url-redirection-local
|
||||
@@ -13,6 +13,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import UrlRedirect
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class UrlRedirectLocalConfig extends TaintTracking::Configuration {
|
||||
UrlRedirectLocalConfig() { this = "UrlRedirectLocalConfig" }
|
||||
@@ -22,6 +23,7 @@ class UrlRedirectLocalConfig extends TaintTracking::Configuration {
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof UrlRedirectSink }
|
||||
}
|
||||
|
||||
from UrlRedirectSink sink, LocalUserInput source, UrlRedirectLocalConfig conf
|
||||
where conf.hasFlow(source, sink)
|
||||
select sink, "Potentially untrusted URL redirection due to $@.", source, "user-provided value"
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, UrlRedirectLocalConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Potentially untrusted URL redirection due to $@.",
|
||||
source.getNode(), "user-provided value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Resolving XML external entity in user-controlled data
|
||||
* @description Parsing user-controlled XML documents and allowing expansion of external entity
|
||||
* references may lead to disclosure of confidential data or denial of service.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/xxe
|
||||
@@ -13,6 +13,7 @@
|
||||
import java
|
||||
import XmlParsers
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class SafeSAXSourceFlowConfig extends TaintTracking::Configuration2 {
|
||||
SafeSAXSourceFlowConfig() { this = "XmlParsers::SafeSAXSourceFlowConfig" }
|
||||
@@ -44,6 +45,7 @@ class XxeConfig extends TaintTracking::Configuration {
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeXxeSink }
|
||||
}
|
||||
|
||||
from UnsafeXxeSink sink, RemoteUserInput source, XxeConfig conf
|
||||
where conf.hasFlow(source, sink)
|
||||
select sink, "Unsafe parsing of XML file from $@.", source, "user input"
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, XxeConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Unsafe parsing of XML file from $@.", source.getNode(),
|
||||
"user input"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name User-controlled data in numeric cast
|
||||
* @description Casting user-controlled numeric data to a narrower type without validation
|
||||
* can cause unexpected truncation.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/tainted-numeric-cast
|
||||
@@ -14,6 +14,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import NumericCastCommon
|
||||
import DataFlow::PathGraph
|
||||
|
||||
private class NumericCastFlowConfig extends TaintTracking::Configuration {
|
||||
NumericCastFlowConfig() { this = "NumericCastTainted::RemoteUserInputToNumericNarrowingCastExpr" }
|
||||
@@ -34,11 +35,13 @@ private class NumericCastFlowConfig extends TaintTracking::Configuration {
|
||||
}
|
||||
|
||||
from
|
||||
NumericNarrowingCastExpr exp, VarAccess tainted, RemoteUserInput origin,
|
||||
NumericCastFlowConfig conf
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, NumericNarrowingCastExpr exp,
|
||||
VarAccess tainted, NumericCastFlowConfig conf
|
||||
where
|
||||
exp.getExpr() = tainted and
|
||||
conf.hasFlow(origin, DataFlow::exprNode(tainted)) and
|
||||
sink.getNode().asExpr() = tainted and
|
||||
conf.hasFlowPath(source, sink) and
|
||||
not exists(RightShiftOp e | e.getShiftedVariable() = tainted.getVariable())
|
||||
select exp, "$@ flows to here and is cast to a narrower type, potentially causing truncation.",
|
||||
origin, "User-provided value"
|
||||
select exp, source, sink,
|
||||
"$@ flows to here and is cast to a narrower type, potentially causing truncation.",
|
||||
source.getNode(), "User-provided value"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Local-user-controlled data in numeric cast
|
||||
* @description Casting user-controlled numeric data to a narrower type without validation
|
||||
* can cause unexpected truncation.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id java/tainted-numeric-cast-local
|
||||
@@ -14,6 +14,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import NumericCastCommon
|
||||
import DataFlow::PathGraph
|
||||
|
||||
private class NumericCastFlowConfig extends TaintTracking::Configuration {
|
||||
NumericCastFlowConfig() {
|
||||
@@ -36,10 +37,13 @@ private class NumericCastFlowConfig extends TaintTracking::Configuration {
|
||||
}
|
||||
|
||||
from
|
||||
NumericNarrowingCastExpr exp, VarAccess tainted, LocalUserInput origin, NumericCastFlowConfig conf
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, NumericNarrowingCastExpr exp,
|
||||
VarAccess tainted, NumericCastFlowConfig conf
|
||||
where
|
||||
exp.getExpr() = tainted and
|
||||
conf.hasFlow(origin, DataFlow::exprNode(tainted)) and
|
||||
sink.getNode().asExpr() = tainted and
|
||||
conf.hasFlowPath(source, sink) and
|
||||
not exists(RightShiftOp e | e.getShiftedVariable() = tainted.getVariable())
|
||||
select exp, "$@ flows to here and is cast to a narrower type, potentially causing truncation.",
|
||||
origin, "User-provided value"
|
||||
select exp, source, sink,
|
||||
"$@ flows to here and is cast to a narrower type, potentially causing truncation.",
|
||||
source.getNode(), "User-provided value"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name Hard-coded credential in API call
|
||||
* @description Using a hard-coded credential in a call to a sensitive Java API may compromise security.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision medium
|
||||
* @id java/hardcoded-credential-api-call
|
||||
@@ -12,6 +12,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import HardcodedCredentials
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration {
|
||||
HardcodedCredentialApiCallConfiguration() { this = "HardcodedCredentialApiCallConfiguration" }
|
||||
@@ -32,6 +33,8 @@ class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
from CredentialsApiSink sink, HardcodedExpr source, HardcodedCredentialApiCallConfiguration conf
|
||||
where conf.hasFlow(DataFlow::exprNode(source), DataFlow::exprNode(sink))
|
||||
select source, "Hard-coded value flows to $@.", sink, "sensitive API call"
|
||||
from
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, HardcodedCredentialApiCallConfiguration conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select source.getNode(), source, sink, "Hard-coded value flows to $@.", sink.getNode(),
|
||||
"sensitive API call"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name Hard-coded credential in sensitive call
|
||||
* @description Using a hard-coded credential in a sensitive call may compromise security.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision low
|
||||
* @id java/hardcoded-credential-sensitive-call
|
||||
@@ -13,6 +13,7 @@ import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.DataFlow2
|
||||
import HardcodedCredentials
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class HardcodedCredentialSourceCallConfiguration extends DataFlow::Configuration {
|
||||
HardcodedCredentialSourceCallConfiguration() {
|
||||
@@ -45,7 +46,8 @@ class FinalCredentialsSourceSink extends CredentialsSourceSink {
|
||||
}
|
||||
|
||||
from
|
||||
FinalCredentialsSourceSink sink, HardcodedExpr source,
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink,
|
||||
HardcodedCredentialSourceCallConfiguration conf
|
||||
where conf.hasFlow(DataFlow::exprNode(source), DataFlow::exprNode(sink))
|
||||
select source, "Hard-coded value flows to $@.", sink, "sensitive call"
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select source.getNode(), source, sink, "Hard-coded value flows to $@.", sink.getNode(),
|
||||
"sensitive call"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name User-controlled bypass of sensitive method
|
||||
* @description User-controlled bypassing of sensitive methods may allow attackers to avoid
|
||||
* passing through authentication systems.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/user-controlled-bypass
|
||||
@@ -16,6 +16,7 @@ import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.security.SensitiveActions
|
||||
import semmle.code.java.controlflow.Dominance
|
||||
import semmle.code.java.controlflow.Guards
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
* Calls to a sensitive method that are controlled by a condition
|
||||
@@ -38,9 +39,13 @@ class ConditionalBypassFlowConfig extends TaintTracking::Configuration {
|
||||
override predicate isSink(DataFlow::Node sink) { conditionControlsMethod(_, sink.asExpr()) }
|
||||
}
|
||||
|
||||
from UserInput u, MethodAccess m, Expr e, ConditionalBypassFlowConfig conf
|
||||
from
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, MethodAccess m, Expr e,
|
||||
ConditionalBypassFlowConfig conf
|
||||
where
|
||||
conditionControlsMethod(m, e) and
|
||||
conf.hasFlow(u, DataFlow::exprNode(e))
|
||||
select m, "Sensitive method may not be executed depending on $@, which flows from $@.", e,
|
||||
"this condition", u, "user input"
|
||||
sink.getNode().asExpr() = e and
|
||||
conf.hasFlowPath(source, sink)
|
||||
select m, source, sink,
|
||||
"Sensitive method may not be executed depending on $@, which flows from $@.", e, "this condition",
|
||||
source.getNode(), "user input"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name User-controlled data used in permissions check
|
||||
* @description Using user-controlled data in a permissions check may result in inappropriate
|
||||
* permissions being granted.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/tainted-permissions-check
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class TypeShiroSubject extends RefType {
|
||||
TypeShiroSubject() { this.getQualifiedName() = "org.apache.shiro.subject.Subject" }
|
||||
@@ -58,6 +59,8 @@ class TaintedPermissionsCheckFlowConfig extends TaintTracking::Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
from UserInput u, PermissionsConstruction p, TaintedPermissionsCheckFlowConfig conf
|
||||
where conf.hasFlow(u, DataFlow::exprNode(p.getInput()))
|
||||
select p, "Permissions check uses user-controlled $@.", u, "data"
|
||||
from
|
||||
DataFlow::PathNode source, DataFlow::PathNode sink, PermissionsConstruction p,
|
||||
TaintedPermissionsCheckFlowConfig conf
|
||||
where sink.getNode().asExpr() = p.getInput() and conf.hasFlowPath(source, sink)
|
||||
select p, source, sink, "Permissions check uses user-controlled $@.", source.getNode(), "data"
|
||||
|
||||
Reference in New Issue
Block a user