Skip to content

Commit dd51b7f

Browse files
committed
Swift: Add many tests.
1 parent c1be060 commit dd51b7f

File tree

7 files changed

+227
-6
lines changed

7 files changed

+227
-6
lines changed
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
TODO
1+
edges
2+
nodes
3+
subpaths
4+
#select
5+
| TODO |
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
TODO
1+
edges
2+
nodes
3+
subpaths
4+
#select
5+
| TODO |

swift/ql/test/query-tests/Security/CWE-311/test.swift

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
2+
// --- stubs ---
3+
4+
class NSObject
5+
{
6+
}
7+
8+
class NSManagedObject : NSObject
9+
{
10+
func value(forKey: String) -> Any? { return "" }
11+
func setValue(_: Any?, forKey: String) {}
12+
func primitiveValue(forKey: String) -> Any? { return "" }
13+
func setPrimitiveValue(_: Any?, forKey: String) {}
14+
}
15+
16+
class MyManagedObject : NSManagedObject
17+
{
18+
func setIndirect(value: String) {
19+
setValue(value, forKey: "myKey")
20+
}
21+
22+
var myValue: String {
23+
get {
24+
if let v = value(forKey: "myKey") as? String
25+
{
26+
return v
27+
} else {
28+
return ""
29+
}
30+
}
31+
set {
32+
setValue(newValue, forKey: "myKey")
33+
}
34+
}
35+
}
36+
37+
func encrypt(_ data: String) -> String { return data }
38+
func hash(data: inout String) { }
39+
40+
func getPassword() -> String { return "" }
41+
func doSomething(password: String) { }
42+
43+
// --- tests ---
44+
45+
func test1(obj : NSManagedObject, password : String, password_hash : String) {
46+
// NSManagedObject methods...
47+
48+
obj.setValue(password, forKey: "myKey") // BAD
49+
obj.setValue(password_hash, forKey: "myKey") // GOOD (not sensitive)
50+
51+
obj.setPrimitiveValue(password, forKey: "myKey") // BAD
52+
obj.setPrimitiveValue(password_hash, forKey: "myKey") // GOOD (not sensitive)
53+
}
54+
55+
func test2(obj : MyManagedObject, password : String, password_file : String) {
56+
// MyManagedObject methods...
57+
58+
obj.setValue(password, forKey: "myKey") // BAD
59+
obj.setValue(password_file, forKey: "myKey") // GOOD (not sensitive)
60+
61+
obj.setIndirect(value: password) // BAD
62+
obj.setIndirect(value: password_file) // GOOD (not sensitive)
63+
64+
obj.myValue = password // BAD
65+
obj.myValue = password_file // GOOD (not sensitive)
66+
}
67+
68+
func test3(obj : NSManagedObject, x : String) {
69+
// alternative evidence of sensitivity...
70+
71+
obj.setValue(x, forKey: "myKey") // BAD
72+
doSomething(password: x);
73+
obj.setValue(x, forKey: "myKey") // BAD
74+
75+
var y = getPassword();
76+
obj.setValue(y, forKey: "myKey") // BAD
77+
}
78+
79+
func test4(obj : NSManagedObject, pwd : String) {
80+
// sanitizers...
81+
82+
var x = pwd;
83+
var y = pwd;
84+
var z = pwd;
85+
86+
obj.setValue(x, forKey: "myKey") // BAD
87+
obj.setValue(y, forKey: "myKey") // BAD
88+
obj.setValue(z, forKey: "myKey") // BAD
89+
90+
x = encrypt(x);
91+
hash(data: &y);
92+
z = "";
93+
94+
obj.setValue(x, forKey: "myKey") // GOOD (not sensitive)
95+
obj.setValue(y, forKey: "myKey") // GOOD (not sensitive)
96+
obj.setValue(z, forKey: "myKey") // GOOD (not sensitive)
97+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
// --- stubs ---
3+
4+
enum UpdatePolicy : Int {
5+
case error = 1
6+
}
7+
8+
class RealmSwiftObject {
9+
}
10+
11+
typealias Object = RealmSwiftObject
12+
13+
class MyRealmSwiftObject : RealmSwiftObject {
14+
override init() { data = "" }
15+
16+
var data: String
17+
}
18+
19+
class Realm {
20+
func add(_ object: Object, update: UpdatePolicy = .error) {}
21+
22+
func create<T>(_ type : T.Type, value: Any = [:], update: UpdatePolicy = .error) where T : RealmSwiftObject { }
23+
24+
func object<Element, KeyType>(ofType type: Element.Type, forPrimaryKey key: KeyType) -> Element? where Element : RealmSwiftObject { return nil }
25+
26+
}
27+
28+
// --- tests ---
29+
30+
func test1(realm : Realm, myPassword : String, myHashedPassword : String) {
31+
// add objects (within a transaction) ...
32+
33+
let a = MyRealmSwiftObject()
34+
a.data = myPassword
35+
realm.add(a) // BAD
36+
37+
let b = MyRealmSwiftObject()
38+
b.data = myHashedPassword
39+
realm.add(b) // GOOD (not sensitive)
40+
41+
let c = MyRealmSwiftObject()
42+
c.data = myPassword
43+
realm.create(MyRealmSwiftObject.self, value: c) // BAD
44+
45+
let d = MyRealmSwiftObject()
46+
d.data = myHashedPassword
47+
realm.create(MyRealmSwiftObject.self, value: d) // GOOD (not sensitive)
48+
49+
// retrieve objects ...
50+
51+
var e = realm.object(ofType: MyRealmSwiftObject.self, forPrimaryKey: "key")
52+
e!.data = myPassword // BAD
53+
54+
var f = realm.object(ofType: MyRealmSwiftObject.self, forPrimaryKey: "key")
55+
f!.data = myHashedPassword // GOOD (not sensitive)
56+
}
57+
58+
// limitation: its possible to configure a Realm DB to be stored encrypted, if this is done correctly
59+
// (taking care with the encryption key) then storing otherwise plaintext sensitive data would be OK.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
// --- stubs ---
3+
4+
class Data {
5+
init<S>(_ elements: S) {}
6+
}
7+
8+
class NWConnection {
9+
enum SendCompletion {
10+
case idempotent
11+
}
12+
13+
class ContentContext {
14+
static let defaultMessage = ContentContext()
15+
}
16+
17+
func send(content: Data?, contentContext: NWConnection.ContentContext = .defaultMessage, isComplete: Bool = true, completion: NWConnection.SendCompletion) { }
18+
func send<Content>(content: Content?, contentContext: NWConnection.ContentContext = .defaultMessage, isComplete: Bool = true, completion: NWConnection.SendCompletion) { }
19+
}
20+
21+
// --- tests ---
22+
23+
func test1(passwordPlain : String, passwordHash : String) {
24+
let nw = NWConnection()
25+
26+
// ...
27+
28+
nw.send(content: "123456", completion: .idempotent) // GOOD (not sensitive)
29+
nw.send(content: passwordPlain, completion: .idempotent) // BAD
30+
nw.send(content: passwordHash, completion: .idempotent) // GOOD (not sensitive)
31+
32+
let data1 = Data("123456")
33+
let data2 = Data(passwordPlain)
34+
let data3 = Data(passwordHash)
35+
36+
nw.send(content: data1, completion: .idempotent) // GOOD (not sensitive)
37+
nw.send(content: data2, completion: .idempotent) // BAD
38+
nw.send(content: data3, completion: .idempotent) // GOOD (not sensitive)
39+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
// --- stubs ---
3+
4+
class URL
5+
{
6+
init?(string: String) {}
7+
init?(string: String, relativeTo: URL?) {}
8+
}
9+
10+
// --- tests ---
11+
12+
func test1(passwd : String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
13+
let a = URL(string: "http://example.com/login?p=" + passwd); // BAD
14+
let b = URL(string: "http://example.com/login?p=" + encrypted_passwd); // GOOD (not sensitive)
15+
let c = URL(string: "http://example.com/login?ac=" + account_no); // BAD
16+
let d = URL(string: "http://example.com/login?cc=" + credit_card_no); // BAD
17+
18+
let base = URL(string: "http://example.com/"); // GOOD (not sensitive)
19+
let e = URL(string: "abc", relativeTo: base); // GOOD (not sensitive)
20+
let f = URL(string: passwd, relativeTo: base); // BAD
21+
let g = URL(string: "abc", relativeTo: f); // BAD
22+
}

0 commit comments

Comments
 (0)