Skip to content

Commit 04450c5

Browse files
authored
Merge pull request #11378 from atorralba/atorralba/swift/nsdata-models
Swift: Add models for NSData and NSMutableData
2 parents 8f065e9 + 2ac06b8 commit 04450c5

File tree

9 files changed

+686
-0
lines changed

9 files changed

+686
-0
lines changed

swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ private module Frameworks {
8181
private import codeql.swift.frameworks.StandardLibrary.CustomUrlSchemes
8282
private import codeql.swift.frameworks.StandardLibrary.Data
8383
private import codeql.swift.frameworks.StandardLibrary.InputStream
84+
private import codeql.swift.frameworks.StandardLibrary.NSData
8485
private import codeql.swift.frameworks.StandardLibrary.String
8586
private import codeql.swift.frameworks.StandardLibrary.Url
8687
private import codeql.swift.frameworks.StandardLibrary.UrlSession
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/** Provides classes and models to work with `NSData`-related objects. */
2+
3+
import swift
4+
private import codeql.swift.dataflow.DataFlow
5+
private import codeql.swift.dataflow.ExternalFlow
6+
private import codeql.swift.dataflow.FlowSteps
7+
8+
/** The class `NSData`. */
9+
class NsData extends ClassDecl {
10+
NsData() { this.getFullName() = "NSData" }
11+
}
12+
13+
/** The class `NSMutableData`. */
14+
class NsMutableData extends ClassDecl {
15+
NsMutableData() { this.getFullName() = "NSMutableData" }
16+
}
17+
18+
private class NsDataSources extends SourceModelCsv {
19+
override predicate row(string row) {
20+
row =
21+
[
22+
";NSData;true;init(contentsOf:);;;ReturnValue;remote",
23+
";NSData;true;init(contentsOf:options:);;;ReturnValue;remote"
24+
]
25+
}
26+
}
27+
28+
private class NsDataSummaries extends SummaryModelCsv {
29+
override predicate row(string row) {
30+
row =
31+
[
32+
";NSData;true;init(bytes:length:);;;Argument[0];ReturnValue;taint",
33+
";NSData;true;init(bytesNoCopy:length:);;;Argument[0];ReturnValue;taint",
34+
";NSData;true;init(bytesNoCopy:length:deallocator:);;;Argument[0];ReturnValue;taint",
35+
";NSData;true;init(bytesNoCopy:length:freeWhenDone:);;;Argument[0];ReturnValue;taint",
36+
";NSData;true;init(data:);;;Argument[0];ReturnValue;taint",
37+
";NSData;true;init(contentsOfFile:);;;Argument[0];ReturnValue;taint",
38+
";NSData;true;init(contentsOfFile:options:);;;Argument[0];ReturnValue;taint",
39+
";NSData;true;init(contentsOf:);;;Argument[0];ReturnValue;taint",
40+
";NSData;true;init(contentsOf:options:);;;Argument[0];ReturnValue;taint",
41+
";NSData;true;init(contentsOfMappedFile:);;;Argument[0];ReturnValue;taint",
42+
";NSData;true;init(base64Encoded:options:);;;Argument[0];ReturnValue;taint",
43+
";NSData;true;init(base64Encoding:);;;Argument[0];ReturnValue;taint",
44+
";NSData;true;base64EncodedData(options:);;;Argument[-1];ReturnValue;taint",
45+
";NSData;true;base64EncodedString(options:);;;Argument[-1];ReturnValue;taint",
46+
";NSData;true;base64Encoding();;;Argument[-1];ReturnValue;taint",
47+
";NSData;true;dataWithContentsOfMappedFile(_:);;;Argument[0];ReturnValue;taint",
48+
";NSData;true;enumerateBytes(_:);;;Argument[-1];Argument[0].Parameter[0];taint",
49+
";NSData;true;getBytes(_:);;;Argument[-1];Argument[0];taint",
50+
";NSData;true;getBytes(_:length:);;;Argument[-1];Argument[0];taint",
51+
";NSData;true;getBytes(_:range:);;;Argument[-1];Argument[0];taint",
52+
";NSData;true;subdata(with:);;;Argument[-1];ReturnValue;taint",
53+
";NSData;true;compressed(using:);;;Argument[-1];ReturnValue;taint",
54+
";NSData;true;decompressed(using:);;;Argument[-1];ReturnValue;taint"
55+
]
56+
}
57+
}
58+
59+
private class NsMutableDataSummaries extends SummaryModelCsv {
60+
override predicate row(string row) {
61+
row =
62+
[
63+
";NSMutableData;true;append(_:length:);;;Argument[0];Argument[-1];taint",
64+
";NSMutableData;true;append(_:);;;Argument[0];Argument[-1];taint",
65+
";NSMutableData;true;replaceBytes(in:withBytes:);;;Argument[1];Argument[-1];taint",
66+
";NSMutableData;true;replaceBytes(in:withBytes:length:);;;Argument[1];Argument[-1];taint",
67+
";NSMutableData;true;setData(_:);;;Argument[0];Argument[-1];taint",
68+
]
69+
}
70+
}
71+
72+
/** A content implying that, if a `NSData` object is tainted, some of its fields are also tainted. */
73+
private class NsDataTaintedFields extends TaintInheritingContent, DataFlow::Content::FieldContent {
74+
NsDataTaintedFields() {
75+
exists(FieldDecl f | this.getField() = f |
76+
f.getEnclosingDecl() instanceof NsData and
77+
f.getName() = ["bytes", "description"]
78+
)
79+
}
80+
}
81+
82+
/** A content implying that, if a `NSMutableData` object is tainted, some of its fields are also tainted. */
83+
private class NsMutableDataTaintedFields extends TaintInheritingContent,
84+
DataFlow::Content::FieldContent {
85+
NsMutableDataTaintedFields() {
86+
exists(FieldDecl f | this.getField() = f |
87+
f.getEnclosingDecl() instanceof NsMutableData and
88+
f.getName() = "mutableBytes"
89+
)
90+
}
91+
}

swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
| customurlschemes.swift:38:52:38:62 | url | external |
44
| customurlschemes.swift:43:9:43:28 | ...[...] | Remote URL in UIApplicationDelegate.application.launchOptions |
55
| customurlschemes.swift:48:9:48:28 | ...[...] | Remote URL in UIApplicationDelegate.application.launchOptions |
6+
| nsdata.swift:18:17:18:17 | call to init(contentsOf:) | external |
7+
| nsdata.swift:18:17:18:40 | call to init(contentsOf:) | external |
8+
| nsdata.swift:19:17:19:17 | call to init(contentsOf:options:) | external |
9+
| nsdata.swift:19:17:19:53 | call to init(contentsOf:options:) | external |
610
| string.swift:56:21:56:21 | call to init(contentsOf:) | external |
711
| string.swift:56:21:56:44 | call to init(contentsOf:) | external |
812
| string.swift:57:21:57:21 | call to init(contentsOf:encoding:) | external |
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// --- stubs ---
2+
3+
struct URL
4+
{
5+
init?(string: String) {}
6+
}
7+
8+
class NSData {
9+
struct ReadingOptions : OptionSet { let rawValue: Int }
10+
init?(contentsOf: URL) {}
11+
init?(contentsOf: URL, options: NSData.ReadingOptions) {}
12+
}
13+
14+
// --- tests ---
15+
16+
func testNSData() {
17+
let url = URL(string: "http://example.com/")
18+
let _ = try NSData(contentsOf: url!) // SOURCE
19+
let _ = try NSData(contentsOf: url!, options: []) // SOURCE
20+
}

swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
| nsdata.swift:139:15:139:15 | nsDataTainted24 | nsdata.swift:139:15:139:31 | .bytes |
2+
| nsdata.swift:140:15:140:15 | nsDataTainted24 | nsdata.swift:140:15:140:31 | .description |
3+
| nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | nsmutabledata.swift:49:15:49:37 | .mutableBytes |
14
| string.swift:7:13:7:13 | | string.swift:7:13:7:13 | [post] |
25
| string.swift:7:13:7:13 | | string.swift:7:14:7:14 | [post] &... |
36
| string.swift:7:13:7:13 | TapExpr | string.swift:7:13:7:13 | "..." |

0 commit comments

Comments
 (0)