Skip to content

Commit

Permalink
Put QLDoc on data flow and taint tracking modules
Browse files Browse the repository at this point in the history
We preserve all old QLDocs, but move them from the
config to the Flow module. This makes more sense than
the Config module, which is often private, and is generally
not directly accessed.
  • Loading branch information
owen-mc committed Aug 9, 2023
1 parent a959506 commit 9612740
Show file tree
Hide file tree
Showing 39 changed files with 174 additions and 50 deletions.
9 changes: 4 additions & 5 deletions go/ql/lib/semmle/go/StringOps.qll
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,6 @@ module StringOps {
}
}

/**
* A configuration for tracking flow from a call to `strings.NewReplacer` to
* the receiver of a call to `strings.Replacer.Replace` or
* `strings.Replacer.WriteString`.
*/
private module StringsNewReplacerConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof StringsNewReplacerCall }

Expand All @@ -238,6 +233,10 @@ module StringOps {
}
}

/**
* Tracks data flow from a call to `strings.NewReplacer` to the receiver of
* a call to `strings.Replacer.Replace` or `strings.Replacer.WriteString`.
*/
private module StringsNewReplacerFlow = DataFlow::Global<StringsNewReplacerConfig>;

/**
Expand Down
4 changes: 4 additions & 0 deletions go/ql/lib/semmle/go/security/AllocationSizeOverflow.qll
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ module AllocationSizeOverflow {
predicate isBarrier(DataFlow::Node nd) { nd instanceof Sanitizer }
}

/**
* Tracks taint flow to find `len(...)` calls whose argument may be large.
*/
private module FindLargeLensFlow = TaintTracking::Global<FindLargeLensConfig>;

private DataFlow::CallNode getALargeLenCall() {
Expand Down Expand Up @@ -111,5 +114,6 @@ module AllocationSizeOverflow {
}
}

/** Tracks taint flow to find allocation-size overflows. */
module Flow = TaintTracking::Global<Config>;
}
7 changes: 7 additions & 0 deletions go/ql/lib/semmle/go/security/CleartextLogging.qll
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,12 @@ module CleartextLogging {
}
}

/**
* Tracks data flow for reasoning about clear-text logging of sensitive
* information, from `Source`s, which are sources of sensitive data, to
* `Sink`s, which is an abstract class representing all the places sensitive
* data may be stored in cleartext. Additional sources or sinks can be added
* by extending the relevant class.
*/
module Flow = DataFlow::Global<Config>;
}
8 changes: 8 additions & 0 deletions go/ql/lib/semmle/go/security/CommandInjection.qll
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ module CommandInjection {
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}

/**
* Tracks taint flow for reasoning about command-injection vulnerabilities
* with sinks which are not sanitized by `--`.
*/
module Flow = TaintTracking::Global<Config>;

private class ArgumentArrayWithDoubleDash extends DataFlow::Node {
Expand Down Expand Up @@ -129,5 +133,9 @@ module CommandInjection {
}
}

/**
* Tracks taint flow for reasoning about command-injection vulnerabilities
* with sinks which are sanitized by `--`.
*/
module DoubleDashSanitizingFlow = TaintTracking::Global<DoubleDashSanitizingConfig>;
}
6 changes: 6 additions & 0 deletions go/ql/lib/semmle/go/security/ExternalAPIs.qll
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ private module UntrustedDataConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }
}

/**
* Tracks data flow from `RemoteFlowSource`s to `ExternalApiDataNode`s.
*/
module UntrustedDataToExternalApiFlow = DataFlow::Global<UntrustedDataConfig>;

/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */
Expand Down Expand Up @@ -234,6 +237,9 @@ private module UntrustedDataToUnknownExternalApiConfig implements DataFlow::Conf
predicate isSink(DataFlow::Node sink) { sink instanceof UnknownExternalApiDataNode }
}

/**
* Tracks data flow from `RemoteFlowSource`s to `UnknownExternalApiDataNode`s.
*/
module UntrustedDataToUnknownExternalApiFlow =
DataFlow::Global<UntrustedDataToUnknownExternalApiConfig>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ private module ConversionWithoutBoundsCheckConfig implements DataFlow::StateConf
}
}

/**
* Tracks taint flow from an integer obtained from parsing a string flows to a
* type conversion to a smaller integer type, which could cause unexpected
* values.
*/
module Flow = TaintTracking::GlobalWithState<ConversionWithoutBoundsCheckConfig>;

private predicate upperBoundCheckGuard(DataFlow::Node g, Expr e, boolean branch) {
Expand Down
4 changes: 4 additions & 0 deletions go/ql/lib/semmle/go/security/InsecureRandomness.qll
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,9 @@ module InsecureRandomness {
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}

/**
* Tracks taint flow for reasoning about random values that are not
* cryptographically secure.
*/
module Flow = TaintTracking::Global<Config>;
}
1 change: 1 addition & 0 deletions go/ql/lib/semmle/go/security/OpenUrlRedirect.qll
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,6 @@ module OpenUrlRedirect {
}
}

/** Tracks taint flow for reasoning about unvalidated URL redirections. */
module Flow = DataFlow::Global<Config>;
}
1 change: 1 addition & 0 deletions go/ql/lib/semmle/go/security/ReflectedXss.qll
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ module ReflectedXss {
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}

/** Tracks taint flow for reasoning about XSS. */
module Flow = TaintTracking::Global<Config>;
}
1 change: 1 addition & 0 deletions go/ql/lib/semmle/go/security/RequestForgery.qll
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,6 @@ module RequestForgery {
}
}

/** Tracks taint flow for reasoning about request forgery. */
module Flow = TaintTracking::Global<Config>;
}
1 change: 1 addition & 0 deletions go/ql/lib/semmle/go/security/SafeUrlFlow.qll
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,6 @@ module SafeUrlFlow {
}
}

/** Tracks taint flow for reasoning about safe URLs. */
module Flow = TaintTracking::Global<Config>;
}
1 change: 1 addition & 0 deletions go/ql/lib/semmle/go/security/SqlInjection.qll
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ module SqlInjection {
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}

/** Tracks taint flow for reasoning about SQL-injection vulnerabilities. */
module Flow = TaintTracking::Global<Config>;
}
1 change: 1 addition & 0 deletions go/ql/lib/semmle/go/security/StoredCommand.qll
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@ module StoredCommand {
predicate isBarrier(DataFlow::Node node) { node instanceof CommandInjection::Sanitizer }
}

/** Tracks taint flow for reasoning about command-injection vulnerabilities. */
module Flow = TaintTracking::Global<Config>;
}
1 change: 1 addition & 0 deletions go/ql/lib/semmle/go/security/StoredXss.qll
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ module StoredXss {
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}

/** Tracks taint flow for reasoning about XSS. */
module Flow = TaintTracking::Global<Config>;
}
4 changes: 4 additions & 0 deletions go/ql/lib/semmle/go/security/StringBreak.qll
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,9 @@ module StringBreak {
}
}

/**
* Tracks taint flow for reasoning about unsafe-quoting vulnerabilities,
* parameterized with the type of quote being tracked.
*/
module Flow = TaintTracking::GlobalWithState<Config>;
}
1 change: 1 addition & 0 deletions go/ql/lib/semmle/go/security/TaintedPath.qll
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ module TaintedPath {
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}

/** Tracks taint flow for reasoning about path-traversal vulnerabilities. */
module Flow = TaintTracking::Global<Config>;
}
8 changes: 8 additions & 0 deletions go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ module UnsafeUnzipSymlink {
predicate isBarrier(DataFlow::Node node) { node instanceof EvalSymlinksInvalidator }
}

/**
* Tracks taint flow from archive header fields to
* `path/filepath.EvalSymlinks` calls.
*/
private module EvalSymlinksFlow = TaintTracking::Global<EvalSymlinksConfig>;

/**
Expand Down Expand Up @@ -90,5 +94,9 @@ module UnsafeUnzipSymlink {
predicate isBarrier(DataFlow::Node node) { node instanceof SymlinkSanitizer }
}

/**
* Tracks taint flow from archive header fields to an `os.Symlink` call,
* which never flow to a `path/filepath.EvalSymlinks` call.
*/
module Flow = TaintTracking::Global<Config>;
}
4 changes: 4 additions & 0 deletions go/ql/lib/semmle/go/security/XPathInjection.qll
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,9 @@ module XPathInjection {
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}

/**
* Tracks taint flow for reasoning about untrusted user input used in an
* XPath expression.
*/
module Flow = TaintTracking::Global<Config>;
}
1 change: 1 addition & 0 deletions go/ql/lib/semmle/go/security/ZipSlip.qll
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@ module ZipSlip {
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}

/** Tracks taint flow for reasoning about zip-slip vulnerabilities. */
module Flow = TaintTracking::Global<Config>;
}
4 changes: 4 additions & 0 deletions go/ql/src/InconsistentCode/UnhandledCloseWritableHandle.ql
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ module UnhandledFileCloseConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { isCloseSink(sink, _) }
}

/**
* Tracks data flow for reasoning about which writable file handles resulting from calls to
* `os.OpenFile` have `os.File.Close` called on them.
*/
module UnhandledFileCloseFlow = DataFlow::Global<UnhandledFileCloseConfig>;

import UnhandledFileCloseFlow::PathGraph
Expand Down
4 changes: 4 additions & 0 deletions go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ module SuspiciousCharacterInRegexpConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { sink instanceof RegexpPattern }
}

/**
* Tracks data flow from strings containing suspicious escape sequences to a
* use as a regular expression.
*/
module Flow = DataFlow::Global<SuspiciousCharacterInRegexpConfig>;

import Flow::PathGraph
Expand Down
8 changes: 4 additions & 4 deletions go/ql/src/Security/CWE-209/StackTraceExposure.ql
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ class DebugStackFunction extends Function {
DebugStackFunction() { this.hasQualifiedName("runtime/debug", "Stack") }
}

/**
* A taint-tracking configuration that looks for stack traces being written to
* an HTTP response body without an intervening debug- or development-mode conditional.
*/
module StackTraceExposureConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.(DataFlow::PostUpdateNode).getPreUpdateNode() =
Expand All @@ -68,6 +64,10 @@ module StackTraceExposureConfig implements DataFlow::ConfigSig {
}
}

/**
* Tracks taint flow for reasoning about stack traces being written to an HTTP
* response body without an intervening debug- or development-mode conditional.
*/
module StackTraceExposureFlow = TaintTracking::Global<StackTraceExposureConfig>;

import StackTraceExposureFlow::PathGraph
Expand Down
4 changes: 4 additions & 0 deletions go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ module Config implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { writeIsSink(sink, _) }
}

/**
* Tracks data flow to identify `HostKeyCallbackFunc` instances that reach
* `ClientConfig.HostKeyCallback` fields.
*/
module Flow = DataFlow::Global<Config>;

import Flow::PathGraph
Expand Down
4 changes: 4 additions & 0 deletions go/ql/src/Security/CWE-326/InsufficientKeySize.ql
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ module Config implements DataFlow::ConfigSig {
}
}

/**
* Tracks data flow from an RSA key length to a calls to an RSA key generation
* function.
*/
module Flow = DataFlow::Global<Config>;

import Flow::PathGraph
Expand Down
16 changes: 8 additions & 8 deletions go/ql/src/Security/CWE-327/InsecureTLS.ql
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ int getASecureTlsVersion() {
*/
int getATlsVersion() { result = getASecureTlsVersion() or isInsecureTlsVersion(result, _, _) }

/**
* A taint-tracking configuration for tracking flow from TLS versions to the
* `tls.Config.MinVersion` and `tls.Config.MaxVersion` fields.
*/
module TlsVersionFlowConfig implements DataFlow::ConfigSig {
/**
* Holds if `source` is a TLS version source yielding value `val`.
Expand All @@ -77,6 +73,10 @@ module TlsVersionFlowConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _, _) }
}

/**
* Tracks taint flow from TLS versions to the `tls.Config.MinVersion` and
* `tls.Config.MaxVersion` fields.
*/
module TlsVersionFlow = TaintTracking::Global<TlsVersionFlowConfig>;

/**
Expand Down Expand Up @@ -150,10 +150,6 @@ predicate isInsecureTlsVersionFlow(
)
}

/**
* A taint-tracking configuration for tracking flow from insecure TLS cipher
* suites into a `tls.Config` struct, to the `CipherSuites` field.
*/
module TlsInsecureCipherSuitesFlowConfig implements DataFlow::ConfigSig {
/**
* Holds if `source` reads an insecure TLS cipher suite named `suiteName`.
Expand Down Expand Up @@ -207,6 +203,10 @@ module TlsInsecureCipherSuitesFlowConfig implements DataFlow::ConfigSig {
predicate isBarrierOut(DataFlow::Node node) { isSink(node) }
}

/**
* Tracks taint flow from insecure TLS cipher suites into the `CipherSuites`
* field of a `tls.Config` struct.
*/
module TlsInsecureCipherSuitesFlow = TaintTracking::Global<TlsInsecureCipherSuitesFlowConfig>;

/**
Expand Down
11 changes: 11 additions & 0 deletions go/ql/src/Security/CWE-352/ConstantOauth2State.ql
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ module ConstantStateFlowConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { isSinkCall(sink, _) }
}

/**
* Tracks data flow of a constant string value to a call to `AuthCodeURL` as
* the `state` parameter.
*/
module Flow = DataFlow::Global<ConstantStateFlowConfig>;

import Flow::PathGraph
Expand Down Expand Up @@ -108,6 +112,13 @@ module PrivateUrlFlowsToAuthCodeUrlCallConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { isSinkCall(sink, _) }
}

/**
* Tracks data flow from a URL indicating the OAuth redirect doesn't point to a publicly
* accessible address to the receiver of an `AuthCodeURL` call.
*
* Note we accept localhost and 127.0.0.1 on the assumption this is probably a transient
* listener; if it actually is a persistent server then that really is vulnerable to CSRF.
*/
module PrivateUrlFlowsToAuthCodeUrlCallFlow =
DataFlow::Global<PrivateUrlFlowsToAuthCodeUrlCallConfig>;

Expand Down
1 change: 1 addition & 0 deletions go/ql/src/Security/CWE-640/EmailInjection.qll
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ module EmailInjection {
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
}

/** Tracks taint flow for reasoning about email-injection vulnerabilities. */
module Flow = TaintTracking::Global<Config>;
}
4 changes: 4 additions & 0 deletions go/ql/src/experimental/CWE-090/LDAPInjection.qll
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,8 @@ private module LdapInjectionConfig implements DataFlow::ConfigSig {
predicate isBarrier(DataFlow::Node node) { node instanceof LdapSanitizer }
}

/**
* Tracks taint flow for reasoning about when an `UntrustedFlowSource` flows
* into an argument or field that is vulnerable to LDAP injection.
*/
module LdapInjectionFlow = TaintTracking::Global<LdapInjectionConfig>;
Loading

0 comments on commit 9612740

Please sign in to comment.