Skip to content

Commit 1735860

Browse files
committed
change callback to rely on an behavior heuristic rather than a naming heuristic
1 parent 08d0cb7 commit 1735860

1 file changed

Lines changed: 13 additions & 3 deletions

File tree

javascript/ql/src/semmle/javascript/security/dataflow/ExceptionXss.qll

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
import javascript
8+
import Statements.UselessConditional
89

910
module ExceptionXss {
1011
import DomBasedXssCustomizations::DomBasedXss as DomBasedXssCustom
@@ -63,15 +64,24 @@ module ExceptionXss {
6364
NotYetThrown() { this = "NotYetThrown" }
6465
}
6566

66-
// Consider using "if (err) {.. [do something with err] .. }" as an extra condition if there are too many FP's.
67+
/**
68+
* A callback that is the last argument to some call, and the callback has the form:
69+
* function (err, value) {if (err) {...} .. }
70+
*/
6771
class Callback extends DataFlow::FunctionNode {
72+
DataFlow::ParameterNode errorParameter;
73+
6874
Callback() {
6975
exists(DataFlow::CallNode call | call.getLastArgument().getAFunctionValue() = this) and
7076
this.getNumParameter() = 2 and
71-
this.getParameter(0).getName().regexpMatch("err.*") // Using "e" was considered. But that matches too many jQuery methods where "element" is shortened as "e".
77+
errorParameter = this.getParameter(0) and
78+
exists(Expr errorCheck |
79+
isExplicitConditional(this.getFunction().getBodyStmt(0), errorCheck) and
80+
errorParameter.flowsTo(DataFlow::valueNode(errorCheck))
81+
)
7282
}
7383

74-
DataFlow::Node getErrorParam() { result = this.getParameter(0) }
84+
DataFlow::Node getErrorParam() { result = errorParameter }
7585
}
7686

7787
// `someFunction(.. <pred> .., (<result>, value) => {...}).

0 commit comments

Comments
 (0)