mirror of
https://github.com/github/codeql.git
synced 2026-04-20 14:34:04 +02:00
Add path injection query
This commit is contained in:
@@ -82,10 +82,12 @@ private module Frameworks {
|
||||
private import codeql.swift.frameworks.StandardLibrary.Data
|
||||
private import codeql.swift.frameworks.StandardLibrary.InputStream
|
||||
private import codeql.swift.frameworks.StandardLibrary.NSData
|
||||
private import codeql.swift.frameworks.StandardLibrary.NsUrl
|
||||
private import codeql.swift.frameworks.StandardLibrary.String
|
||||
private import codeql.swift.frameworks.StandardLibrary.Url
|
||||
private import codeql.swift.frameworks.StandardLibrary.UrlSession
|
||||
private import codeql.swift.frameworks.StandardLibrary.WebView
|
||||
private import codeql.swift.security.PathInjection
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import swift
|
||||
private import codeql.swift.dataflow.DataFlow
|
||||
private import codeql.swift.dataflow.ExternalFlow
|
||||
private import codeql.swift.dataflow.FlowSteps
|
||||
|
||||
/**
|
||||
* A model for `NSURL` members that permit taint flow.
|
||||
*/
|
||||
private class NsUrlSummaries extends SummaryModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
";NSURL;true;init(string:);(String);;Argument[0];ReturnValue;taint",
|
||||
// TODO
|
||||
]
|
||||
}
|
||||
}
|
||||
99
swift/ql/lib/codeql/swift/security/PathInjection.qll
Normal file
99
swift/ql/lib/codeql/swift/security/PathInjection.qll
Normal file
@@ -0,0 +1,99 @@
|
||||
/** Provides classes and predicates to reason about path injection vulnerabilities. */
|
||||
|
||||
import swift
|
||||
private import codeql.swift.dataflow.DataFlow
|
||||
private import codeql.swift.dataflow.ExternalFlow
|
||||
|
||||
/** A data flow sink for path injection vulnerabilities. */
|
||||
abstract class PathInjectionSink extends DataFlow::Node { }
|
||||
|
||||
/** A sanitizer for path injection vulnerabilities. */
|
||||
abstract class PathInjectionSanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A unit class for adding additional taint steps.
|
||||
*
|
||||
* Extend this class to add additional taint steps that should apply to paths related to
|
||||
* path injection vulnerabilities.
|
||||
*/
|
||||
class PathInjectionAdditionalTaintStep extends Unit {
|
||||
/**
|
||||
* Holds if the step from `node1` to `node2` should be considered a taint
|
||||
* step for paths related to path injection vulnerabilities.
|
||||
*/
|
||||
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
|
||||
}
|
||||
|
||||
private class DefaultPathInjectionSink extends PathInjectionSink {
|
||||
DefaultPathInjectionSink() { sinkNode(this, "path-injection") }
|
||||
}
|
||||
|
||||
private class DefaultPathInjectionSanitizer extends PathInjectionSanitizer {
|
||||
DefaultPathInjectionSanitizer() { none() } // TODO: Implement a proper path sanitizer
|
||||
}
|
||||
|
||||
private class PathInjectionSinks extends SinkModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
";Data;true;write(to:options:);;;Argument[0];path-injection",
|
||||
";NSData;true;write(to:atomically:);;;Argument[0];path-injection",
|
||||
";NSData;true;write(to:options:);;;Argument[0];path-injection",
|
||||
";NSData;true;write(toFile:atomically:);;;Argument[0];path-injection",
|
||||
";NSData;true;write(toFile:options:);;;Argument[0];path-injection",
|
||||
";FileManager;true;contentsOfDirectory(at:includingPropertiesForKeys:options:);;;Argument[0];path-injection",
|
||||
";FileManager;true;contentsOfDirectory(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;enumerator(at:includingPropertiesForKeys:options:errorHandler:);;;Argument[0];path-injection",
|
||||
";FileManager;true;enumerator(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;subpathsOfDirectory(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;subpaths(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;createDirectory(at:withIntermediateDirectories:attributes:);;;Argument[0];path-injection",
|
||||
";FileManager;true;createDirectory(atPath:withIntermediateDirectories:attributes:);;;Argument[0];path-injection",
|
||||
";FileManager;true;createFile(atPath:contents:attributes:);;;Argument[0];path-injection",
|
||||
";FileManager;true;removeItem(at:);;;Argument[0];path-injection",
|
||||
";FileManager;true;removeItem(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;trashItem(at:resultingItemURL:);;;Argument[0];path-injection",
|
||||
";FileManager;true;replaceItem(at:withItemAt:backupItemName:options:resultingItemURL:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;replaceItemAt(_:withItemAt:backupItemName:options:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;replaceItemAt(_:withItemAt:backupItemName:options:resultingItemURL:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;copyItem(at:to:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;copyItem(atPath:toPath:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;moveItem(at:to:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;moveItem(atPath:toPath:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;createSymbolicLink(at:withDestinationURL:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;createSymbolicLink(atPath:withDestinationPath:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;linkItem(at:to:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;linkItem(atPath:toPath:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;destinationOfSymbolicLink(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;fileExists(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;fileExists(atPath:isDirectory:);;;Argument[0];path-injection",
|
||||
";FileManager;true;isReadableFile(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;isWritableFile(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;isDeletableFile(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;componentsToDisplay(forPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;displayName(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;attributesOfItem(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;attributesOfFileSystem(forPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;setAttributes(_:ofItemAtPath:);;;Argument[1];path-injection",
|
||||
";FileManager;true;contents(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;contentsEqual(atPath:andPath:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;getRelationship(_:ofDirectoryAt:toItemAt:);;;Argument[1..2];path-injection",
|
||||
";FileManager;true;getRelationship(_:of:in:toItemAt:);;;Argument[3];path-injection",
|
||||
";FileManager;true;changeCurrentDirectoryPath(_:);;;Argument[0];path-injection",
|
||||
";FileManager;true;unmountVolume(at:options:completionHandler:);;;Argument[0];path-injection",
|
||||
";FileManager;true;NSHFSTypeOfFile(_:);;;Argument[0];path-injection",
|
||||
// Deprecated FileManager methods:
|
||||
";FileManager;true;changeFileAttributes(_:atPath:);;;Argument[1];path-injection",
|
||||
";FileManager;true;fileAttributes(atPath:traverseLink:);;;Argument[0];path-injection",
|
||||
";FileManager;true;fileSystemAttributes(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;directoryContents(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;createDirectory(atPath:attributes:);;;Argument[0];path-injection",
|
||||
";FileManager;true;createSymbolicLink(atPath:pathContent:);;;Argument[0..1];path-injection",
|
||||
";FileManager;true;pathContentOfSymbolicLink(atPath:);;;Argument[0];path-injection",
|
||||
";FileManager;true;replaceItemAtURL(originalItemURL:withItemAtURL:backupItemName:options:);;;Argument[0..1];path-injection",
|
||||
";NIOFileHandle;true;init(descriptor:);;;Argument[0];path-injection",
|
||||
";NIOFileHandle;true;init(path:mode:flags:);;;Argument[0];path-injection",
|
||||
";NIOFileHandle;true;init(path:);;;Argument[0];path-injection"
|
||||
]
|
||||
}
|
||||
}
|
||||
30
swift/ql/lib/codeql/swift/security/PathInjectionQuery.qll
Normal file
30
swift/ql/lib/codeql/swift/security/PathInjectionQuery.qll
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Provides a taint-tracking configuration for reasoning about path injection
|
||||
* vulnerabilities.
|
||||
*/
|
||||
|
||||
import swift
|
||||
private import codeql.swift.dataflow.DataFlow
|
||||
private import codeql.swift.dataflow.ExternalFlow
|
||||
private import codeql.swift.dataflow.FlowSources
|
||||
private import codeql.swift.dataflow.TaintTracking
|
||||
private import codeql.swift.security.PathInjection
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for path injection vulnerabilities.
|
||||
*/
|
||||
class PathInjectionConfiguration extends TaintTracking::Configuration {
|
||||
PathInjectionConfiguration() { this = "PathInjectionConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof PathInjectionSink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node sanitizer) {
|
||||
sanitizer instanceof PathInjectionSanitizer
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
any(PathInjectionAdditionalTaintStep s).step(node1, node2)
|
||||
}
|
||||
}
|
||||
58
swift/ql/src/queries/Security/CWE-022/PathInjection.qhelp
Normal file
58
swift/ql/src/queries/Security/CWE-022/PathInjection.qhelp
Normal file
@@ -0,0 +1,58 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Accessing paths controlled by users can allow an attacker to access unexpected resources. This
|
||||
can result in sensitive information being revealed or deleted, or an attacker being able to influence
|
||||
behavior by modifying unexpected files.</p>
|
||||
|
||||
<p>Paths that are naively constructed from data controlled by a user may contain unexpected special characters,
|
||||
such as "..". Such a path may potentially point to any directory on the file system.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
|
||||
<p>Validate user input before using it to construct a file path. Ideally, follow these rules:</p>
|
||||
|
||||
<ul>
|
||||
<li>Do not allow more than a single "." character.</li>
|
||||
<li>Do not allow directory separators such as "/" or "\" (depending on the file system).</li>
|
||||
<li>Do not rely on simply replacing problematic sequences such as "../". For example, after applying this filter to
|
||||
".../...//" the resulting string would still be "../".</li>
|
||||
<li>Ideally use a whitelist of known good patterns.</li>
|
||||
</ul>
|
||||
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
In the first example, a file name is read from an HTTP request and then used to access a file.
|
||||
However, a malicious response could include a file name that is an absolute path, such as
|
||||
<code>"/Applications/(current_application)/Documents/sensitive.data"</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the second example, it appears that the user is restricted to opening a file within the
|
||||
<code>"/Library/Caches"</code> home directory. However, a malicious response could contain a file name containing
|
||||
special characters. For example, the string <code>"../../Documents/sensitive.data"</code> will result in the code
|
||||
reading the file located at <code>"/Applications/(current_application)/Library/Caches/../../Documents/sensitive.data"</code>,
|
||||
which contains users' sensitive data. This file may then be made accesible to an attacker, giving them access to all this data.
|
||||
</p>
|
||||
|
||||
<sample src="PathInjectionBad.swift" />
|
||||
|
||||
<p>
|
||||
In the third example, the path used to access the file system is normalized <em>before</em> being checked against a
|
||||
known prefix. This ensures that regardless of the user input, the resulting path is safe.
|
||||
</p>
|
||||
|
||||
<sample src="PathInjectionGood.swift" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>OWASP: <a href="https://owasp.org/www-community/attacks/Path_Traversal">Path Traversal</a>.</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
25
swift/ql/src/queries/Security/CWE-022/PathInjection.ql
Normal file
25
swift/ql/src/queries/Security/CWE-022/PathInjection.ql
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @name Uncontrolled data used in path expression
|
||||
* @description Accessing paths influenced by users can allow an attacker to access unexpected resources.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @security-severity 7.5
|
||||
* @precision high
|
||||
* @id swift/path-injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-022
|
||||
* external/cwe/cwe-023
|
||||
* external/cwe/cwe-036
|
||||
* external/cwe/cwe-073
|
||||
* external/cwe/cwe-099
|
||||
*/
|
||||
|
||||
import swift
|
||||
import codeql.swift.dataflow.DataFlow
|
||||
import codeql.swift.security.PathInjectionQuery
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where any(PathInjectionConfiguration c).hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "This path depends on a $@.", source.getNode(),
|
||||
"user-provided value"
|
||||
10
swift/ql/src/queries/Security/CWE-022/PathInjectionBad.swift
Normal file
10
swift/ql/src/queries/Security/CWE-022/PathInjectionBad.swift
Normal file
@@ -0,0 +1,10 @@
|
||||
let fm = FileManager.default
|
||||
let path = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
// BAD
|
||||
return fm.contents(atPath: path)
|
||||
|
||||
// BAD
|
||||
if (path.hasPrefix(NSHomeDirectory() + "/Library/Caches")) {
|
||||
return fm.contents(atPath: path)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
let fm = FileManager.default
|
||||
let path = try String(contentsOf: URL(string: "http://example.com/")!)
|
||||
|
||||
// GOOD
|
||||
let filePath = FilePath(stringLiteral: path)
|
||||
if (filePath.lexicallyNormalized().starts(with: FilePath(stringLiteral: NSHomeDirectory() + "/Library/Caches"))) {
|
||||
return fm.contents(atPath: path)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import swift
|
||||
import codeql.swift.dataflow.DataFlow
|
||||
import codeql.swift.dataflow.FlowSources
|
||||
import codeql.swift.security.PathInjectionQuery
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class PathInjectionTest extends InlineExpectationsTest {
|
||||
PathInjectionTest() { this = "PathInjectionTest" }
|
||||
|
||||
override string getARelevantTag() { result = "hasPathInjection" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(
|
||||
PathInjectionConfiguration config, DataFlow::Node source, DataFlow::Node sink, Expr sinkExpr
|
||||
|
|
||||
config.hasFlow(source, sink) and
|
||||
sinkExpr = sink.asExpr() and
|
||||
location = sinkExpr.getLocation() and
|
||||
element = sinkExpr.toString() and
|
||||
tag = "hasPathInjection" and
|
||||
value = source.asExpr().getLocation().getStartLine().toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
// --- stubs ---
|
||||
|
||||
struct URL {
|
||||
init?(string: String) {}
|
||||
}
|
||||
|
||||
class NSURL {
|
||||
init?(string: String) {}
|
||||
}
|
||||
|
||||
extension String {
|
||||
init(contentsOf: URL) {
|
||||
let data = ""
|
||||
self.init(data)
|
||||
}
|
||||
}
|
||||
|
||||
class Data {
|
||||
struct WritingOptions : OptionSet { let rawValue: Int }
|
||||
init<S>(_ elements: S) {}
|
||||
func write(to: URL, options: Data.WritingOptions = []) {}
|
||||
}
|
||||
|
||||
class NSData {
|
||||
struct WritingOptions : OptionSet { let rawValue: Int }
|
||||
func write(to: URL, atomically: Bool) -> Bool { return false }
|
||||
func write(to: URL, options: NSData.WritingOptions) {}
|
||||
func write(toFile: String, atomically: Bool) -> Bool { return false }
|
||||
func write(toFile: String, options: NSData.WritingOptions) {}
|
||||
}
|
||||
|
||||
struct URLResourceKey {}
|
||||
|
||||
struct FileAttributeKey : Hashable {}
|
||||
|
||||
struct ObjCBool {}
|
||||
|
||||
class FileManager {
|
||||
class DirectoryEnumerator {}
|
||||
struct DirectoryEnumerationOptions : OptionSet { let rawValue: Int }
|
||||
struct ItemReplacementOptions : OptionSet { let rawValue: Int }
|
||||
struct UnmountOptions : OptionSet { let rawValue: Int }
|
||||
struct SearchPathDomainMask {}
|
||||
enum SearchPathDirectory : UInt { case none }
|
||||
enum URLRelationship : Int { case none }
|
||||
|
||||
func contentsOfDirectory(at: URL, includingPropertiesForKeys: [URLResourceKey]?, options: FileManager.DirectoryEnumerationOptions) -> [URL] { return []}
|
||||
func contentsOfDirectory(atPath: String) -> [String] { return [] }
|
||||
func enumerator(at: URL, includingPropertiesForKeys: [URLResourceKey]?, options: FileManager.DirectoryEnumerationOptions, errorHandler: ((URL, Error) -> Bool)?) -> FileManager.DirectoryEnumerator? { return nil }
|
||||
func enumerator(atPath: String) -> FileManager.DirectoryEnumerator? { return nil }
|
||||
func subpathsOfDirectory(atPath: String) -> [String] { return [] }
|
||||
func subpaths(atPath: String) -> [String]? { return nil }
|
||||
func createDirectory(at: URL, withIntermediateDirectories: Bool, attributes: [FileAttributeKey : Any]?) {}
|
||||
func createDirectory(atPath: String, withIntermediateDirectories: Bool, attributes: [FileAttributeKey : Any]?) {}
|
||||
func createFile(atPath: String, contents: Data?, attributes: [FileAttributeKey : Any]?) -> Bool { return false }
|
||||
func removeItem(at: URL) {}
|
||||
func removeItem(atPath: String) {}
|
||||
func trashItem(at: URL, resultingItemURL: AutoreleasingUnsafeMutablePointer<NSURL?>?) {}
|
||||
func replaceItemAt(_: URL, withItemAt: URL, backupItemName: String?, options: FileManager.ItemReplacementOptions) -> URL? { return nil}
|
||||
func replaceItem(at: URL, withItemAt: URL, backupItemName: String?, options: FileManager.ItemReplacementOptions, resultingItemURL: AutoreleasingUnsafeMutablePointer<NSURL?>?) {}
|
||||
func copyItem(at: URL, to: URL) {}
|
||||
func copyItem(atPath: String, toPath: String) {}
|
||||
func moveItem(at: URL, to: URL) {}
|
||||
func moveItem(atPath: String, toPath: String) {}
|
||||
func createSymbolicLink(at: URL, withDestinationURL: URL) {}
|
||||
func createSymbolicLink(atPath: String, withDestinationPath: String) {}
|
||||
func linkItem(at: URL, to: URL) {}
|
||||
func linkItem(atPath: String, toPath: String) {}
|
||||
func destinationOfSymbolicLink(atPath: String) -> String { return "" }
|
||||
func fileExists(atPath: String) -> Bool { return false }
|
||||
func fileExists(atPath: String, isDirectory: UnsafeMutablePointer<ObjCBool>?) -> Bool { return false }
|
||||
func isReadableFile(atPath: String) -> Bool { return false }
|
||||
func isWritableFile(atPath: String) -> Bool { return false }
|
||||
func isExecutableFile(atPath: String) -> Bool { return false }
|
||||
func isDeletableFile(atPath: String) -> Bool { return false }
|
||||
func componentsToDisplay(forPath: String) -> [String]? { return nil }
|
||||
func displayName(atPath: String) -> String { return "" }
|
||||
func attributesOfItem(atPath: String) -> [FileAttributeKey : Any] { return [:] }
|
||||
func attributesOfFileSystem(forPath: String) -> [FileAttributeKey : Any] { return [:] }
|
||||
func setAttributes(_: [FileAttributeKey : Any], ofItemAtPath: String) {}
|
||||
func contents(atPath: String) -> Data? { return nil }
|
||||
func contentsEqual(atPath: String, andPath: String) -> Bool { return false }
|
||||
func getRelationship(_: UnsafeMutablePointer<FileManager.URLRelationship>, ofDirectoryAt: URL, toItemAt: URL) {}
|
||||
func getRelationship(_: UnsafeMutablePointer<FileManager.URLRelationship>, of: FileManager.SearchPathDirectory, in: FileManager.SearchPathDomainMask, toItemAt: URL) {}
|
||||
func changeCurrentDirectoryPath(_: String) -> Bool { return false }
|
||||
func unmountVolume(at: URL, options: FileManager.UnmountOptions, completionHandler: (Error?) -> Void) {}
|
||||
func NSHFSTypeOfFile(_: String!) -> String! { return "" }
|
||||
// Deprecated methods
|
||||
func changeFileAttributes(_: [AnyHashable : Any], atPath: String) -> Bool { return false }
|
||||
func fileAttributes(atPath: String, traverseLink: Bool) -> [AnyHashable : Any]? { return nil }
|
||||
func fileSystemAttributes(atPath: String) -> [AnyHashable : Any]? { return nil }
|
||||
func directoryContents(atPath: String) -> [Any]? { return nil }
|
||||
func createDirectory(atPath: String, attributes: [AnyHashable : Any]) -> Bool { return false }
|
||||
func createSymbolicLink(atPath: String, pathContent: String) -> Bool { return false }
|
||||
func pathContentOfSymbolicLink(atPath: String) -> String? { return nil }
|
||||
func replaceItemAtURL(originalItemURL: NSURL, withItemAtURL: NSURL, backupItemName: String?, options: FileManager.ItemReplacementOptions) -> NSURL? { return nil }
|
||||
}
|
||||
|
||||
// --- tests ---
|
||||
|
||||
func test() {
|
||||
let remoteString = String(contentsOf: URL(string: "http://example.com/")!)
|
||||
let remoteUrl = URL(string: remoteString)!
|
||||
let remoteNsUrl = NSURL(string: remoteString)!
|
||||
let safeUrl = URL(string: "")!
|
||||
let safeNsUrl = NSURL(string: "")!
|
||||
|
||||
Data("").write(to: remoteUrl, options: []) // $ hasPathInjection=102
|
||||
|
||||
let nsData = NSData()
|
||||
let _ = nsData.write(to: remoteUrl, atomically: false) // $ hasPathInjection=102
|
||||
nsData.write(to: remoteUrl, options: []) // $ hasPathInjection=102
|
||||
let _ = nsData.write(toFile: remoteString, atomically: false) // $ hasPathInjection=102
|
||||
nsData.write(toFile: remoteString, options: []) // $ hasPathInjection=102
|
||||
|
||||
let fm = FileManager()
|
||||
let _ = fm.contentsOfDirectory(at: remoteUrl, includingPropertiesForKeys: [], options: []) // $ hasPathInjection=102
|
||||
let _ = fm.contentsOfDirectory(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.enumerator(at: remoteUrl, includingPropertiesForKeys: [], options: [], errorHandler: nil) // $ hasPathInjection=102
|
||||
let _ = fm.enumerator(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.subpathsOfDirectory(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.subpaths(atPath: remoteString) // $ hasPathInjection=102
|
||||
fm.createDirectory(at: remoteUrl, withIntermediateDirectories: false, attributes: [:]) // $ hasPathInjection=102
|
||||
let _ = fm.createDirectory(atPath: remoteString, attributes: [:]) // $ hasPathInjection=102
|
||||
let _ = fm.createFile(atPath: remoteString, contents: nil, attributes: [:]) // $ hasPathInjection=102
|
||||
fm.removeItem(at: remoteUrl) // $ hasPathInjection=102
|
||||
fm.removeItem(atPath: remoteString) // $ hasPathInjection=102
|
||||
fm.trashItem(at: remoteUrl, resultingItemURL: AutoreleasingUnsafeMutablePointer<NSURL?>.init(bitPattern: 0)) // $ hasPathInjection=102
|
||||
let _ = fm.replaceItemAt(remoteUrl, withItemAt: safeUrl, backupItemName: nil, options: []) // $ hasPathInjection=102
|
||||
let _ = fm.replaceItemAt(safeUrl, withItemAt: remoteUrl, backupItemName: nil, options: []) // $ hasPathInjection=102
|
||||
fm.replaceItem(at: remoteUrl, withItemAt: safeUrl, backupItemName: nil, options: [], resultingItemURL: AutoreleasingUnsafeMutablePointer<NSURL?>.init(bitPattern: 0)) // $ hasPathInjection=102
|
||||
fm.replaceItem(at: safeUrl, withItemAt: remoteUrl, backupItemName: nil, options: [], resultingItemURL: AutoreleasingUnsafeMutablePointer<NSURL?>.init(bitPattern: 0)) // $ hasPathInjection=102
|
||||
fm.copyItem(at: remoteUrl, to: safeUrl) // $ hasPathInjection=102
|
||||
fm.copyItem(at: safeUrl, to: remoteUrl) // $ hasPathInjection=102
|
||||
fm.copyItem(atPath: remoteString, toPath: "") // $ hasPathInjection=102
|
||||
fm.copyItem(atPath: "", toPath: remoteString) // $ hasPathInjection=102
|
||||
fm.moveItem(at: remoteUrl, to: safeUrl) // $ hasPathInjection=102
|
||||
fm.moveItem(at: safeUrl, to: remoteUrl) // $ hasPathInjection=102
|
||||
fm.moveItem(atPath: remoteString, toPath: "") // $ hasPathInjection=102
|
||||
fm.moveItem(atPath: "", toPath: remoteString) // $ hasPathInjection=102
|
||||
fm.createSymbolicLink(at: remoteUrl, withDestinationURL: safeUrl) // $ hasPathInjection=102
|
||||
fm.createSymbolicLink(at: safeUrl, withDestinationURL: remoteUrl) // $ hasPathInjection=102
|
||||
fm.createSymbolicLink(atPath: remoteString, withDestinationPath: "") // $ hasPathInjection=102
|
||||
fm.createSymbolicLink(atPath: "", withDestinationPath: remoteString) // $ hasPathInjection=102
|
||||
fm.linkItem(at: remoteUrl, to: safeUrl) // $ hasPathInjection=102
|
||||
fm.linkItem(at: safeUrl, to: remoteUrl) // $ hasPathInjection=102
|
||||
fm.linkItem(atPath: remoteString, toPath: "") // $ hasPathInjection=102
|
||||
fm.linkItem(atPath: "", toPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.destinationOfSymbolicLink(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.fileExists(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.fileExists(atPath: remoteString, isDirectory: UnsafeMutablePointer<ObjCBool>.init(bitPattern: 0)) // $ hasPathInjection=102
|
||||
let _ = fm.isReadableFile(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.isWritableFile(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.isDeletableFile(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.componentsToDisplay(forPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.displayName(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.attributesOfItem(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.attributesOfFileSystem(forPath: remoteString) // $ hasPathInjection=102
|
||||
fm.setAttributes([:], ofItemAtPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.contents(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.contentsEqual(atPath: remoteString, andPath: "") // $ hasPathInjection=102
|
||||
let _ = fm.contentsEqual(atPath: "", andPath: remoteString) // $ hasPathInjection=102
|
||||
fm.getRelationship(UnsafeMutablePointer<FileManager.URLRelationship>.allocate(capacity: 0), ofDirectoryAt: remoteUrl, toItemAt: safeUrl) // $ hasPathInjection=102
|
||||
fm.getRelationship(UnsafeMutablePointer<FileManager.URLRelationship>.allocate(capacity: 0), ofDirectoryAt: safeUrl, toItemAt: remoteUrl) // $ hasPathInjection=102
|
||||
fm.getRelationship(UnsafeMutablePointer<FileManager.URLRelationship>.allocate(capacity: 0), of: FileManager.SearchPathDirectory.none, in: FileManager.SearchPathDomainMask(), toItemAt: remoteUrl) // $ hasPathInjection=102
|
||||
let _ = fm.changeCurrentDirectoryPath(remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.unmountVolume(at: remoteUrl, options: [], completionHandler: { _ in }) // $ hasPathInjection=102
|
||||
let _ = fm.NSHFSTypeOfFile(remoteString) // $ hasPathInjection=102
|
||||
// Deprecated methods
|
||||
let _ = fm.changeFileAttributes([:], atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.fileAttributes(atPath: remoteString, traverseLink: false) // $ hasPathInjection=102
|
||||
let _ = fm.fileSystemAttributes(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.directoryContents(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.createDirectory(atPath: remoteString, attributes: [:]) // $ hasPathInjection=102
|
||||
let _ = fm.createSymbolicLink(atPath: remoteString, pathContent: "") // $ hasPathInjection=102
|
||||
let _ = fm.createSymbolicLink(atPath: "", pathContent: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.pathContentOfSymbolicLink(atPath: remoteString) // $ hasPathInjection=102
|
||||
let _ = fm.replaceItemAtURL(originalItemURL: remoteNsUrl, withItemAtURL: safeNsUrl, backupItemName: nil, options: []) // $ hasPathInjection=102
|
||||
let _ = fm.replaceItemAtURL(originalItemURL: safeNsUrl, withItemAtURL: remoteNsUrl, backupItemName: nil, options: []) // $ hasPathInjection=102
|
||||
}
|
||||
Reference in New Issue
Block a user