mirror of
https://github.com/github/codeql.git
synced 2026-01-30 14:52:57 +01:00
162 lines
4.7 KiB
Plaintext
162 lines
4.7 KiB
Plaintext
/**
|
|
* Provides default sources, sinks and sanitizers for reasoning about
|
|
* download of sensitive file through insecure connection, as well as
|
|
* extension points for adding your own.
|
|
*/
|
|
|
|
import javascript
|
|
|
|
/**
|
|
* Classes and predicates for reasoning about download of sensitive file through insecure connection vulnerabilities.
|
|
*/
|
|
module InsecureDownload {
|
|
/**
|
|
* A data flow source for download of sensitive file through insecure connection.
|
|
*/
|
|
abstract class Source extends DataFlow::Node {
|
|
/**
|
|
* Gets a flow-label for this source.
|
|
*/
|
|
abstract DataFlow::FlowLabel getALabel();
|
|
}
|
|
|
|
/**
|
|
* A data flow sink for download of sensitive file through insecure connection.
|
|
*/
|
|
abstract class Sink extends DataFlow::Node {
|
|
/**
|
|
* Gets the call that downloads the sensitive file.
|
|
*/
|
|
abstract DataFlow::Node getDownloadCall();
|
|
|
|
/**
|
|
* Gets a flow-label where this sink is vulnerable.
|
|
*/
|
|
abstract DataFlow::FlowLabel getALabel();
|
|
}
|
|
|
|
/**
|
|
* A sanitizer for download of sensitive file through insecure connection.
|
|
*/
|
|
abstract class Sanitizer extends DataFlow::Node { }
|
|
|
|
/**
|
|
* Flow-labels for reasoning about download of sensitive file through insecure connection.
|
|
*/
|
|
module Label {
|
|
/**
|
|
* A flow-label for file URLs that are both sensitive and downloaded over an insecure connection.
|
|
*/
|
|
class SensitiveInsecureUrl extends DataFlow::FlowLabel {
|
|
SensitiveInsecureUrl() { this = "sensitiveInsecure" }
|
|
}
|
|
|
|
/** DEPRECATED: Alias for SensitiveInsecureUrl */
|
|
deprecated class SensitiveInsecureURL = SensitiveInsecureUrl;
|
|
|
|
/**
|
|
* A flow-label for a URL that is downloaded over an insecure connection.
|
|
*/
|
|
class InsecureUrl extends DataFlow::FlowLabel {
|
|
InsecureUrl() { this = "insecure" }
|
|
}
|
|
|
|
/** DEPRECATED: Alias for InsecureUrl */
|
|
deprecated class InsecureURL = InsecureUrl;
|
|
}
|
|
|
|
/**
|
|
* A HTTP or FTP URL that refers to a file with a sensitive file extension,
|
|
* seen as a source for download of sensitive file through insecure connection.
|
|
*/
|
|
class SensitiveFileUrl extends Source {
|
|
string str;
|
|
|
|
SensitiveFileUrl() {
|
|
str = this.getStringValue() and
|
|
str.regexpMatch("http://.*|ftp://.*")
|
|
}
|
|
|
|
override DataFlow::FlowLabel getALabel() {
|
|
result instanceof Label::InsecureUrl
|
|
or
|
|
hasUnsafeExtension(str) and
|
|
result instanceof Label::SensitiveInsecureUrl
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Holds if `str` is a string that ends with an unsafe file extension.
|
|
*/
|
|
bindingset[str]
|
|
predicate hasUnsafeExtension(string str) {
|
|
exists(string suffix | suffix = unsafeExtension() |
|
|
str.suffix(str.length() - suffix.length() - 1).toLowerCase() = "." + suffix
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Gets a file-extension that can potentially be dangerous.
|
|
*
|
|
* Archives are included, because they often contain source-code.
|
|
*/
|
|
string unsafeExtension() {
|
|
result =
|
|
[
|
|
"exe", "dmg", "pkg", "tar.gz", "zip", "sh", "bat", "cmd", "app", "apk", "msi", "dmg",
|
|
"tar.gz", "zip", "js", "py", "jar", "war"
|
|
]
|
|
}
|
|
|
|
/**
|
|
* A url downloaded by a client-request, seen as a sink for download of
|
|
* sensitive file through insecure connection.
|
|
*/
|
|
class ClientRequestUrl extends Sink {
|
|
ClientRequest request;
|
|
|
|
ClientRequestUrl() { this = request.getUrl() }
|
|
|
|
override DataFlow::Node getDownloadCall() { result = request }
|
|
|
|
override DataFlow::FlowLabel getALabel() {
|
|
result instanceof Label::SensitiveInsecureUrl
|
|
or
|
|
hasUnsafeExtension(request.getASavePath().getStringValue()) and
|
|
result instanceof Label::InsecureUrl
|
|
}
|
|
}
|
|
|
|
/** DEPRECATED: Alias for ClientRequestUrl */
|
|
deprecated class ClientRequestURL = ClientRequestUrl;
|
|
|
|
/**
|
|
* Gets a node for the response from `request`, type-tracked using `t`.
|
|
*/
|
|
DataFlow::SourceNode clientRequestResponse(DataFlow::TypeTracker t, ClientRequest request) {
|
|
t.start() and
|
|
result = request.getAResponseDataNode()
|
|
or
|
|
exists(DataFlow::TypeTracker t2 | result = clientRequestResponse(t2, request).track(t2, t))
|
|
}
|
|
|
|
/**
|
|
* A url that is downloaded through an insecure connection, where the result ends up being saved to a sensitive location.
|
|
*/
|
|
class FileWriteSink extends Sink {
|
|
ClientRequest request;
|
|
|
|
FileWriteSink() {
|
|
exists(FileSystemWriteAccess write |
|
|
this = request.getUrl() and
|
|
clientRequestResponse(DataFlow::TypeTracker::end(), request).flowsTo(write.getADataNode()) and
|
|
hasUnsafeExtension(write.getAPathArgument().getStringValue())
|
|
)
|
|
}
|
|
|
|
override DataFlow::FlowLabel getALabel() { result instanceof Label::InsecureUrl }
|
|
|
|
override DataFlow::Node getDownloadCall() { result = request }
|
|
}
|
|
}
|