OpenUrlRedirect: Use a taint-tracking safe URLs

This commit is contained in:
Sauyon Lee
2020-03-23 02:38:10 -07:00
parent 932840b0a3
commit 83a417f52e
2 changed files with 15 additions and 33 deletions

View File

@@ -53,7 +53,7 @@ module OpenUrlRedirect {
/**
* A data-flow configuration for reasoning about safe URLs for unvalidated URL redirections.
*/
class SafeUrlConfiguration extends DataFlow::Configuration {
class SafeUrlConfiguration extends TaintTracking::Configuration {
SafeUrlConfiguration() { this = "SafeUrlFlow" }
override predicate isSource(DataFlow::Node source) {
@@ -64,35 +64,27 @@ module OpenUrlRedirect {
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
TaintTracking::functionModelStep(any(SafeUrlMethod m), pred, succ)
or
TaintTracking::functionModelStep(any(Path::PathManipulatingFunction pmf), pred, succ)
or
TaintTracking::functionModelStep(any(StringRightTrimmer rt), pred, succ)
or
TaintTracking::referenceStep(pred, succ)
or
TaintTracking::stringConcatStep(pred, succ)
or
TaintTracking::tupleStep(pred, succ)
or
exists(DataFlow::FieldReadNode frn | succ = frn |
frn.getBase() = pred and
(frn.getFieldName() = "Host" or frn.getFieldName() = "Path")
)
or
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
// propagate to a URL when its host is assigned to
exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") |
w.writesField(v.getAUse(), f, pred) and succ = v.getAUse()
)
}
override predicate isBarrierOut(DataFlow::Node node) {
override predicate isSanitizerOut(DataFlow::Node node) {
// block propagation of this safe value when its host is overwritten
exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") |
w.writesField(node.getASuccessor(), f, _)
)
or
exists(DataFlow::FieldReadNode frn, string name |
(name = "RawQuery" or name = "Fragment" or name = "User") and
frn.getField().hasQualifiedName("net/url", "URL")
|
node = frn.getBase()
)
or
TaintTracking::functionModelStep(any(UnsafeUrlMethod um), node, _)
}
}
}

View File

@@ -33,20 +33,10 @@ module OpenUrlRedirect {
abstract class BarrierGuard extends DataFlow::BarrierGuard { }
/**
* A method on a `net/url.URL` that is considered safe to redirect to.
* A method on a `net/url.URL` that is considered unsafe to redirect to.
*/
class SafeUrlMethod extends TaintTracking::FunctionModel, Method {
SafeUrlMethod() {
this instanceof StringMethod
or
exists(string m | this.hasQualifiedName("net/url", "URL", m) |
m = "Hostname" or m = "Port" or m = "RequestURI"
)
}
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
inp.isReceiver() and outp.isResult()
}
class UnsafeUrlMethod extends URL::UrlGetter {
UnsafeUrlMethod() { this.getName() = "Query" }
}
/**