Merge pull request #10014 from geoffw0/inlinetaint

Swift: Add an inline expectations test for taint flow
This commit is contained in:
Geoffrey White 2022-08-11 11:18:18 +01:00 коммит произвёл GitHub
Родитель ff23f8ef86 1dcc44ff2f
Коммит 2ee1979546
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 71 добавлений и 49 удалений

Просмотреть файл

@ -3,27 +3,9 @@
*/
import swift
import codeql.swift.dataflow.TaintTracking
import codeql.swift.dataflow.DataFlow::DataFlow
import Taint
import PathGraph
class TestConfiguration extends TaintTracking::Configuration {
TestConfiguration() { this = "TestConfiguration" }
override predicate isSource(Node src) {
src.asExpr().(CallExpr).getStaticTarget().getName().matches("source%")
}
override predicate isSink(Node sink) {
exists(CallExpr sinkCall |
sinkCall.getStaticTarget().getName().matches("sink%") and
sinkCall.getAnArgument().getExpr() = sink.asExpr()
)
}
override int explorationLimit() { result = 100 }
}
from PathNode src, PathNode sink, TestConfiguration test
where test.hasFlowPath(src, sink)
select sink, src, sink, "result"

Просмотреть файл

@ -0,0 +1,20 @@
import swift
import codeql.swift.dataflow.TaintTracking
import codeql.swift.dataflow.DataFlow::DataFlow
class TestConfiguration extends TaintTracking::Configuration {
TestConfiguration() { this = "TestConfiguration" }
override predicate isSource(Node src) {
src.asExpr().(CallExpr).getStaticTarget().getName().matches("source%")
}
override predicate isSink(Node sink) {
exists(CallExpr sinkCall |
sinkCall.getStaticTarget().getName().matches("sink%") and
sinkCall.getAnArgument().getExpr() = sink.asExpr()
)
}
override int explorationLimit() { result = 100 }
}

Просмотреть файл

Просмотреть файл

@ -0,0 +1,20 @@
import swift
import Taint
import TestUtilities.InlineExpectationsTest
class TaintTest extends InlineExpectationsTest {
TaintTest() { this = "TaintTest" }
override string getARelevantTag() { result = "tainted" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(TestConfiguration config, Node source, Node sink, Expr sinkExpr |
config.hasFlow(source, sink) and
sinkExpr = sink.asExpr() and
location = sinkExpr.getLocation() and
element = sinkExpr.toString() and
tag = "tainted" and
value = source.asExpr().getLocation().getStartLine().toString()
)
}
}

Просмотреть файл

@ -14,12 +14,12 @@ func taintThroughData() {
let dataTainted2 = Data(dataTainted)
sink(arg: dataClean)
sink(arg: dataTainted) // tainted [NOT DETECTED]
sink(arg: dataTainted2) // tainted [NOT DETECTED]
sink(arg: dataTainted) // $ MISSING: tainted=13
sink(arg: dataTainted2) // $ MISSING: tainted=13
let stringClean = String(data: dataClean, encoding: String.Encoding.utf8)
let stringTainted = String(data: dataTainted, encoding: String.Encoding.utf8)
sink2(arg: stringClean!) // tainted [NOT DETECTED]
sink2(arg: stringTainted!) // tainted [NOT DETECTED]
sink2(arg: stringClean!) // $ MISSING: tainted=13
sink2(arg: stringTainted!) // $ MISSING: tainted=13
}

Просмотреть файл

@ -4,18 +4,18 @@ func sink(arg: String) {}
func taintThroughInterpolatedStrings() {
var x = source()
sink(arg: "\(x)") // tainted
sink(arg: "\(x)") // $ tainted=5
sink(arg: "\(x) \(x)") // tainted
sink(arg: "\(x) \(x)") // $ tainted=5
sink(arg: "\(x) \(0) \(x)") // tainted
sink(arg: "\(x) \(0) \(x)") // $ tainted=5
var y = 42
sink(arg: "\(y)") // clean
sink(arg: "\(x) hello \(y)") // tainted
sink(arg: "\(x) hello \(y)") // $ tainted=5
sink(arg: "\(y) world \(x)") // tainted
sink(arg: "\(y) world \(x)") // $ tainted=5
x = 0
sink(arg: "\(x)") // clean
@ -28,15 +28,15 @@ func taintThroughStringConcatenation() {
var tainted = source2()
sink(arg: clean)
sink(arg: tainted) // tainted
sink(arg: tainted) // $ tainted=28
sink(arg: clean + clean)
sink(arg: clean + tainted) // tainted
sink(arg: tainted + clean) // tainted
sink(arg: tainted + tainted) // tainted
sink(arg: clean + tainted) // $ tainted=28
sink(arg: tainted + clean) // $ tainted=28
sink(arg: tainted + tainted) // $ tainted=28
sink(arg: ">" + clean + "<")
sink(arg: ">" + tainted + "<") // tainted
sink(arg: ">" + tainted + "<") // $ tainted=28
var str = "abc"
@ -46,7 +46,7 @@ func taintThroughStringConcatenation() {
sink(arg: str)
str += source2()
sink(arg: str) // tainted [NOT DETECTED]
sink(arg: str) // $ MISSING: tainted=48
var str2 = "abc"
@ -56,7 +56,7 @@ func taintThroughStringConcatenation() {
sink(arg: str2)
str2.append(source2())
sink(arg: str2) // tainted [NOT DETECTED]
sink(arg: str2) // $ MISSING: tainted=58
var str3 = "abc"
@ -66,7 +66,7 @@ func taintThroughStringConcatenation() {
sink(arg: str3)
str3.append(contentsOf: source2())
sink(arg: str2) // tainted [NOT DETECTED]
sink(arg: str2) // $ MISSING: tainted=68
}
func taintThroughStringOperations() {
@ -75,15 +75,15 @@ func taintThroughStringOperations() {
var taintedInt = source()
sink(arg: String(clean))
sink(arg: String(tainted)) // tainted [NOT DETECTED]
sink(arg: String(taintedInt)) // tainted [NOT DETECTED]
sink(arg: String(tainted)) // $ MISSING: tainted=74
sink(arg: String(taintedInt)) // $ MISSING: tainted=75
sink(arg: String(repeating: clean, count: 2))
sink(arg: String(repeating: tainted, count: 2)) // tainted [NOT DETECTED]
sink(arg: String(repeating: tainted, count: 2)) // $ MISSING: tainted=74
sink(arg: clean.description)
sink(arg: tainted.description) // tainted [NOT DETECTED]
sink(arg: tainted.description) // $ MISSING: tainted=74
sink(arg: clean.debugDescription)
sink(arg: tainted.debugDescription) // tainted [NOT DETECTED]
sink(arg: tainted.debugDescription) // $ MISSING: tainted=74
}

Просмотреть файл

@ -6,14 +6,14 @@ func taintThroughTry() {
do
{
sink(arg: try clean())
sink(arg: try source()) // tainted
sink(arg: try source()) // $ tainted=9
} catch {
// ...
}
sink(arg: try! clean())
sink(arg: try! source()) // tainted
sink(arg: try! source()) // $ tainted=15
sink(arg: (try? clean())!)
sink(arg: (try? source())!) // tainted
sink(arg: (try? source())!) // $ tainted=18
}

Просмотреть файл

@ -15,19 +15,19 @@ func taintThroughURL() {
let urlTainted = URL(string: tainted)!
sink(arg: urlClean)
sink(arg: urlTainted) // tainted
sink(arg: urlTainted) // $ tainted=13
sink(arg: URL(string: clean, relativeTo: nil)!)
sink(arg: URL(string: tainted, relativeTo: nil)!) // tainted
sink(arg: URL(string: tainted, relativeTo: nil)!) // $ tainted=13
sink(arg: URL(string: clean, relativeTo: urlClean)!)
sink(arg: URL(string: clean, relativeTo: urlTainted)!) // tainted
sink(arg: URL(string: clean, relativeTo: urlTainted)!) // $ tainted=13
if let x = URL(string: clean) {
sink(arg: x)
}
if let y = URL(string: tainted) {
sink(arg: y) // tainted [NOT DETECTED]
sink(arg: y) // $ MISSING: tainted=13
}
var urlClean2 : URL!
@ -36,5 +36,5 @@ func taintThroughURL() {
var urlTainted2 : URL!
urlTainted2 = URL(string: tainted)
sink(arg: urlTainted2) // tainted
sink(arg: urlTainted2) // $ tainted=13
}