Compare commits

...

2 Commits

Author SHA1 Message Date
Jean Helie
3da0c9b62d Add generated models for spring framework 2023-07-04 15:56:01 +02:00
Jean Helie
045b270924 add Automodel specific version of the queries using ai-generated sink models 2023-07-04 15:42:53 +02:00
11 changed files with 7350 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,87 @@
private import java
private import semmle.code.java.dataflow.ExternalFlow as ExternalFlow
private import semmle.code.java.dataflow.TaintTracking::TaintTracking
/** Gets the models-as-data description for the method argument with the index `index`. */
bindingset[index]
private string getArgumentForIndex(int index) {
index = -1 and result = "Argument[this]"
or
index >= 0 and result = "Argument[" + index + "]"
}
private boolean considerSubtypes(Callable callable) {
if
callable.isStatic() or
callable.getDeclaringType().isStatic() or
callable.isFinal() or
callable.getDeclaringType().isFinal()
then result = false
else result = true
}
private class SinkModelExpr extends Expr {
predicate hasSignature(
string package, string type, boolean subtypes, string name, string signature, string input
) {
exists(Call call, Callable callable, int argIdx |
call.getCallee() = callable and
(
this = call.getArgument(argIdx)
or
this = call.getQualifier() and argIdx = -1
) and
input = getArgumentForIndex(argIdx) and
package = callable.getDeclaringType().getPackage().getName() and
type = callable.getDeclaringType().getErasure().(RefType).nestedName() and
subtypes = considerSubtypes(callable) and
name = callable.getName() and
signature = ExternalFlow::paramsString(callable)
)
}
}
private string pyBool(boolean b) {
b = true and result = "True"
or
b = false and result = "False"
}
/**
* Gets a string representation of the existing sink model at the expression `e`, in the format in
* which it would appear in a Models-as-Data file.
*/
string getSinkModelRepr(SinkModelExpr e) {
exists(
string package, string type, boolean subtypes, string name, string signature, string input,
string ext, string kind, string provenance
|
e.hasSignature(package, type, subtypes, name, signature, input) and
ExternalFlow::sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) and
provenance = "ai-generated" and
result =
"\"" + package + "\", \"" + type + "\", " + pyBool(subtypes) + ", \"" + name + "\", \"" +
signature + "\", \"" + ext + "\", \"" + input + "\", \"" + kind + "\", \"" + provenance +
"\""
)
}
/**
* Gets the string representation of a sink model in a format suitable for appending to an alert
* message.
*/
string getSinkModelQueryRepr(SinkModelExpr e) { result = "\nsinkModel: " + getSinkModelRepr(e) }
// TODO: make this logic more generic
// private predicate relevantSinkModel(int c, string s) {
// exists(RequestForgeryFlow::PathNode source, RequestForgeryFlow::PathNode sink |
// RequestForgeryFlow::flowPath(source, sink) and
// s = getSinkModelRepr(sink.getNode().asExpr())
// ) and
// c =
// count(RequestForgeryFlow::PathNode sink |
// exists(RequestForgeryFlow::PathNode source |
// RequestForgeryFlow::flowPath(source, sink) and
// s = getSinkModelRepr(sink.getNode().asExpr())
// )
// )
// }

View File

@@ -0,0 +1,41 @@
/**
* @name Uncontrolled data used in path expression
* @description Accessing paths influenced by users can allow an attacker to access unexpected resources.
* @kind path-problem
* @problem.severity error
* @security-severity 7.5
* @precision high
* @id java/path-injection-automodel
* @tags security
* external/cwe/cwe-022
* external/cwe/cwe-023
* external/cwe/cwe-036
* external/cwe/cwe-073
* ai-generated
*/
import java
import semmle.code.java.security.PathCreation
import semmle.code.java.security.TaintedPathQuery
import TaintedPathFlow::PathGraph
private import semmle.code.java.AutomodelSinkTriageUtils
/**
* Gets the data-flow node at which to report a path ending at `sink`.
*
* Previously this query flagged alerts exclusively at `PathCreation` sites,
* so to avoid perturbing existing alerts, where a `PathCreation` exists we
* continue to report there; otherwise we report directly at `sink`.
*/
DataFlow::Node getReportingNode(DataFlow::Node sink) {
TaintedPathFlow::flowTo(sink) and
if exists(PathCreation pc | pc.getAnInput() = sink.asExpr())
then result.asExpr() = any(PathCreation pc | pc.getAnInput() = sink.asExpr())
else result = sink
}
from TaintedPathFlow::PathNode source, TaintedPathFlow::PathNode sink
where TaintedPathFlow::flowPath(source, sink)
select getReportingNode(sink.getNode()), source, sink,
"This path depends on a $@." + getSinkModelQueryRepr(sink.getNode().asExpr()), source.getNode(),
"user-provided value"

View File

@@ -0,0 +1,27 @@
/**
* @name Uncontrolled command line
* @description Using externally controlled strings in a command line is vulnerable to malicious
* changes in the strings.
* @kind path-problem
* @problem.severity error
* @security-severity 9.8
* @precision high
* @id java/command-line-injection-automodel
* @tags security
* external/cwe/cwe-078
* external/cwe/cwe-088
* ai-generated
*/
import java
import semmle.code.java.security.CommandLineQuery
import RemoteUserInputToArgumentToExecFlow::PathGraph
private import semmle.code.java.AutomodelSinkTriageUtils
from
RemoteUserInputToArgumentToExecFlow::PathNode source,
RemoteUserInputToArgumentToExecFlow::PathNode sink, Expr execArg
where execIsTainted(source, sink, execArg)
select execArg, source, sink,
"This command line depends on a $@." + getSinkModelQueryRepr(sink.getNode().asExpr()),
source.getNode(), "user-provided value"

View File

@@ -0,0 +1,35 @@
/**
* @name Query built by concatenation with a possibly-untrusted string
* @description Building a SQL or Java Persistence query by concatenating a possibly-untrusted string
* is vulnerable to insertion of malicious code.
* @kind problem
* @problem.severity error
* @security-severity 8.8
* @precision medium
* @id java/concatenated-sql-query-automodel
* @tags security
* external/cwe/cwe-089
* external/cwe/cwe-564
* ai-generated
*/
import java
import semmle.code.java.security.SqlConcatenatedLib
import semmle.code.java.security.SqlInjectionQuery
import semmle.code.java.security.SqlConcatenatedQuery
private import semmle.code.java.AutomodelSinkTriageUtils
from QueryInjectionSink query, Expr uncontrolled
where
(
builtFromUncontrolledConcat(query.asExpr(), uncontrolled)
or
exists(StringBuilderVar sbv |
uncontrolledStringBuilderQuery(sbv, uncontrolled) and
UncontrolledStringBuilderSourceFlow::flow(DataFlow::exprNode(sbv.getToStringCall()), query)
)
) and
not queryIsTaintedBy(query, _, _)
select query,
"Query built by concatenation with $@, which may be untrusted." +
getSinkModelQueryRepr(query.asExpr()), uncontrolled, "this expression"

View File

@@ -0,0 +1,27 @@
/**
* @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 path-problem
* @problem.severity error
* @security-severity 8.8
* @precision high
* @id java/sql-injection-automodel
* @tags security
* external/cwe/cwe-089
* external/cwe/cwe-564
* ai-generated
*/
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.SqlInjectionQuery
import QueryInjectionFlow::PathGraph
private import semmle.code.java.AutomodelSinkTriageUtils
from
QueryInjectionSink query, QueryInjectionFlow::PathNode source, QueryInjectionFlow::PathNode sink
where queryIsTaintedBy(query, source, sink)
select query, source, sink,
"This query depends on a $@." + getSinkModelQueryRepr(sink.getNode().asExpr()), source.getNode(),
"user-provided value"

View File

@@ -0,0 +1,26 @@
/**
* @name Android missing certificate pinning
* @description Network connections that do not use certificate pinning may allow attackers to eavesdrop on communications.
* @kind problem
* @problem.severity warning
* @security-severity 5.9
* @precision medium
* @id java/android/missing-certificate-pinning-automodel
* @tags security
* external/cwe/cwe-295
* ai-generated
*/
import java
import semmle.code.java.security.AndroidCertificatePinningQuery
private import semmle.code.java.AutomodelSinkTriageUtils
from DataFlow::Node node, string domain, string msg
where
missingPinning(node, domain) and
if domain = ""
then msg = "(no explicitly trusted domains)"
else msg = "(" + domain + " is not trusted by a pin)"
select node,
"This network call does not implement certificate pinning. " + msg +
getSinkModelQueryRepr(node.asExpr())

View File

@@ -0,0 +1,24 @@
/**
* @name Insertion of sensitive information into log files
* @description Writing sensitive information to log files can allow that
* information to be leaked to an attacker more easily.
* @kind path-problem
* @problem.severity warning
* @security-severity 7.5
* @precision medium
* @id java/sensitive-log-automodel
* @tags security
* external/cwe/cwe-532
* ai-generated
*/
import java
import semmle.code.java.security.SensitiveLoggingQuery
import SensitiveLoggerFlow::PathGraph
private import semmle.code.java.AutomodelSinkTriageUtils
from SensitiveLoggerFlow::PathNode source, SensitiveLoggerFlow::PathNode sink
where SensitiveLoggerFlow::flowPath(source, sink)
select sink.getNode(), source, sink,
"This $@ is written to a log file." + getSinkModelQueryRepr(sink.getNode().asExpr()),
source.getNode(), "potentially sensitive information"

View File

@@ -0,0 +1,24 @@
/**
* @name URL redirection from remote source
* @description URL redirection based on unvalidated user-input
* may cause redirection to malicious web sites.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @precision high
* @id java/unvalidated-url-redirection-automodel
* @tags security
* external/cwe/cwe-601
* ai-generated
*/
import java
import semmle.code.java.security.UrlRedirectQuery
import UrlRedirectFlow::PathGraph
private import semmle.code.java.AutomodelSinkTriageUtils
from UrlRedirectFlow::PathNode source, UrlRedirectFlow::PathNode sink
where UrlRedirectFlow::flowPath(source, sink)
select sink.getNode(), source, sink,
"Untrusted URL redirection depends on a $@." + getSinkModelQueryRepr(sink.getNode().asExpr()),
source.getNode(), "user-provided value"

View File

@@ -0,0 +1,24 @@
/**
* @name Server-side request forgery
* @description Making web requests based on unvalidated user-input
* may cause the server to communicate with malicious servers.
* @kind path-problem
* @problem.severity error
* @security-severity 9.1
* @precision high
* @id java/ssrf-automodel
* @tags security
* external/cwe/cwe-918
* ai-generated
*/
import java
import semmle.code.java.security.RequestForgeryConfig
import RequestForgeryFlow::PathGraph
private import semmle.code.java.AutomodelSinkTriageUtils
from RequestForgeryFlow::PathNode source, RequestForgeryFlow::PathNode sink
where RequestForgeryFlow::flowPath(source, sink)
select sink.getNode(), source, sink,
"Potential server-side request forgery due to a $@." +
getSinkModelQueryRepr(sink.getNode().asExpr()), source.getNode(), "user-provided value"

File diff suppressed because it is too large Load Diff