Skip to content

Commit 70e0b33

Browse files
authored
Merge pull request #14807 from geoffw0/formatsinks
Swift: More sinks for swift/uncontrolled-format-string
2 parents 68a7734 + 8b628e3 commit 70e0b33

File tree

5 files changed

+248
-81
lines changed

5 files changed

+248
-81
lines changed

swift/ql/lib/codeql/swift/StringFormat.qll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ class LocalizedStringWithFormat extends FormattingFunction, Method {
5555
override int getFormatParameterIndex() { result = 0 }
5656
}
5757

58+
/**
59+
* A method that appends a formatted string.
60+
*/
61+
class StringMethodWithFormat extends FormattingFunction, Method {
62+
StringMethodWithFormat() {
63+
this.hasQualifiedName("NSMutableString", "appendFormat(_:_:)")
64+
or
65+
this.hasQualifiedName("StringProtocol", "appendingFormat(_:_:)")
66+
}
67+
68+
override int getFormatParameterIndex() { result = 0 }
69+
}
70+
5871
/**
5972
* The functions `NSLog` and `NSLogv`.
6073
*/
@@ -72,3 +85,16 @@ class NsExceptionRaise extends FormattingFunction, Method {
7285

7386
override int getFormatParameterIndex() { result = 1 }
7487
}
88+
89+
/**
90+
* A function that appears to be an imported C `printf` variant.
91+
*/
92+
class PrintfFormat extends FormattingFunction, FreeFunction {
93+
int formatParamIndex;
94+
95+
PrintfFormat() {
96+
this.getShortName().matches("%printf%") and this.getParam(formatParamIndex).getName() = "format"
97+
}
98+
99+
override int getFormatParameterIndex() { result = formatParamIndex }
100+
}

swift/ql/lib/codeql/swift/security/UncontrolledFormatStringExtensions.qll

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ private import codeql.swift.StringFormat
88
private import codeql.swift.dataflow.DataFlow
99
private import codeql.swift.dataflow.TaintTracking
1010
private import codeql.swift.dataflow.ExternalFlow
11+
private import codeql.swift.frameworks.StandardLibrary.PointerTypes
12+
private import codeql.swift.security.PredicateInjectionExtensions
1113

1214
/**
1315
* A dataflow sink for uncontrolled format string vulnerabilities.
@@ -43,6 +45,49 @@ private class DefaultUncontrolledFormatStringSink extends UncontrolledFormatStri
4345
}
4446
}
4547

48+
/**
49+
* Holds if `f`, `ix` describe `pd` and `pd` is a parameter that might be a format
50+
* string.
51+
*/
52+
pragma[noinline]
53+
predicate formatLikeHeuristic(Callable f, int ix, ParamDecl pd) {
54+
pd.getName() = ["format", "formatString", "fmt"] and
55+
pd = f.getParam(ix)
56+
}
57+
58+
/**
59+
* An uncontrolled format string sink that is determined by imprecise methods.
60+
*/
61+
class HeuristicUncontrolledFormatStringSink extends UncontrolledFormatStringSink {
62+
HeuristicUncontrolledFormatStringSink() {
63+
exists(Callable f, Type argsType |
64+
(
65+
// by parameter name
66+
exists(CallExpr ce, int ix |
67+
formatLikeHeuristic(f, ix, _) and
68+
f = ce.getStaticTarget() and
69+
this.asExpr() = ce.getArgument(ix).getExpr()
70+
)
71+
or
72+
// by argument name
73+
exists(Argument a |
74+
a.getLabel() = ["format", "formatString", "fmt"] and
75+
a.getApplyExpr().getStaticTarget() = f and
76+
this.asExpr() = a.getExpr()
77+
)
78+
) and
79+
// last parameter is vararg
80+
argsType = f.getParam(f.getNumberOfParams() - 1).getType().getUnderlyingType() and
81+
(
82+
argsType instanceof CVaListPointerType or
83+
argsType instanceof VariadicSequenceType
84+
)
85+
) and
86+
// prevent overlap with `swift/predicate-injection`
87+
not this instanceof PredicateInjectionSink
88+
}
89+
}
90+
4691
/**
4792
* A barrier for uncontrolled format string vulnerabilities.
4893
*/
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
5+
* Added additional sinks for the "Uncontrolled format string" (`swift/uncontrolled-format-string`) query. Some of these sinks are heuristic (imprecise) in nature.

0 commit comments

Comments
 (0)