Added support for new URIValidator in AntiSSRF library. Updated test caes to use postprocessing results. Currently results for partial ssrf still need work, it is flagging cases where the URL is fully controlled, but is sanitized. I'm not sure if this should be flagged yet.

This commit is contained in:
REDMOND\brodes
2026-02-02 16:09:53 -05:00
parent 27e19813be
commit 97ddab0724
10 changed files with 1061 additions and 413 deletions

View File

@@ -176,4 +176,49 @@ module ServerSideRequestForgery {
strNode = [call.getArg(0), call.getArgByName("string")]
)
}
/** A validation that a string does not contain certain characters, considered as a sanitizer. */
private class UriValidator extends FullUrlControlSanitizer {
UriValidator() { this = DataFlow::BarrierGuard<uri_validator/3>::getABarrierNode() }
}
import semmle.python.dataflow.new.internal.DataFlowPublic
private predicate uri_validator(DataFlow::GuardNode g, ControlFlowNode node, boolean branch) {
exists(DataFlow::CallCfgNode call, Node n, string funcs |
funcs in ["in_domain", "in_azure_keyvault_domain", "in_azure_storage_domain"]
|
call = API::moduleImport("AntiSSRF").getMember("URIValidator").getMember(funcs).getACall() and
call.getArg(0).asCfgNode() = node and
n.getALocalSource() = call and
(
// validator used in a comparison
exists(CompareNode cn, Cmpop op | cn = g |
(
// validator == true or validator == false or validator is True or validator is False
(op instanceof Eq or op instanceof Is) and
exists(ControlFlowNode l, boolean bool |
l.getNode().(BooleanLiteral).booleanValue() = bool and
bool in [true, false] and
branch = bool and
cn.operands(n.asCfgNode(), op, l)
)
or
// validator != false or validator != true or validator is not True or validator is not False
(op instanceof NotEq or op instanceof IsNot) and
exists(ControlFlowNode l, boolean bool |
l.getNode().(BooleanLiteral).booleanValue() = bool and
bool in [true, false] and
branch = bool.booleanNot() and
cn.operands(n.asCfgNode(), op, l)
)
)
)
or
// validator call directly (e.g., if URIValidator.in_domain(...) )
g = call.asCfgNode() and
branch = true
)
)
}
}