mirror of
https://github.com/github/codeql.git
synced 2026-08-03 00:43:00 +02:00
517 lines
21 KiB
Swift
517 lines
21 KiB
Swift
|
|
class NSObject
|
|
{
|
|
}
|
|
|
|
struct URL
|
|
{
|
|
typealias BookmarkResolutionOptions = NSURL.BookmarkResolutionOptions
|
|
|
|
struct URLResourceKey : Hashable {
|
|
init(_ rawValue: String) { }
|
|
init(rawValue: String) { }
|
|
|
|
// …
|
|
}
|
|
|
|
struct URLResourceValues {
|
|
var name: String?
|
|
var path: String?
|
|
var canonicalPath: String?
|
|
var localizedLabel: String?
|
|
var localizedName: String?
|
|
var parentDirectory: URL?
|
|
|
|
// …
|
|
}
|
|
|
|
struct AsyncBytes {
|
|
// …
|
|
}
|
|
|
|
enum DirectoryHint {
|
|
case inferFromPath
|
|
}
|
|
|
|
init?(string: String) {}
|
|
init?(string: String, relativeTo: URL?) {}
|
|
init(fileURLWithPath path: String) { }
|
|
init(fileURLWithPath path: String, isDirectory: Bool) { }
|
|
init(fileURLWithPath path: String, relativeTo base: URL?) { }
|
|
init(fileURLWithPath path: String, isDirectory: Bool, relativeTo base: URL?) { }
|
|
init(fileURLWithFileSystemRepresentation path: UnsafePointer<Int8>, isDirectory: Bool, relativeTo baseURL: URL?) { }
|
|
init(fileReferenceLiteralResourceName name: String) { }
|
|
init?(_ path: FilePath) { }
|
|
init?(_ path: FilePath, isDirectory: Bool) { }
|
|
init(resolvingBookmarkData data: Data, options: URL.BookmarkResolutionOptions = [], relativeTo url: URL? = nil, bookmarkDataIsStale: inout Bool) throws { }
|
|
init(resolvingAliasFileAt url: URL, options: URL.BookmarkResolutionOptions = []) throws { }
|
|
init?(resource: URLResource) { }
|
|
init?(dataRepresentation: Data, relativeTo url: URL?, isAbsolute: Bool = false) { }
|
|
init?(filePath path: FilePath, directoryHint: URL.DirectoryHint = .inferFromPath) { }
|
|
init(filePath path: String, directoryHint: URL.DirectoryHint = .inferFromPath, relativeTo base: URL? = nil) { }
|
|
|
|
var dataRepresentation: Data { get { return Data(0) } }
|
|
var absoluteString: String { get { return "" } }
|
|
var absoluteURL: URL { get {return URL(string: "")!} }
|
|
var baseURL: URL { get {return URL(string: "")!} }
|
|
var fragment: String? { get {return nil} }
|
|
var host: String? { get {return nil} }
|
|
var lastPathComponent: String { get {return ""} }
|
|
var path: String { get {return ""} }
|
|
var pathComponents: [String] { get {return [""]} }
|
|
var pathExtension: String { get {return ""} }
|
|
var port: Int? { get {return nil} }
|
|
var query: String? { get {return nil} }
|
|
var relativePath: String { get {return ""} }
|
|
var relativeString: String { get {return ""} }
|
|
var scheme: String? { get {return nil} }
|
|
var standardized: URL { get {return URL(string: "")!} }
|
|
var standardizedFileURL: URL { get {return URL(string: "")!} }
|
|
var user: String? { get {return nil} }
|
|
var password: String? { get {return nil} }
|
|
var resourceBytes: URL.AsyncBytes { get { return (nil as AsyncBytes?)! } }
|
|
var lines: AsyncLineSequence<URL.AsyncBytes> { get { return (nil as AsyncLineSequence<URL.AsyncBytes>?)! } }
|
|
|
|
func resourceValues(forKeys keys: Set<URLResourceKey>) throws -> URLResourceValues { return URLResourceValues() }
|
|
static func resourceValues(forKeys keys: Set<URLResourceKey>, fromBookmarkData data: Data) -> URLResourceValues? { return nil }
|
|
mutating func setResourceValues(_ values: URLResourceValues) throws { }
|
|
mutating func setTemporaryResourceValue(_ value: Any, forKey key: URLResourceKey) { }
|
|
func withUnsafeFileSystemRepresentation<ResultType>(_ block: (UnsafePointer<Int8>?) throws -> ResultType) rethrows -> ResultType { return (nil as ResultType?)! }
|
|
func resolvingSymlinksInPath() -> URL { return URL(string: "")! }
|
|
mutating func appendPathComponent(_ pathComponent: String) { }
|
|
mutating func appendPathComponent(_ pathComponent: String, isDirectory: Bool) { }
|
|
func appendingPathComponent(_ pathComponent: String) -> URL { return URL(string: "")! }
|
|
func appendingPathComponent(_ pathComponent: String, isDirectory: Bool) -> URL { return URL(string: "")! }
|
|
mutating func appendPathExtension(_ pathExtension: String) { }
|
|
func appendingPathExtension(_ pathExtension: String) -> URL { return URL(string: "")! }
|
|
func deletingLastPathComponent() -> URL { return URL(string: "")! }
|
|
func deletingPathExtension() -> URL { return URL(string: "")! }
|
|
mutating func append<S>(component: S, directoryHint: URL.DirectoryHint = .inferFromPath) where S: StringProtocol { }
|
|
mutating func append<S>(components: S..., directoryHint: URL.DirectoryHint = .inferFromPath) where S: StringProtocol { }
|
|
mutating func append<S>(path: S, directoryHint: URL.DirectoryHint = .inferFromPath) where S: StringProtocol { }
|
|
mutating func append(queryItems: [URLQueryItem]) { }
|
|
func appending<S>(component: S, directoryHint: URL.DirectoryHint = .inferFromPath) -> URL where S: StringProtocol { return URL(string: "")! }
|
|
func appending<S>(components: S..., directoryHint: URL.DirectoryHint = .inferFromPath) -> URL where S: StringProtocol { return URL(string: "")! }
|
|
func appending<S>(path: S, directoryHint: URL.DirectoryHint = .inferFromPath) -> URL where S: StringProtocol { return URL(string: "")! }
|
|
func appending(queryItems: [URLQueryItem]) -> URL { return URL(string: "")! }
|
|
func promisedItemResourceValues(forKeys keys: Set<URLResourceKey>) throws -> URLResourceValues { return (nil as URLResourceValues?)! }
|
|
func formatted() -> String { return "" }
|
|
func fragment(percentEncoded: Bool = true) -> String? { return nil }
|
|
func host(percentEncoded: Bool = true) -> String? { return nil }
|
|
func password(percentEncoded: Bool = true) -> String? { return nil }
|
|
func path(percentEncoded: Bool = true) -> String { return "" }
|
|
func query(percentEncoded: Bool = true) -> String? { return nil }
|
|
func user(percentEncoded: Bool = true) -> String? { return nil }
|
|
|
|
// simplified:
|
|
func bookmarkData(options: Int = 0, includingResourceValuesForKeys keys: Set<URLResourceKey>? = nil, relativeTo url: URL? = nil) throws -> Data { return Data(0) }
|
|
static func bookmarkData(withContentsOf url: URL) throws -> Data { return Data(0) }
|
|
|
|
static var homeDirectory: URL { get { return URL(string: "")! } }
|
|
static func homeDirectory(forUser user: String) -> URL? { return nil }
|
|
}
|
|
|
|
class NSURL {
|
|
struct BookmarkResolutionOptions : OptionSet {
|
|
let rawValue: Int
|
|
}
|
|
|
|
init?(string: String) {}
|
|
}
|
|
|
|
class Data
|
|
{
|
|
init<S>(_ elements: S) {}
|
|
}
|
|
|
|
struct FilePath {
|
|
init(_ string: String) {}
|
|
}
|
|
|
|
struct AsyncLineSequence<Base> : AsyncSequence {
|
|
typealias Element = String
|
|
struct AsyncIterator : AsyncIteratorProtocol {
|
|
typealias Element = String
|
|
mutating func next() async -> String? { return nil }
|
|
}
|
|
func makeAsyncIterator() -> AsyncIterator { return AsyncIterator() }
|
|
}
|
|
|
|
class InputStream {}
|
|
|
|
struct Mirror {}
|
|
|
|
typealias TimeInterval = Double
|
|
|
|
struct URLResource {
|
|
// simplified:
|
|
init(name: String, subdirectory: String? = nil, locale: Int = 0, bundle: Int = 0) {
|
|
self.name = name
|
|
self.subdirectory = subdirectory
|
|
}
|
|
|
|
let name: String
|
|
let subdirectory: String?
|
|
}
|
|
|
|
struct URLRequest : CustomStringConvertible, CustomDebugStringConvertible {
|
|
enum CachePolicy { case none }
|
|
enum NetworkServiceType { case none }
|
|
enum Attribution { case none }
|
|
var cachePolicy: CachePolicy = .none
|
|
var httpMethod: String? = ""
|
|
var url: URL? = URL(string: "")
|
|
var httpBody: Data? = Data("")
|
|
var httpBodyStream: InputStream? = nil
|
|
var mainDocument: URL = URL(string: "")!
|
|
var mainDocumentURL: URL? = URL(string: "")
|
|
var allHTTPHeaderFields: [String : String]? = nil
|
|
var timeoutInterval: TimeInterval = TimeInterval()
|
|
var httpShouldHandleCookies: Bool = false
|
|
var httpShouldUsePipelining: Bool = false
|
|
var allowsCellularAccess: Bool = false
|
|
var allowsConstrainedNetworkAccess: Bool = false
|
|
var allowsExpensiveNetworkAccess: Bool = false
|
|
var networkServiceType: NetworkServiceType = .none
|
|
var attribution: Attribution = .none
|
|
var description: String = ""
|
|
var debugDescription: String = ""
|
|
var customMirror: Mirror = Mirror()
|
|
var hashValue: Int = 0
|
|
var assumesHTTP3Capable: Bool = false
|
|
var requiresDNSSECValidation: Bool = false
|
|
}
|
|
|
|
struct URLQueryItem { }
|
|
|
|
class URLResponse : NSObject { }
|
|
|
|
class URLSessionTask : NSObject { }
|
|
|
|
class URLSessionDataTask : URLSessionTask { }
|
|
|
|
class URLSession {
|
|
class var shared: URLSession { get { return URLSession() } }
|
|
|
|
func dataTask(
|
|
with url: URL,
|
|
completionHandler: (Data?, URLResponse?, Error?) -> Void
|
|
) -> URLSessionDataTask { return URLSessionDataTask() }
|
|
}
|
|
|
|
func source() -> Any { return "" }
|
|
func sink(arg: URL) {}
|
|
func sink(data: Data) {}
|
|
func sink(string: String) {}
|
|
func sink(int: Int) {}
|
|
func sink(any: Any) {}
|
|
func taintThroughURL() {
|
|
let clean = "http://example.com/"
|
|
let tainted = source() as! String
|
|
let urlClean = URL(string: clean)!
|
|
let urlTainted = URL(string: tainted)!
|
|
|
|
sink(arg: urlClean)
|
|
sink(arg: urlTainted) // $ tainted=210
|
|
// Fields
|
|
sink(data: urlTainted.dataRepresentation) // $ tainted=210
|
|
sink(string: urlTainted.absoluteString) // $ tainted=210
|
|
sink(arg: urlTainted.absoluteURL) // $ tainted=210
|
|
sink(arg: urlTainted.baseURL) // $ tainted=210
|
|
sink(string: urlTainted.fragment!) // $ tainted=210
|
|
sink(string: urlTainted.host!) // $ tainted=210
|
|
sink(string: urlTainted.lastPathComponent) // $ tainted=210
|
|
sink(string: urlTainted.path) // $ tainted=210
|
|
sink(string: urlTainted.pathComponents[0]) // $ tainted=210
|
|
sink(string: urlTainted.pathExtension) // $ tainted=210
|
|
sink(int: urlTainted.port!) // $ tainted=210
|
|
sink(string: urlTainted.query!) // $ tainted=210
|
|
sink(string: urlTainted.relativePath) // $ tainted=210
|
|
sink(string: urlTainted.relativeString) // $ tainted=210
|
|
sink(string: urlTainted.scheme!) // $ tainted=210
|
|
sink(arg: urlTainted.standardized) // $ tainted=210
|
|
sink(arg: urlTainted.standardizedFileURL) // $ tainted=210
|
|
sink(string: urlTainted.user!) // $ tainted=210
|
|
sink(string: urlTainted.password!) // $ tainted=210
|
|
sink(any: urlTainted.resourceBytes) // $ tainted=210
|
|
|
|
sink(arg: URL(string: clean, relativeTo: nil)!)
|
|
sink(arg: URL(string: tainted, relativeTo: nil)!) // $ tainted=210
|
|
sink(arg: URL(string: clean, relativeTo: urlClean)!)
|
|
// Fields (assuming `clean` was a relative path instead of a full URL)
|
|
sink(arg: URL(string: clean, relativeTo: urlTainted)!.absoluteURL) // $ tainted=210
|
|
sink(arg: URL(string: clean, relativeTo: urlTainted)!.baseURL) // $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.fragment!) // $ $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.host!) // $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.lastPathComponent) // $ $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.path) // $ $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.pathComponents[0]) // $ $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.pathExtension) // $ $ tainted=210
|
|
sink(int: URL(string: clean, relativeTo: urlTainted)!.port!) // $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.query!) // $ $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.relativePath) // $ $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.relativeString) // $ $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.scheme!) // $ tainted=210
|
|
sink(arg: URL(string: clean, relativeTo: urlTainted)!.standardized) // $ tainted=210
|
|
sink(arg: URL(string: clean, relativeTo: urlTainted)!.standardizedFileURL) // $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.user!) // $ tainted=210
|
|
sink(string: URL(string: clean, relativeTo: urlTainted)!.password!) // $ tainted=210
|
|
|
|
if let x = URL(string: clean) {
|
|
sink(arg: x)
|
|
}
|
|
if let y = URL(string: tainted) {
|
|
sink(arg: y) // $ tainted=210
|
|
}
|
|
|
|
var urlClean2 : URL!
|
|
urlClean2 = URL(string: clean)
|
|
sink(arg: urlClean2)
|
|
|
|
var urlTainted2 : URL!
|
|
urlTainted2 = URL(string: tainted)
|
|
sink(arg: urlTainted2) // $ tainted=210
|
|
|
|
let _ = URLSession.shared.dataTask(with: urlTainted) { (data, response, error) in
|
|
sink(data: data!) // $ tainted=210
|
|
}
|
|
|
|
sink(arg: URL(fileURLWithPath: tainted)) // $ tainted=210
|
|
sink(arg: URL(fileURLWithPath: tainted, isDirectory: false)) // $ tainted=210
|
|
sink(arg: URL(fileURLWithPath: tainted, relativeTo: urlClean)) // $ tainted=210
|
|
sink(arg: URL(fileURLWithPath: clean, relativeTo: urlTainted)) // $ tainted=210
|
|
sink(arg: URL(fileURLWithPath: tainted, isDirectory: false, relativeTo: urlClean)) // $ tainted=210
|
|
sink(arg: URL(fileURLWithPath: clean, isDirectory: false, relativeTo: urlTainted)) // $ tainted=210
|
|
sink(arg: URL(fileURLWithPath: tainted)) // $ tainted=210
|
|
|
|
let _ = clean.withCString({
|
|
ptrClean in
|
|
sink(arg: URL(fileURLWithFileSystemRepresentation: ptrClean, isDirectory: false, relativeTo: nil))
|
|
sink(arg: URL(fileURLWithFileSystemRepresentation: ptrClean, isDirectory: false, relativeTo: urlTainted)) // $ tainted=210
|
|
});
|
|
sink(arg: URL(fileURLWithFileSystemRepresentation: 0 as! UnsafePointer<Int8>, isDirectory: false, relativeTo: urlTainted)) // $ tainted=210
|
|
let _ = tainted.withCString({
|
|
ptrTainted in
|
|
sink(arg: URL(fileURLWithFileSystemRepresentation: ptrTainted, isDirectory: false, relativeTo: nil)) // $ MISSING: tainted=210
|
|
})
|
|
|
|
sink(arg: URL(fileReferenceLiteralResourceName: tainted)) // $ tainted=210
|
|
sink(arg: URL(FilePath(tainted))!) // $ tainted=210
|
|
sink(arg: URL(FilePath(tainted), isDirectory: false)!) // $ tainted=210
|
|
|
|
if let values = try? urlTainted.resourceValues(forKeys: []) {
|
|
sink(any: values) // $ tainted=210
|
|
sink(string: values.name!) // $ tainted=210
|
|
sink(string: values.path!) // $ tainted=210
|
|
sink(string: values.canonicalPath!) // $ tainted=210
|
|
sink(string: values.localizedLabel!) // $ tainted=210
|
|
sink(string: values.localizedName!) // $ tainted=210
|
|
sink(any: values.parentDirectory!) // $ tainted=210
|
|
}
|
|
if let values = try? urlTainted.promisedItemResourceValues(forKeys: []) {
|
|
sink(any: values) // $ tainted=210
|
|
sink(string: values.name!) // $ tainted=210
|
|
sink(string: values.path!) // $ tainted=210
|
|
sink(string: values.canonicalPath!) // $ tainted=210
|
|
sink(string: values.localizedLabel!) // $ tainted=210
|
|
sink(string: values.localizedName!) // $ tainted=210
|
|
sink(any: values.parentDirectory!) // $ tainted=210
|
|
}
|
|
|
|
urlClean.withUnsafeFileSystemRepresentation({
|
|
ptr in
|
|
sink(any: ptr!)
|
|
})
|
|
urlTainted.withUnsafeFileSystemRepresentation({
|
|
ptr in
|
|
sink(any: ptr!) // $ tainted=210
|
|
})
|
|
|
|
sink(arg: urlTainted.resolvingSymlinksInPath()) // $ tainted=210
|
|
sink(arg: urlTainted.appendingPathComponent(clean)) // $ tainted=210
|
|
sink(arg: urlClean.appendingPathComponent(tainted)) // $ tainted=210
|
|
sink(arg: urlTainted.appendingPathComponent(clean, isDirectory: false)) // $ tainted=210
|
|
sink(arg: urlClean.appendingPathComponent(tainted, isDirectory: false)) // $ tainted=210
|
|
sink(arg: urlTainted.appendingPathExtension(clean)) // $ tainted=210
|
|
sink(arg: urlClean.appendingPathExtension(tainted)) // $ tainted=210
|
|
sink(arg: urlTainted.deletingLastPathComponent()) // $ tainted=210
|
|
sink(arg: urlTainted.deletingPathExtension()) // $ tainted=210
|
|
sink(arg: urlTainted.appending(component: clean)) // $ tainted=210
|
|
sink(arg: urlClean.appending(component: tainted)) // $ tainted=210
|
|
sink(arg: urlTainted.appending(components: clean)) // $ tainted=210
|
|
sink(arg: urlClean.appending(components: tainted)) // $ MISSING: tainted=210
|
|
sink(arg: urlClean.appending(components: clean, tainted)) // $ MISSING: tainted=210
|
|
sink(arg: urlTainted.appending(path: clean)) // $ tainted=210
|
|
sink(arg: urlClean.appending(path: tainted)) // $ tainted=210
|
|
sink(arg: urlTainted.appending(queryItems: [])) // $ tainted=210
|
|
sink(arg: urlClean.appending(queryItems: [source() as! URLQueryItem])) // $ MISSING: tainted=210
|
|
|
|
sink(arg: URL(filePath: tainted)) // $ tainted=210
|
|
sink(arg: URL(filePath: tainted, relativeTo: nil)) // $ tainted=210
|
|
sink(arg: URL(filePath: clean, relativeTo: urlTainted)) // $ tainted=210
|
|
sink(arg: try! URL(resolvingAliasFileAt: urlTainted)) // $ tainted=210
|
|
sink(arg: URL(resource: URLResource(name: tainted))!) // $ tainted=210
|
|
sink(arg: URL(resource: URLResource(name: clean, subdirectory: tainted))!) // $ tainted=210
|
|
|
|
let dataClean = Data(clean)
|
|
let dataTainted = Data(tainted)
|
|
var stale = true
|
|
sink(arg: URL(dataRepresentation: dataTainted, relativeTo: urlClean)!) // $ tainted=210
|
|
sink(arg: URL(dataRepresentation: dataClean, relativeTo: urlTainted)!) // $ tainted=210
|
|
sink(arg: try! URL(resolvingBookmarkData: dataTainted, bookmarkDataIsStale: &stale)) // $ tainted=210
|
|
sink(arg: try! URL(resolvingBookmarkData: dataClean, relativeTo: urlTainted, bookmarkDataIsStale: &stale)) // $ tainted=210
|
|
|
|
sink(string: urlTainted.formatted()) // $ tainted=210
|
|
sink(string: urlTainted.fragment()!) // $ tainted=210
|
|
sink(string: urlTainted.host()!) // $ tainted=210
|
|
sink(string: urlTainted.password()!) // $ tainted=210
|
|
sink(string: urlTainted.path()) // $ tainted=210
|
|
sink(string: urlTainted.query()!) // $ tainted=210
|
|
sink(string: urlTainted.user()!) // $ tainted=210
|
|
|
|
var url1 = URL(string: clean)!
|
|
if let values = try? urlClean.resourceValues(forKeys: []) {
|
|
try! url1.setResourceValues(values)
|
|
}
|
|
sink(arg: url1)
|
|
if let values = try? urlTainted.resourceValues(forKeys: []) {
|
|
try! url1.setResourceValues(values)
|
|
}
|
|
sink(arg: url1) // $ tainted=210
|
|
|
|
var url2 = URL(string: clean)!
|
|
url2.setTemporaryResourceValue(source(), forKey: URL.URLResourceKey(""))
|
|
sink(arg: url2) // $ tainted=383
|
|
|
|
var url3 = URL(string: clean)!
|
|
url3.appendPathComponent(clean)
|
|
sink(arg: url3)
|
|
url3.appendPathComponent(tainted)
|
|
sink(arg: url3) // $ tainted=210
|
|
|
|
var url4 = URL(string: clean)!
|
|
url4.appendPathComponent(tainted, isDirectory: false)
|
|
sink(arg: url4) // $ tainted=210
|
|
|
|
var url5 = URL(string: clean)!
|
|
url5.appendPathExtension(tainted)
|
|
sink(arg: url5) // $ tainted=210
|
|
|
|
var url6 = URL(string: clean)!
|
|
url6.append(component: tainted)
|
|
sink(arg: url6) // $ tainted=210
|
|
|
|
var url7 = URL(string: clean)!
|
|
url7.append(components: tainted)
|
|
sink(arg: url7) // $ MISSING: tainted=210
|
|
|
|
var url8 = URL(string: clean)!
|
|
url8.append(components: clean, tainted)
|
|
sink(arg: url8) // $ MISSING: tainted=210
|
|
|
|
var url9 = URL(string: clean)!
|
|
url9.append(path: tainted)
|
|
sink(arg: url9) // $ tainted=210
|
|
|
|
var url10 = URL(string: clean)!
|
|
url10.append(queryItems: [source() as! URLQueryItem])
|
|
sink(arg: url10) // $ MISSING: tainted=210
|
|
|
|
sink(data: try! urlTainted.bookmarkData()) // $ tainted=210
|
|
sink(data: try! URL.bookmarkData(withContentsOf: urlTainted)) // $ tainted=210
|
|
sink(any: URL.resourceValues(forKeys: [], fromBookmarkData: dataTainted)!) // $ tainted=210
|
|
|
|
sink(arg: URL.homeDirectory) // (static var, not tainted)
|
|
sink(arg: URL.homeDirectory(forUser: clean)!)
|
|
sink(arg: URL.homeDirectory(forUser: tainted)!) // $ tainted=210
|
|
}
|
|
|
|
func taintThroughUrlRequest() {
|
|
let clean = URLRequest()
|
|
let tainted = source() as! URLRequest
|
|
|
|
sink(any: clean)
|
|
sink(any: tainted) // $ tainted=431
|
|
sink(any: clean.cachePolicy)
|
|
sink(any: tainted.cachePolicy)
|
|
sink(any: clean.httpMethod)
|
|
sink(any: tainted.httpMethod)
|
|
sink(any: clean.url!)
|
|
sink(any: tainted.url!) // $ tainted=431
|
|
sink(any: clean.httpBody!)
|
|
sink(any: tainted.httpBody!) // $ tainted=431
|
|
sink(any: clean.httpBodyStream!)
|
|
sink(any: tainted.httpBodyStream!) // $ tainted=431
|
|
sink(any: clean.mainDocument)
|
|
sink(any: tainted.mainDocument) // $ tainted=431
|
|
sink(any: clean.mainDocumentURL!)
|
|
sink(any: tainted.mainDocumentURL!) // $ tainted=431
|
|
sink(any: clean.allHTTPHeaderFields!)
|
|
sink(any: tainted.allHTTPHeaderFields!) // $ tainted=431
|
|
sink(any: clean.timeoutInterval)
|
|
sink(any: tainted.timeoutInterval)
|
|
sink(any: clean.httpShouldHandleCookies)
|
|
sink(any: tainted.httpShouldHandleCookies)
|
|
sink(any: clean.httpShouldUsePipelining)
|
|
sink(any: tainted.httpShouldUsePipelining)
|
|
sink(any: clean.allowsCellularAccess)
|
|
sink(any: tainted.allowsCellularAccess)
|
|
sink(any: clean.allowsConstrainedNetworkAccess)
|
|
sink(any: tainted.allowsConstrainedNetworkAccess)
|
|
sink(any: clean.allowsExpensiveNetworkAccess)
|
|
sink(any: tainted.allowsExpensiveNetworkAccess)
|
|
sink(any: clean.networkServiceType)
|
|
sink(any: tainted.networkServiceType)
|
|
sink(any: clean.attribution)
|
|
sink(any: tainted.attribution)
|
|
sink(any: clean.description)
|
|
sink(any: tainted.description) // $ tainted=431
|
|
sink(any: clean.debugDescription)
|
|
sink(any: tainted.debugDescription) // $ tainted=431
|
|
sink(any: clean.customMirror)
|
|
sink(any: tainted.customMirror)
|
|
sink(any: clean.hashValue)
|
|
sink(any: tainted.hashValue)
|
|
sink(any: clean.assumesHTTP3Capable)
|
|
sink(any: tainted.assumesHTTP3Capable)
|
|
sink(any: clean.requiresDNSSECValidation)
|
|
sink(any: tainted.requiresDNSSECValidation)
|
|
}
|
|
|
|
func taintThroughUrlResource() {
|
|
let clean = URLResource(name: "")
|
|
let tainted = source() as! URLResource
|
|
|
|
sink(string: clean.name)
|
|
sink(string: tainted.name) // $ tainted=483
|
|
sink(string: clean.subdirectory!)
|
|
sink(string: tainted.subdirectory!) // $ tainted=483
|
|
}
|
|
|
|
func taintUrlAsync() async throws {
|
|
let tainted = source() as! String
|
|
let urlTainted = URL(string: tainted)!
|
|
|
|
sink(any: urlTainted.lines) // $ tainted=492
|
|
|
|
for try await line in urlTainted.lines {
|
|
sink(string: line) // $ MISSING: tainted=492
|
|
}
|
|
}
|
|
|
|
func closureReturnValue() {
|
|
let url = URL(string: "http://example.com/")!
|
|
|
|
let r1 = url.withUnsafeFileSystemRepresentation({
|
|
ptr in
|
|
return "abc"
|
|
})
|
|
sink(string: r1)
|
|
|
|
let r2 = url.withUnsafeFileSystemRepresentation({
|
|
ptr in
|
|
return source() as! String
|
|
})
|
|
sink(string: r2) // $ tainted=513
|
|
}
|