Merge pull request #16297 from michaelnebel/java/improveapitelemetry

Java: Identify more APIs as supported in the telemetry queries.
This commit is contained in:
Michael Nebel
2024-05-03 12:34:19 +02:00
committed by GitHub
37 changed files with 334 additions and 97 deletions

View File

@@ -0,0 +1,39 @@
/** Provides classes representing various flow sinks for data flow / taint tracking. */
private import semmle.code.java.dataflow.FlowSinks as FlowSinks
final class SinkNode = FlowSinks::ApiSinkNode;
/**
* Module that adds all API like sinks to `SinkNode`, excluding sinks for cryptography based
* queries, and queries where sinks are not succifiently defined (eg. using broad method name matching).
*/
private module AllApiSinks {
private import semmle.code.java.security.AndroidSensitiveCommunicationQuery
private import semmle.code.java.security.ArbitraryApkInstallation
private import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery
private import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery
private import semmle.code.java.security.CleartextStorageCookieQuery
private import semmle.code.java.security.CleartextStorageSharedPrefsQuery
private import semmle.code.java.security.ExternallyControlledFormatStringQuery
private import semmle.code.java.security.InsecureBasicAuth
private import semmle.code.java.security.IntentUriPermissionManipulation
private import semmle.code.java.security.InsecureLdapAuth
private import semmle.code.java.security.InsecureTrustManager
private import semmle.code.java.security.JndiInjection
private import semmle.code.java.security.JWT
private import semmle.code.java.security.OgnlInjection
private import semmle.code.java.security.SensitiveResultReceiverQuery
private import semmle.code.java.security.SensitiveUiQuery
private import semmle.code.java.security.SpelInjection
private import semmle.code.java.security.SpelInjectionQuery
private import semmle.code.java.security.QueryInjection
private import semmle.code.java.security.TempDirLocalInformationDisclosureQuery
private import semmle.code.java.security.UnsafeAndroidAccess
private import semmle.code.java.security.UnsafeContentUriResolution
private import semmle.code.java.security.UnsafeDeserializationQuery
private import semmle.code.java.security.UrlRedirect
private import semmle.code.java.security.WebviewDebuggingEnabledQuery
private import semmle.code.java.security.XPath
private import semmle.code.java.security.XSS
}

View File

@@ -0,0 +1,23 @@
/** Provides classes representing various flow sources for data flow / taint tracking. */
private import semmle.code.java.dataflow.FlowSources as FlowSources
final class SourceNode = FlowSources::ApiSourceNode;
/**
* Module that adds all API like sources to `SourceNode`, excluding some sources for cryptography based
* queries, and queries where sources are not succifiently defined (eg. using broad method name matching).
*/
private module AllApiSources {
private import semmle.code.java.security.ArbitraryApkInstallation
private import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery
private import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery
private import semmle.code.java.security.CleartextStorageCookieQuery
private import semmle.code.java.security.CleartextStorageSharedPrefsQuery
private import semmle.code.java.security.ImplicitPendingIntentsQuery
private import semmle.code.java.security.ImproperIntentVerificationQuery
private import semmle.code.java.security.InsecureTrustManager
private import semmle.code.java.security.JWT
private import semmle.code.java.security.StackTraceExposureQuery
private import semmle.code.java.security.ZipSlipQuery
}

View File

@@ -0,0 +1,18 @@
/** Provides classes representing various flow sinks for data flow / taint tracking. */
private import java
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.DataFlow
/**
* A data flow sink node for an API, which should be considered
* supported for a modeling perspective.
*/
abstract class ApiSinkNode extends DataFlow::Node { }
/**
* Add all sink models as data sinks.
*/
private class ApiSinkNodeExternal extends ApiSinkNode {
ApiSinkNodeExternal() { sinkNode(this, _) }
}

View File

@@ -194,15 +194,17 @@ private class AndroidExternalStorageSource extends RemoteFlowSource {
}
/** Class for `tainted` user input. */
abstract class UserInput extends DataFlow::Node { }
abstract class UserInput extends SourceNode { }
/**
* Input that may be controlled by a remote user.
*/
private class RemoteUserInput extends UserInput instanceof RemoteFlowSource { }
private class RemoteUserInput extends UserInput instanceof RemoteFlowSource {
override string getThreatModel() { result = RemoteFlowSource.super.getThreatModel() }
}
/** A node with input that may be controlled by a local user. */
abstract class LocalUserInput extends UserInput, SourceNode {
abstract class LocalUserInput extends UserInput {
override string getThreatModel() { result = "local" }
}
@@ -385,3 +387,18 @@ class AndroidJavascriptInterfaceMethodParameter extends RemoteFlowSource {
result = "Parameter of method with JavascriptInterface annotation"
}
}
/**
* A data flow source node for an API, which should be considered
* supported for a modeling perspective.
*/
abstract class ApiSourceNode extends DataFlow::Node { }
private class AddSourceNodes extends ApiSourceNode instanceof SourceNode { }
/**
* Add all source models as data sources.
*/
private class ApiSourceNodeExternal extends ApiSourceNode {
ApiSourceNodeExternal() { sourceNode(this, _) }
}

View File

@@ -4,6 +4,7 @@ import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.frameworks.android.Intent
import semmle.code.java.security.SensitiveActions
private import semmle.code.java.dataflow.FlowSinks
/**
* Gets regular expression for matching names of Android variables that indicate the value being held contains sensitive information.
@@ -151,17 +152,24 @@ deprecated class SensitiveCommunicationConfig extends TaintTracking::Configurati
}
}
/**
* A sensitive communication sink node.
*/
private class SensitiveCommunicationSink extends ApiSinkNode {
SensitiveCommunicationSink() {
isSensitiveBroadcastSink(this)
or
isStartActivityOrServiceSink(this)
}
}
/**
* Taint configuration tracking flow from variables containing sensitive information to broadcast Intents.
*/
module SensitiveCommunicationConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof SensitiveInfoExpr }
predicate isSink(DataFlow::Node sink) {
isSensitiveBroadcastSink(sink)
or
isStartActivityOrServiceSink(sink)
}
predicate isSink(DataFlow::Node sink) { sink instanceof SensitiveCommunicationSink }
/**
* Holds if broadcast doesn't specify receiving package name of the 3rd party app

View File

@@ -4,6 +4,7 @@ import java
import semmle.code.java.frameworks.android.Intent
import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.FlowSources
/** A string literal that represents the MIME type for Android APKs. */
@@ -48,7 +49,7 @@ class SetDataMethod extends Method {
}
/** A dataflow sink for the URI of an intent. */
class SetDataSink extends DataFlow::ExprNode {
class SetDataSink extends ApiSinkNode, DataFlow::ExprNode {
SetDataSink() {
exists(MethodCall ma |
this.getExpr() = ma.getQualifier() and
@@ -69,7 +70,7 @@ class UriConstructorMethod extends Method {
* A dataflow source representing the URIs which an APK not controlled by the
* application may come from. Including external storage and web URLs.
*/
class ExternalApkSource extends DataFlow::Node {
class ExternalApkSource extends ApiSourceNode {
ExternalApkSource() {
sourceNode(this, "android-external-storage-dir") or
this.asExpr().(MethodCall).getMethod() instanceof UriConstructorMethod or

View File

@@ -6,6 +6,8 @@ import semmle.code.java.frameworks.android.ContentProviders
import semmle.code.java.frameworks.android.Intent
import semmle.code.java.frameworks.android.SQLite
import semmle.code.java.security.CleartextStorageQuery
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.FlowSources
private class LocalDatabaseCleartextStorageSink extends CleartextStorageSink {
LocalDatabaseCleartextStorageSink() { localDatabaseInput(_, this.asExpr()) }
@@ -96,15 +98,24 @@ private predicate localDatabaseStore(DataFlow::Node database, MethodCall store)
)
}
private module LocalDatabaseFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof LocalDatabaseOpenMethodCall
}
/**
* A local database open method call source node.
*/
private class LocalDatabaseOpenMethodCallSource extends ApiSourceNode {
LocalDatabaseOpenMethodCallSource() { this.asExpr() instanceof LocalDatabaseOpenMethodCall }
}
predicate isSink(DataFlow::Node sink) {
localDatabaseInput(sink, _) or
localDatabaseStore(sink, _)
}
/**
* A local database sink node.
*/
private class LocalDatabaseSink extends ApiSinkNode {
LocalDatabaseSink() { localDatabaseInput(this, _) or localDatabaseStore(this, _) }
}
private module LocalDatabaseFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalDatabaseOpenMethodCallSource }
predicate isSink(DataFlow::Node sink) { sink instanceof LocalDatabaseSink }
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
// Adds a step for tracking databases through field flow, that is, a database is opened and

View File

@@ -5,9 +5,11 @@
import java
import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.security.CleartextStorageQuery
import semmle.code.xml.AndroidManifest
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.FlowSources
private class AndroidFilesystemCleartextStorageSink extends CleartextStorageSink {
AndroidFilesystemCleartextStorageSink() {
@@ -79,13 +81,27 @@ private class CloseFileMethod extends Method {
}
}
private module FilesystemFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof LocalFileOpenCall }
/**
* A local file open call source node.
*/
private class LocalFileOpenCallSource extends ApiSourceNode {
LocalFileOpenCallSource() { this.asExpr() instanceof LocalFileOpenCall }
}
predicate isSink(DataFlow::Node sink) {
filesystemInput(sink, _) or
closesFile(sink, _)
/**
* A local file sink node.
*/
private class LocalFileSink extends ApiSinkNode {
LocalFileSink() {
filesystemInput(this, _) or
closesFile(this, _)
}
}
private module FilesystemFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src instanceof LocalFileOpenCallSource }
predicate isSink(DataFlow::Node sink) { sink instanceof LocalFileSink }
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
// Add nested Writer constructors as extra data flow steps

View File

@@ -4,6 +4,8 @@ import java
import semmle.code.java.dataflow.DataFlow
deprecated import semmle.code.java.dataflow.DataFlow3
import semmle.code.java.security.CleartextStorageQuery
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.FlowSources
private class CookieCleartextStorageSink extends CleartextStorageSink {
CookieCleartextStorageSink() { this.asExpr() = cookieInput(_) }
@@ -37,10 +39,24 @@ private predicate cookieStore(DataFlow::Node cookie, Expr store) {
)
}
private module CookieToStoreFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof Cookie }
/**
* A cookie source node.
*/
private class CookieSource extends ApiSourceNode {
CookieSource() { this.asExpr() instanceof Cookie }
}
predicate isSink(DataFlow::Node sink) { cookieStore(sink, _) }
/**
* A cookie store sink node.
*/
private class CookieStoreSink extends ApiSinkNode {
CookieStoreSink() { cookieStore(this, _) }
}
private module CookieToStoreFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src instanceof CookieSource }
predicate isSink(DataFlow::Node sink) { sink instanceof CookieStoreSink }
}
private module CookieToStoreFlow = DataFlow::Global<CookieToStoreFlowConfig>;

View File

@@ -4,6 +4,8 @@ import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.frameworks.android.SharedPreferences
import semmle.code.java.security.CleartextStorageQuery
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.FlowSources
private class SharedPrefsCleartextStorageSink extends CleartextStorageSink {
SharedPrefsCleartextStorageSink() {
@@ -67,16 +69,30 @@ private predicate sharedPreferencesStore(DataFlow::Node editor, MethodCall m) {
editor.asExpr() = m.getQualifier().getUnderlyingExpr()
}
/** Flow from `SharedPreferences.Editor` to either a setter or a store method. */
private module SharedPreferencesFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) {
src.asExpr() instanceof SharedPreferencesEditorMethodCall
}
predicate isSink(DataFlow::Node sink) {
sharedPreferencesInput(sink, _) or
sharedPreferencesStore(sink, _)
/**
* A shared preferences editor method call source node.
*/
private class SharedPreferencesEditorMethodCallSource extends ApiSourceNode {
SharedPreferencesEditorMethodCallSource() {
this.asExpr() instanceof SharedPreferencesEditorMethodCall
}
}
/**
* A shared preferences sink node.
*/
private class SharedPreferencesSink extends ApiSinkNode {
SharedPreferencesSink() {
sharedPreferencesInput(this, _) or
sharedPreferencesStore(this, _)
}
}
/** Flow from `SharedPreferences.Editor` to either a setter or a store method. */
private module SharedPreferencesFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src instanceof SharedPreferencesEditorMethodCallSource }
predicate isSink(DataFlow::Node sink) { sink instanceof SharedPreferencesSink }
}
private module SharedPreferencesFlow = DataFlow::Global<SharedPreferencesFlowConfig>;

View File

@@ -1,18 +1,24 @@
/** Provides a taint-tracking configuration to reason about externally controlled format string vulnerabilities. */
import java
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.StringFormat
/**
* A string format sink node.
*/
private class StringFormatSink extends ApiSinkNode {
StringFormatSink() { this.asExpr() = any(StringFormat formatCall).getFormatArgument() }
}
/**
* A taint-tracking configuration for externally controlled format string vulnerabilities.
*/
module ExternallyControlledFormatStringConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource }
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(StringFormat formatCall).getFormatArgument()
}
predicate isSink(DataFlow::Node sink) { sink instanceof StringFormatSink }
predicate isBarrier(DataFlow::Node node) {
node.getType() instanceof NumericType or node.getType() instanceof BooleanType

View File

@@ -2,8 +2,7 @@
import java
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.frameworks.android.Intent
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.frameworks.android.PendingIntent
private newtype TPendingIntentState =
@@ -27,7 +26,7 @@ class NoState extends PendingIntentState, TNoState {
}
/** A source for an implicit `PendingIntent` flow. */
abstract class ImplicitPendingIntentSource extends DataFlow::Node {
abstract class ImplicitPendingIntentSource extends ApiSourceNode {
/**
* DEPRECATED: Open-ended flow state is not intended to be part of the extension points.
*

View File

@@ -4,6 +4,7 @@ import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.security.HttpsUrls
private import semmle.code.java.dataflow.FlowSinks
/**
* A source that represents HTTP URLs.
@@ -20,7 +21,7 @@ private class DefaultInsecureBasicAuthSource extends InsecureBasicAuthSource {
* A sink that represents a method that sets Basic Authentication.
* Extend this class to add your own Insecure Basic Authentication sinks.
*/
abstract class InsecureBasicAuthSink extends DataFlow::Node { }
abstract class InsecureBasicAuthSink extends ApiSinkNode { }
/** A default sink representing methods that set an Authorization header. */
private class DefaultInsecureBasicAuthSink extends InsecureBasicAuthSink {

View File

@@ -2,6 +2,7 @@
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.frameworks.Networking
private import semmle.code.java.frameworks.Jndi
@@ -32,7 +33,7 @@ class InsecureLdapUrl extends Expr {
/**
* A sink representing the construction of a `DirContextEnvironment`.
*/
class InsecureLdapUrlSink extends DataFlow::Node {
class InsecureLdapUrlSink extends ApiSinkNode {
InsecureLdapUrlSink() {
exists(ConstructorCall cc |
cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and

View File

@@ -4,6 +4,7 @@ import java
private import semmle.code.java.frameworks.OpenSaml
private import semmle.code.java.frameworks.Servlets
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.security.Cookies
private import semmle.code.java.security.RandomQuery
@@ -49,7 +50,7 @@ abstract class InsecureRandomnessSink extends DataFlow::Node { }
/**
* A node which sets the value of a cookie.
*/
private class CookieSink extends InsecureRandomnessSink {
private class CookieSink extends InsecureRandomnessSink, ApiSinkNode {
CookieSink() { this.asExpr() instanceof SetCookieValue }
}

View File

@@ -2,11 +2,12 @@
import java
private import semmle.code.java.controlflow.Guards
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.security.Encryption
private import semmle.code.java.security.SecurityFlag
/** The creation of an insecure `TrustManager`. */
abstract class InsecureTrustManagerSource extends DataFlow::Node { }
abstract class InsecureTrustManagerSource extends ApiSourceNode { }
private class DefaultInsecureTrustManagerSource extends InsecureTrustManagerSource {
DefaultInsecureTrustManagerSource() {
@@ -18,7 +19,7 @@ private class DefaultInsecureTrustManagerSource extends InsecureTrustManagerSour
* The use of a `TrustManager` in an SSL context.
* Intentionally insecure connections are not considered sinks.
*/
abstract class InsecureTrustManagerSink extends DataFlow::Node {
abstract class InsecureTrustManagerSink extends ApiSinkNode {
InsecureTrustManagerSink() { not isGuardedByInsecureFlag(this) }
}

View File

@@ -6,6 +6,7 @@
import java
private import semmle.code.java.controlflow.Guards
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.frameworks.android.Android
private import semmle.code.java.frameworks.android.Intent
@@ -14,7 +15,7 @@ private import semmle.code.java.frameworks.android.Intent
* A sink for Intent URI permission manipulation vulnerabilities in Android,
* that is, method calls that return an Intent as the result of an Activity.
*/
abstract class IntentUriPermissionManipulationSink extends DataFlow::Node { }
abstract class IntentUriPermissionManipulationSink extends ApiSinkNode { }
/**
* A sanitizer that makes sure that an Intent is safe to be returned to another Activity.

View File

@@ -1,10 +1,11 @@
/** Provides classes for working with JSON Web Token (JWT) libraries. */
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.FlowSources
/** A method access that assigns signing keys to a JWT parser. */
class JwtParserWithInsecureParseSource extends DataFlow::Node {
class JwtParserWithInsecureParseSource extends ApiSourceNode {
JwtParserWithInsecureParseSource() {
exists(MethodCall ma, Method m |
m.getDeclaringType().getAnAncestor() instanceof TypeJwtParser or
@@ -24,7 +25,7 @@ class JwtParserWithInsecureParseSource extends DataFlow::Node {
* the qualifier of a call to a `parse(token, handler)` method
* where the `handler` is considered insecure.
*/
class JwtParserWithInsecureParseSink extends DataFlow::Node {
class JwtParserWithInsecureParseSink extends ApiSinkNode {
MethodCall insecureParseMa;
JwtParserWithInsecureParseSink() {

View File

@@ -3,11 +3,12 @@
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.frameworks.Jndi
private import semmle.code.java.frameworks.SpringLdap
/** A data flow sink for unvalidated user input that is used in JNDI lookup. */
abstract class JndiInjectionSink extends DataFlow::Node { }
abstract class JndiInjectionSink extends ApiSinkNode { }
/** A sanitizer for JNDI injection vulnerabilities. */
abstract class JndiInjectionSanitizer extends DataFlow::Node { }

View File

@@ -2,6 +2,7 @@
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.frameworks.MyBatis
@@ -10,7 +11,7 @@ private import semmle.code.java.frameworks.MyBatis
*
* Extend this class to add your own OGNL injection sinks.
*/
abstract class OgnlInjectionSink extends DataFlow::Node { }
abstract class OgnlInjectionSink extends ApiSinkNode { }
/**
* A unit class for adding additional taint steps.

View File

@@ -5,9 +5,10 @@ import semmle.code.java.dataflow.DataFlow
import semmle.code.java.frameworks.javaee.Persistence
private import semmle.code.java.frameworks.MyBatis
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSinks
/** A sink for database query language injection vulnerabilities. */
abstract class QueryInjectionSink extends DataFlow::Node { }
abstract class QueryInjectionSink extends ApiSinkNode { }
/**
* A unit class for adding additional taint steps.

View File

@@ -4,6 +4,7 @@ import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.SensitiveActions
private import semmle.code.java.dataflow.FlowSinks
private class ResultReceiverSendCall extends MethodCall {
ResultReceiverSendCall() {
@@ -50,15 +51,22 @@ deprecated private class SensitiveResultReceiverConf extends TaintTracking::Conf
}
}
/**
* A sensitive result receiver sink node.
*/
private class SensitiveResultReceiverSink extends ApiSinkNode {
SensitiveResultReceiverSink() {
exists(ResultReceiverSendCall call |
untrustedResultReceiverSend(_, call) and
this.asExpr() = call.getSentData()
)
}
}
private module SensitiveResultReceiverConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SensitiveExpr }
predicate isSink(DataFlow::Node node) {
exists(ResultReceiverSendCall call |
untrustedResultReceiverSend(_, call) and
node.asExpr() = call.getSentData()
)
}
predicate isSink(DataFlow::Node node) { node instanceof SensitiveResultReceiverSink }
predicate allowImplicitRead(DataFlow::Node n, DataFlow::ContentSet c) { isSink(n) and exists(c) }
}

View File

@@ -2,6 +2,7 @@
import java
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.security.SensitiveActions
private import semmle.code.java.frameworks.android.Layout
@@ -53,16 +54,23 @@ private class MaskCall extends MethodCall {
}
}
/**
* A text field sink node.
*/
private class TextFieldSink extends ApiSinkNode {
TextFieldSink() {
exists(SetTextCall call |
this.asExpr() = call.getStringArgument() and
not setTextCallIsMasked(call)
)
}
}
/** A configuration for tracking sensitive information to text fields. */
private module TextFieldTrackingConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SensitiveExpr }
predicate isSink(DataFlow::Node sink) {
exists(SetTextCall call |
sink.asExpr() = call.getStringArgument() and
not setTextCallIsMasked(call)
)
}
predicate isSink(DataFlow::Node sink) { sink instanceof TextFieldSink }
predicate isBarrier(DataFlow::Node node) { node instanceof SimpleTypeSanitizer }

View File

@@ -2,10 +2,11 @@
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.frameworks.spring.SpringExpression
/** A data flow sink for unvalidated user input that is used to construct SpEL expressions. */
abstract class SpelExpressionEvaluationSink extends DataFlow::ExprNode { }
abstract class SpelExpressionEvaluationSink extends ApiSinkNode, DataFlow::ExprNode { }
/**
* A unit class for adding additional taint steps.

View File

@@ -1,8 +1,7 @@
/** Provides predicates to reason about exposure of stack-traces. */
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.security.InformationLeak
/**
@@ -19,7 +18,7 @@ private class PrintStackTraceMethod extends Method {
}
private module ServletWriterSourceToPrintStackTraceMethodFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof XssVulnerableWriterSource }
predicate isSource(DataFlow::Node src) { src instanceof XssVulnerableWriterSourceNode }
predicate isSink(DataFlow::Node sink) {
exists(MethodCall ma |
@@ -95,7 +94,10 @@ predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stac
)
}
private class GetMessageFlowSource extends DataFlow::Node {
/**
* A get message source node.
*/
private class GetMessageFlowSource extends ApiSourceNode {
GetMessageFlowSource() {
exists(Method method | this.asExpr().(MethodCall).getMethod() = method |
method.hasName("getMessage") and

View File

@@ -1,6 +1,7 @@
/** Provides classes to reason about local information disclosure in a temporary directory. */
import java
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.os.OSCheck
private import semmle.code.java.security.TempDirUtils
@@ -29,7 +30,7 @@ private class MethodFileFileCreation extends MethodFileSystemFileCreation {
/**
* A dataflow node that creates a file or directory in the file system.
*/
abstract private class FileCreationSink extends DataFlow::Node { }
abstract private class FileCreationSink extends ApiSinkNode { }
/**
* The qualifier of a call to one of `File`'s file-creating or directory-creating methods,

View File

@@ -4,6 +4,7 @@
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.frameworks.android.WebView
private import semmle.code.java.frameworks.kotlin.Kotlin
@@ -12,7 +13,7 @@ private import semmle.code.java.frameworks.kotlin.Kotlin
*
* Extend this class to add your own Unsafe Resource Fetching sinks.
*/
abstract class UrlResourceSink extends DataFlow::Node {
abstract class UrlResourceSink extends ApiSinkNode {
/**
* Gets a description of this vulnerability.
*/

View File

@@ -1,13 +1,14 @@
/** Provides classes to reason about vulnerabilites related to content URIs. */
import java
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.frameworks.android.Android
private import semmle.code.java.security.PathSanitizer
private import semmle.code.java.security.Sanitizers
/** A URI that gets resolved by a `ContentResolver`. */
abstract class ContentUriResolutionSink extends DataFlow::Node { }
abstract class ContentUriResolutionSink extends ApiSinkNode { }
/** A sanitizer for content URIs. */
abstract class ContentUriResolutionSanitizer extends DataFlow::Node { }

View File

@@ -3,6 +3,7 @@
*/
import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.TaintTracking2
private import semmle.code.java.dispatch.VirtualDispatch
private import semmle.code.java.frameworks.Kryo
@@ -235,7 +236,7 @@ predicate unsafeDeserialization(MethodCall ma, Expr sink) {
}
/** A sink for unsafe deserialization. */
class UnsafeDeserializationSink extends DataFlow::ExprNode {
class UnsafeDeserializationSink extends ApiSinkNode, DataFlow::ExprNode {
UnsafeDeserializationSink() { unsafeDeserialization(_, this.getExpr()) }
/** Gets a call that triggers unsafe deserialization. */

View File

@@ -2,14 +2,15 @@
import java
import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.frameworks.Servlets
import semmle.code.java.frameworks.ApacheHttp
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.frameworks.JaxWS
private import semmle.code.java.security.RequestForgery
/** A URL redirection sink. */
abstract class UrlRedirectSink extends DataFlow::Node { }
abstract class UrlRedirectSink extends ApiSinkNode { }
/** A URL redirection sanitizer. */
abstract class UrlRedirectSanitizer extends DataFlow::Node { }

View File

@@ -4,6 +4,7 @@ import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.controlflow.Guards
import semmle.code.java.security.SecurityTests
private import semmle.code.java.dataflow.FlowSinks
/** Holds if `ex` looks like a check that this is a debug build. */
private predicate isDebugCheck(Expr ex) {
@@ -44,18 +45,25 @@ deprecated class WebviewDebugEnabledConfig extends DataFlow::Configuration {
}
}
/**
* A webview debug sink node.
*/
private class WebviewDebugSink extends ApiSinkNode {
WebviewDebugSink() {
exists(MethodCall ma |
ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and
this.asExpr() = ma.getArgument(0)
)
}
}
/** A configuration to find instances of `setWebContentDebuggingEnabled` called with `true` values. */
module WebviewDebugEnabledConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
node.asExpr().(BooleanLiteral).getBooleanValue() = true
}
predicate isSink(DataFlow::Node node) {
exists(MethodCall ma |
ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and
node.asExpr() = ma.getArgument(0)
)
}
predicate isSink(DataFlow::Node node) { node instanceof WebviewDebugSink }
predicate isBarrier(DataFlow::Node node) {
exists(Guard debug | isDebugCheck(debug) and debug.controls(node.asExpr().getBasicBlock(), _))

View File

@@ -3,12 +3,13 @@
import java
import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSinks
/**
* A sink that represents a method that interprets XPath expressions.
* Extend this class to add your own XPath Injection sinks.
*/
abstract class XPathInjectionSink extends DataFlow::Node { }
abstract class XPathInjectionSink extends ApiSinkNode { }
/** A default sink representing methods susceptible to XPath Injection attacks. */
private class DefaultXPathInjectionSink extends XPathInjectionSink {

View File

@@ -10,9 +10,11 @@ private import semmle.code.java.frameworks.hudson.Hudson
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.dataflow.FlowSinks
/** A sink that represent a method that outputs data without applying contextual output encoding. */
abstract class XssSink extends DataFlow::Node { }
abstract class XssSink extends ApiSinkNode { }
/** A sanitizer that neutralizes dangerous characters that can be used to perform a XSS attack. */
abstract class XssSanitizer extends DataFlow::Node { }
@@ -62,7 +64,7 @@ private class DefaultXssSanitizer extends XssSanitizer {
/** A configuration that tracks data from a servlet writer to an output method. */
private module XssVulnerableWriterSourceToWritingMethodFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof XssVulnerableWriterSource }
predicate isSource(DataFlow::Node src) { src instanceof XssVulnerableWriterSourceNode }
predicate isSink(DataFlow::Node sink) {
exists(MethodCall ma |
@@ -105,6 +107,13 @@ class XssVulnerableWriterSource extends MethodCall {
}
}
/**
* A xss vulnerable writer source node.
*/
class XssVulnerableWriterSourceNode extends ApiSourceNode {
XssVulnerableWriterSourceNode() { this.asExpr() instanceof XssVulnerableWriterSource }
}
/**
* Holds if `s` is an HTTP Content-Type vulnerable to XSS.
*/

View File

@@ -4,6 +4,7 @@ import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.security.PathSanitizer
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.security.PathCreation
/**
@@ -21,13 +22,20 @@ private class ArchiveEntryNameMethod extends Method {
}
}
/**
* An entry name method source node.
*/
private class ArchiveEntryNameMethodSource extends ApiSourceNode {
ArchiveEntryNameMethodSource() {
this.asExpr().(MethodCall).getMethod() instanceof ArchiveEntryNameMethod
}
}
/**
* A taint-tracking configuration for reasoning about unsafe zip file extraction.
*/
module ZipSlipConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().(MethodCall).getMethod() instanceof ArchiveEntryNameMethod
}
predicate isSource(DataFlow::Node source) { source instanceof ArchiveEntryNameMethodSource }
predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink }