mirror of
https://github.com/github/codeql.git
synced 2026-02-08 11:11:06 +01:00
82 lines
2.5 KiB
Plaintext
82 lines
2.5 KiB
Plaintext
/**
|
|
* @name Insecure URL whitelist
|
|
* @description URL whitelists that are too permissive can cause security vulnerabilities.
|
|
* @kind problem
|
|
* @problem.severity warning
|
|
* @precision very-high
|
|
* @id js/angular/insecure-url-whitelist
|
|
* @tags security
|
|
* frameworks/angularjs
|
|
* external/cwe/cwe-183
|
|
* external/cwe/cwe-625
|
|
*/
|
|
|
|
import javascript
|
|
|
|
/**
|
|
* Holds if `setupCall` is a call to `$sceDelegateProvider.resourceUrlWhitelist` with
|
|
* argument `list`.
|
|
*/
|
|
predicate isResourceUrlWhitelist(DataFlow::MethodCallNode setupCall, DataFlow::ArrayLiteralNode list) {
|
|
exists (AngularJS::ServiceReference service |
|
|
service.getName() = "$sceDelegateProvider" and
|
|
setupCall.asExpr() = service.getAMethodCall("resourceUrlWhitelist") and
|
|
list.flowsTo(setupCall.getArgument(0))
|
|
)
|
|
}
|
|
|
|
/**
|
|
* An entry in a resource URL whitelist.
|
|
*/
|
|
class ResourceUrlWhitelistEntry extends Expr {
|
|
DataFlow::MethodCallNode setupCall;
|
|
string pattern;
|
|
|
|
ResourceUrlWhitelistEntry() {
|
|
exists (DataFlow::ArrayLiteralNode whitelist |
|
|
isResourceUrlWhitelist(setupCall, whitelist) and
|
|
this = whitelist.getAnElement().asExpr() and
|
|
this.mayHaveStringValue(pattern)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Gets the method call that sets up this whitelist.
|
|
*/
|
|
DataFlow::MethodCallNode getSetupCall() {
|
|
result = setupCall
|
|
}
|
|
|
|
/**
|
|
* Holds if this expression is insecure to use in an URL pattern whitelist due
|
|
* to the reason given by `explanation`.
|
|
*/
|
|
predicate isInsecure(string explanation) {
|
|
exists (string componentName, string component |
|
|
exists (int componentNumber |
|
|
componentName = "scheme" and componentNumber = 1
|
|
or
|
|
componentName = "domain" and componentNumber = 2
|
|
or
|
|
componentName = "TLD" and componentNumber = 4
|
|
|
|
|
component = pattern.regexpCapture("(.*?)://(.*?(\\.(.*?))?)(:\\d+)?(/.*)?", componentNumber)
|
|
)
|
|
and
|
|
explanation = "the " + componentName + " '" + component + "' is insecurely specified"
|
|
|
|
|
componentName = "scheme" and component.matches("%*%")
|
|
or
|
|
componentName = "domain" and component.matches("%**%")
|
|
or
|
|
componentName = "TLD" and component = "*"
|
|
)
|
|
}
|
|
}
|
|
|
|
from ResourceUrlWhitelistEntry entry, DataFlow::MethodCallNode setupCall, string explanation
|
|
where entry.isInsecure(explanation) and
|
|
setupCall = entry.getSetupCall()
|
|
select setupCall, "'$@' is not a secure whitelist entry, because " + explanation + ".",
|
|
entry, entry.toString()
|