mirror of
https://github.com/github/codeql.git
synced 2026-04-29 10:45:15 +02:00
Merge pull request #12763 from jketema/swift-configsig-3
Swift: Update final two queries to use `DataFlow::ConfigSig`
This commit is contained in:
@@ -13,7 +13,7 @@ import codeql.swift.security.CleartextStorageDatabaseExtensions
|
||||
* A taint configuration from sensitive information to expressions that are
|
||||
* transmitted over a network.
|
||||
*/
|
||||
class CleartextStorageConfig extends TaintTracking::Configuration {
|
||||
deprecated class CleartextStorageConfig extends TaintTracking::Configuration {
|
||||
CleartextStorageConfig() { this = "CleartextStorageConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SensitiveExpr }
|
||||
@@ -48,3 +48,44 @@ class CleartextStorageConfig extends TaintTracking::Configuration {
|
||||
super.allowImplicitRead(node, c)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint configuration from sensitive information to expressions that are
|
||||
* transmitted over a network.
|
||||
*/
|
||||
module CleartextStorageConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SensitiveExpr }
|
||||
|
||||
predicate isSink(DataFlow::Node node) { node instanceof CleartextStorageDatabaseSink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node sanitizer) {
|
||||
sanitizer instanceof CleartextStorageDatabaseSanitizer
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
any(CleartextStorageDatabaseAdditionalTaintStep s).step(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
predicate isBarrierIn(DataFlow::Node node) {
|
||||
// make sources barriers so that we only report the closest instance
|
||||
isSource(node)
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
|
||||
// flow out from fields of an `NSManagedObject` or `RealmSwiftObject` at the sink,
|
||||
// for example in `realmObj.data = sensitive`.
|
||||
isSink(node) and
|
||||
exists(NominalTypeDecl d, Decl cx |
|
||||
d.getType().getABaseType*().getUnderlyingType().getName() =
|
||||
["NSManagedObject", "RealmSwiftObject"] and
|
||||
cx.asNominalTypeDecl() = d and
|
||||
c.getAReadContent().(DataFlow::Content::FieldContent).getField() = cx.getAMember()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect taint flow of sensitive information to expressions that are
|
||||
* transmitted over a network.
|
||||
*/
|
||||
module CleartextStorageFlow = TaintTracking::Global<CleartextStorageConfig>;
|
||||
|
||||
@@ -7,47 +7,63 @@ import swift
|
||||
import codeql.swift.dataflow.DataFlow
|
||||
import codeql.swift.dataflow.ExternalFlow
|
||||
|
||||
private newtype TStringType =
|
||||
TString() or
|
||||
TNsString() or
|
||||
TStringUtf8() or
|
||||
TStringUtf16() or
|
||||
TStringUnicodeScalars()
|
||||
|
||||
/**
|
||||
* A type of Swift string encoding. This class is used as a flow state for
|
||||
* the string length conflation taint tracking configuration.
|
||||
*/
|
||||
class StringType extends string {
|
||||
class StringType extends TStringType {
|
||||
string name;
|
||||
string singular;
|
||||
string equivClass;
|
||||
TStringType equivClass;
|
||||
string csvLabel;
|
||||
|
||||
StringType() {
|
||||
this = "String" and
|
||||
this = TString() and
|
||||
name = "String" and
|
||||
singular = "a String" and
|
||||
equivClass = "String" and
|
||||
equivClass = this and
|
||||
csvLabel = "string-length"
|
||||
or
|
||||
this = "NSString" and
|
||||
this = TNsString() and
|
||||
name = "NSString" and
|
||||
singular = "an NSString" and
|
||||
equivClass = "NSString" and
|
||||
equivClass = this and
|
||||
csvLabel = "nsstring-length"
|
||||
or
|
||||
this = "String.utf8" and
|
||||
this = TStringUtf8() and
|
||||
name = "String.utf8" and
|
||||
singular = "a String.utf8" and
|
||||
equivClass = "String.utf8" and
|
||||
equivClass = this and
|
||||
csvLabel = "string-utf8-length"
|
||||
or
|
||||
this = "String.utf16" and
|
||||
this = TStringUtf16() and
|
||||
name = "String.utf16" and
|
||||
singular = "a String.utf16" and
|
||||
equivClass = "NSString" and
|
||||
equivClass = TNsString() and
|
||||
csvLabel = "string-utf16-length"
|
||||
or
|
||||
this = "String.unicodeScalars" and
|
||||
this = TStringUnicodeScalars() and
|
||||
name = "String.unicodeScalars" and
|
||||
singular = "a String.unicodeScalars" and
|
||||
equivClass = "String.unicodeScalars" and
|
||||
equivClass = this and
|
||||
csvLabel = "string-unicodescalars-length"
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this string type. */
|
||||
string toString() { result = name }
|
||||
|
||||
/**
|
||||
* Gets the equivalence class for this string type. If these are equal,
|
||||
* they should be treated as equivalent.
|
||||
*/
|
||||
string getEquivClass() { result = equivClass }
|
||||
StringType getEquivClass() { result = equivClass }
|
||||
|
||||
/**
|
||||
* Gets text for the singular form of this string type.
|
||||
@@ -130,15 +146,15 @@ private class ExtraStringLengthConflationSource extends StringLengthConflationSo
|
||||
(
|
||||
// result of a call to `String.utf8.count`
|
||||
typeName = "String.UTF8View" and
|
||||
stringType = "String.utf8"
|
||||
stringType = TStringUtf8()
|
||||
or
|
||||
// result of a call to `String.utf16.count`
|
||||
typeName = "String.UTF16View" and
|
||||
stringType = "String.utf16"
|
||||
stringType = TStringUtf16()
|
||||
or
|
||||
// result of a call to `String.unicodeScalars.count`
|
||||
typeName = "String.UnicodeScalarView" and
|
||||
stringType = "String.unicodeScalars"
|
||||
stringType = TStringUnicodeScalars()
|
||||
) and
|
||||
memberRef.getBase().getType().(NominalType).getName() = typeName and
|
||||
memberRef.getMember().(VarDecl).getName() = "count" and
|
||||
|
||||
@@ -9,31 +9,46 @@ import codeql.swift.dataflow.TaintTracking
|
||||
import codeql.swift.security.StringLengthConflationExtensions
|
||||
|
||||
/**
|
||||
* A configuration for tracking string lengths originating from source that is
|
||||
* a `String` or an `NSString` object, to a sink of a different kind that
|
||||
* A configuration for tracking string lengths originating from a source that
|
||||
* is a `String` or an `NSString` object, to a sink of a different kind that
|
||||
* expects an incompatible measure of length.
|
||||
*/
|
||||
class StringLengthConflationConfiguration extends TaintTracking::Configuration {
|
||||
StringLengthConflationConfiguration() { this = "StringLengthConflationConfiguration" }
|
||||
module StringLengthConflationConfig implements DataFlow::StateConfigSig {
|
||||
class FlowState = StringType;
|
||||
|
||||
override predicate isSource(DataFlow::Node node, string flowstate) {
|
||||
predicate isSource(DataFlow::Node node, FlowState flowstate) {
|
||||
flowstate = node.(StringLengthConflationSource).getStringType()
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node node, string flowstate) {
|
||||
predicate isSink(DataFlow::Node node, FlowState flowstate) {
|
||||
// Permit any *incorrect* flowstate, as those are the results the query
|
||||
// should report.
|
||||
exists(string correctFlowState |
|
||||
exists(FlowState correctFlowState |
|
||||
correctFlowState = node.(StringLengthConflationSink).getCorrectStringType() and
|
||||
flowstate.(StringType).getEquivClass() != correctFlowState.(StringType).getEquivClass()
|
||||
flowstate.getEquivClass() != correctFlowState.getEquivClass()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node sanitizer) {
|
||||
predicate isBarrier(DataFlow::Node sanitizer) {
|
||||
sanitizer instanceof StringLengthConflationSanitizer
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
predicate isBarrier(DataFlow::Node sanitizer, FlowState flowstate) { none() }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
any(StringLengthConflationAdditionalTaintStep s).step(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
DataFlow::Node nodeFrom, FlowState flowstateFrom, DataFlow::Node nodeTo, FlowState flowStateTo
|
||||
) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect taint flow of string lengths originating from a source that is
|
||||
* a `String` or an `NSString` object, to a sink of a different kind that
|
||||
* expects an incompatible measure of length.
|
||||
*/
|
||||
module StringLengthConflationFlow = TaintTracking::GlobalWithState<StringLengthConflationConfig>;
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
import swift
|
||||
import codeql.swift.dataflow.DataFlow
|
||||
import codeql.swift.security.StringLengthConflationQuery
|
||||
import DataFlow::PathGraph
|
||||
import StringLengthConflationFlow::PathGraph
|
||||
|
||||
from
|
||||
StringLengthConflationConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink,
|
||||
StringLengthConflationFlow::PathNode source, StringLengthConflationFlow::PathNode sink,
|
||||
StringType sourceType, StringType sinkType, string message
|
||||
where
|
||||
config.hasFlowPath(source, sink) and
|
||||
config.isSource(source.getNode(), sourceType) and
|
||||
StringLengthConflationFlow::flowPath(source, sink) and
|
||||
StringLengthConflationConfig::isSource(source.getNode(), sourceType) and
|
||||
sinkType = sink.getNode().(StringLengthConflationSink).getCorrectStringType() and
|
||||
message =
|
||||
"This " + sourceType + " length is used in " + sinkType.getSingular() +
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
import swift
|
||||
import codeql.swift.dataflow.DataFlow
|
||||
import codeql.swift.security.CleartextStorageDatabaseQuery
|
||||
import DataFlow::PathGraph
|
||||
import CleartextStorageFlow::PathGraph
|
||||
|
||||
/**
|
||||
* Gets a prettier node to use in the results.
|
||||
@@ -27,10 +27,10 @@ DataFlow::Node cleanupNode(DataFlow::Node n) {
|
||||
}
|
||||
|
||||
from
|
||||
CleartextStorageConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode,
|
||||
CleartextStorageFlow::PathNode sourceNode, CleartextStorageFlow::PathNode sinkNode,
|
||||
DataFlow::Node cleanSink
|
||||
where
|
||||
config.hasFlowPath(sourceNode, sinkNode) and
|
||||
CleartextStorageFlow::flowPath(sourceNode, sinkNode) and
|
||||
cleanSink = cleanupNode(sinkNode.getNode())
|
||||
select cleanSink, sourceNode, sinkNode,
|
||||
"This operation stores '" + cleanSink.toString() +
|
||||
|
||||
Reference in New Issue
Block a user