Skip to content

Commit

Permalink
C#: Indentify more APIs as supported in the telemetry queries (as QL …
Browse files Browse the repository at this point in the history
…defined sources).
  • Loading branch information
michaelnebel committed Apr 22, 2024
1 parent c5bdd5b commit 481e289
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 22 deletions.
73 changes: 73 additions & 0 deletions java/ql/lib/semmle/code/java/dataflow/ApiSources.qll
@@ -0,0 +1,73 @@
/** Provides classes representing various flow sources for data flow / taint tracking. */

private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSources

/**
* A data flow source node.
*/
abstract class SourceNode extends DataFlow::Node { }

/**
* Module that adds all API like sources to `SourceNode`, excluding sources for cryptography based
* queries, and queries where sources are not succifiently.
*/
private module ApiSources {
private import FlowSources as FlowSources
private import semmle.code.java.security.ArbitraryApkInstallation as ArbitraryApkInstallation
private import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery as CleartextStorageAndroidDatabaseQuery
private import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery as CleartextStorageAndroidFilesystemQuery
private import semmle.code.java.security.CleartextStorageSharedPrefsQuery as CleartextStorageSharedPrefsQuery
private import semmle.code.java.security.ImplicitPendingIntentsQuery as ImplicitPendingIntentsQuery
private import semmle.code.java.security.ImproperIntentVerificationQuery as ImproperIntentVerificationQuery
private import semmle.code.java.security.InsecureTrustManagerQuery as InsecureTrustManagerQuery
private import semmle.code.java.security.MissingJWTSignatureCheckQuery as MissingJWTSignatureCheckQuery

Check warning

Code scanning / CodeQL

Acronyms should be PascalCase/camelCase. Warning

Acronyms in MissingJWTSignatureCheckQuery should be PascalCase/camelCase.
private import semmle.code.java.security.XSS as Xss

Check warning

Code scanning / CodeQL

Names only differing by case Warning

Xss is only different by casing from XSS that is used elsewhere for modules.
private import semmle.code.java.security.StackTraceExposureQuery as StackTraceExposureQuery
private import semmle.code.java.security.UnsafeCertTrustQuery as UnsafeCertTrustQuery
private import semmle.code.java.security.ZipSlipQuery as ZipSlipQuery

private class FlowSourcesSourceNode extends SourceNode instanceof FlowSources::SourceNode { }

private class ArbitraryApkInstallationSources extends SourceNode instanceof ArbitraryApkInstallation::ExternalApkSource
{ }

private class CleartextStorageAndroidDatabaseQuerySources extends SourceNode instanceof CleartextStorageAndroidDatabaseQuery::LocalDatabaseOpenMethodCallSource
{ }

private class CleartextStorageAndroidFilesystemQuerySources extends SourceNode instanceof CleartextStorageAndroidFilesystemQuery::LocalFileOpenCallSource
{ }

private class CleartextStorageSharedPrefsQuerySources extends SourceNode instanceof CleartextStorageSharedPrefsQuery::SharedPreferencesEditorMethodCallSource
{ }

private class ImplicitPendingIntentsQuerySources extends SourceNode instanceof ImplicitPendingIntentsQuery::ImplicitPendingIntentSource
{ }

private class ImproperIntentVerificationQuerySources extends SourceNode instanceof ImproperIntentVerificationQuery::VerifiedIntentConfigSource
{ }

private class InsecureTrustManagerQuerySources extends SourceNode instanceof InsecureTrustManagerQuery::InsecureTrustManagerSource
{ }

private class MissingJWTSignatureCheckQuerySources extends SourceNode instanceof MissingJWTSignatureCheckQuery::JwtParserWithInsecureParseSource

Check warning

Code scanning / CodeQL

Acronyms should be PascalCase/camelCase. Warning

Acronyms in MissingJWTSignatureCheckQuerySources should be PascalCase/camelCase.
{ }

private class XssSources extends SourceNode instanceof Xss::XssVulnerableWriterSourceNode { }

private class StackTraceExposureQuerySources extends SourceNode instanceof StackTraceExposureQuery::GetMessageFlowSource
{ }

private class UnsafeCertTrustQuerySources extends SourceNode instanceof UnsafeCertTrustQuery::SslConnectionInit
{ }

private class ZipSlipQuerySources extends SourceNode instanceof ZipSlipQuery::ArchiveEntryNameMethodSource
{ }

/**
* Add all models as data sources.
*/
private class SourceNodeExternal extends SourceNode {
SourceNodeExternal() { sourceNode(this, _) }
}
}
8 changes: 5 additions & 3 deletions java/ql/lib/semmle/code/java/dataflow/FlowSources.qll
Expand Up @@ -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 = super.getThreatModel() }

Check warning

Code scanning / CodeQL

Redundant override Warning

Redundant override of
this predicate
.
}

/** 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" }
}

Expand Down
Expand Up @@ -96,10 +96,15 @@ private predicate localDatabaseStore(DataFlow::Node database, MethodCall store)
)
}

/**
* A class of local database open method call source nodes.
*/
class LocalDatabaseOpenMethodCallSource extends DataFlow::Node {
LocalDatabaseOpenMethodCallSource() { this.asExpr() instanceof LocalDatabaseOpenMethodCall }
}

private module LocalDatabaseFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof LocalDatabaseOpenMethodCall
}
predicate isSource(DataFlow::Node source) { source instanceof LocalDatabaseOpenMethodCallSource }

predicate isSink(DataFlow::Node sink) {
localDatabaseInput(sink, _) or
Expand Down
Expand Up @@ -79,8 +79,15 @@ private class CloseFileMethod extends Method {
}
}

/**
* A class of local file open call source nodes.
*/
class LocalFileOpenCallSource extends DataFlow::Node {
LocalFileOpenCallSource() { this.asExpr() instanceof LocalFileOpenCall }
}

private module FilesystemFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof LocalFileOpenCall }
predicate isSource(DataFlow::Node src) { src instanceof LocalFileOpenCallSource }

predicate isSink(DataFlow::Node sink) {
filesystemInput(sink, _) or
Expand Down
Expand Up @@ -67,11 +67,18 @@ private predicate sharedPreferencesStore(DataFlow::Node editor, MethodCall m) {
editor.asExpr() = m.getQualifier().getUnderlyingExpr()
}

/**
* A shared preferences editor method call source nodes.
*/
class SharedPreferencesEditorMethodCallSource extends DataFlow::Node {
SharedPreferencesEditorMethodCallSource() {
this.asExpr() instanceof SharedPreferencesEditorMethodCall
}
}

/** 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 isSource(DataFlow::Node src) { src instanceof SharedPreferencesEditorMethodCallSource }

predicate isSink(DataFlow::Node sink) {
sharedPreferencesInput(sink, _) or
Expand Down
Expand Up @@ -13,11 +13,18 @@ private class OnReceiveMethod extends Method {
Parameter getIntentParameter() { result = this.getParameter(1) }
}

/**
* A class of verified intent source nodes.
*/
class VerifiedIntentConfigSource extends DataFlow::Node {
VerifiedIntentConfigSource() {
this.asParameter() = any(OnReceiveMethod orm).getIntentParameter()
}
}

/** A configuration to detect whether the `action` of an `Intent` is checked. */
private module VerifiedIntentConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) {
src.asParameter() = any(OnReceiveMethod orm).getIntentParameter()
}
predicate isSource(DataFlow::Node src) { src instanceof VerifiedIntentConfigSource }

predicate isSink(DataFlow::Node sink) {
exists(MethodCall ma |
Expand Down
Expand Up @@ -19,7 +19,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 |
Expand Down Expand Up @@ -95,7 +95,10 @@ predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stac
)
}

private class GetMessageFlowSource extends DataFlow::Node {
/**
* A class of get message source nodes.
*/
class GetMessageFlowSource extends DataFlow::Node {
GetMessageFlowSource() {
exists(Method method | this.asExpr().(MethodCall).getMethod() = method |
method.hasName("getMessage") and
Expand Down
9 changes: 8 additions & 1 deletion java/ql/lib/semmle/code/java/security/XSS.qll
Expand Up @@ -62,7 +62,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 |
Expand Down Expand Up @@ -105,6 +105,13 @@ class XssVulnerableWriterSource extends MethodCall {
}
}

/**
* A class of xss vulnerable writer source nodes.
*/
class XssVulnerableWriterSourceNode extends DataFlow::Node {
XssVulnerableWriterSourceNode() { this.asExpr() instanceof XssVulnerableWriterSource }
}

/**
* Holds if `s` is an HTTP Content-Type vulnerable to XSS.
*/
Expand Down
13 changes: 10 additions & 3 deletions java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll
Expand Up @@ -21,13 +21,20 @@ private class ArchiveEntryNameMethod extends Method {
}
}

/**
* A class of entry name method source nodes.
*/
class ArchiveEntryNameMethodSource extends DataFlow::Node {
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 }

Expand Down
5 changes: 2 additions & 3 deletions java/ql/src/Telemetry/ExternalApi.qll
@@ -1,6 +1,7 @@
/** Provides classes and predicates related to handling APIs from external libraries. */

private import java
private import semmle.code.java.dataflow.ApiSources as ApiSources
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSources
Expand Down Expand Up @@ -69,9 +70,7 @@ class ExternalApi extends Callable {
}

pragma[nomagic]
predicate isSource() {
this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _)
}
predicate isSource() { this.getAnOutput() instanceof ApiSources::SourceNode }

/** Holds if this API is a known sink. */
pragma[nomagic]
Expand Down

0 comments on commit 481e289

Please sign in to comment.