@@ -17,24 +17,23 @@ module ExceptionXss {
1717 DataFlow:: ExceptionalInvocationReturnNode getCallerExceptionalReturn ( Function func ) {
1818 exists ( DataFlow:: InvokeNode call |
1919 not call .isImprecise ( ) and
20- func = call .( DataFlow :: InvokeNode ) . getACallee ( ) and
20+ func = call .getACallee ( ) and
2121 result = call .getExceptionalReturn ( )
2222 )
2323 }
2424
2525 DataFlow:: Node getExceptionalSuccessor ( DataFlow:: Node pred ) {
2626 if exists ( getEnclosingTryStmt ( pred .asExpr ( ) .getEnclosingStmt ( ) ) )
2727 then
28- result . ( DataFlow:: ParameterNode ) . getParameter ( ) = getEnclosingTryStmt ( pred
28+ result = DataFlow:: parameterNode ( getEnclosingTryStmt ( pred
2929 .asExpr ( )
30- .getEnclosingStmt ( ) ) .getACatchClause ( ) .getAParameter ( )
30+ .getEnclosingStmt ( ) ) .getACatchClause ( ) .getAParameter ( ) )
3131 else result = getCallerExceptionalReturn ( pred .getContainer ( ) )
3232 }
3333
3434 predicate canThrowSensitiveInformation ( DataFlow:: Node node ) {
35- // i have to do this "dual" check because there are two data-flow nodes associated with reflective calls.
36- node = any ( DataFlow:: InvokeNode call ) .getAnArgument ( ) and
37- not node = any ( DataFlow:: InvokeNode call | exists ( call .getACallee ( ) ) ) .getAnArgument ( )
35+ // in the case of reflective calls the below ensures that both InvokeNodes have no known callee.
36+ forex ( DataFlow:: InvokeNode call | node = call .getAnArgument ( ) | not exists ( call .getACallee ( ) ) )
3837 or
3938 node .asExpr ( ) .getEnclosingStmt ( ) instanceof ThrowStmt
4039 }
@@ -46,6 +45,12 @@ module ExceptionXss {
4645 )
4746 }
4847
48+ /**
49+ * A FlowLabel representing tainted data that has not been thrown in an exception.
50+ * In the js/xss-through-exception query data-flow can only reach a sink after
51+ * the data has been thrown as an exception, and data that has not been thrown
52+ * as an exception therefore has this flow label, and only this flow label, associated with it.
53+ */
4954 class NotYetThrown extends DataFlow:: FlowLabel {
5055 NotYetThrown ( ) { this = "NotYetThrown" }
5156 }
@@ -67,13 +72,12 @@ module ExceptionXss {
6772 }
6873
6974 override predicate isSanitizer ( DataFlow:: Node node ) {
70- super .isSanitizer ( node ) or
7175 node instanceof XSS:: Shared:: Sanitizer
7276 }
7377
7478 override predicate isAdditionalFlowStep ( DataFlow:: Node pred , DataFlow:: Node succ , DataFlow:: FlowLabel inlbl , DataFlow:: FlowLabel outlbl ) {
7579 inlbl instanceof NotYetThrown and ( outlbl .isTaint ( ) or outlbl instanceof NotYetThrown ) and
76- succ = getExceptionalSuccssor ( pred ) and
80+ succ = getExceptionalSuccessor ( pred ) and
7781 ( canThrowSensitiveInformation ( pred ) or pred = any ( DataFlow:: InvokeNode c ) .getExceptionalReturn ( ) )
7882 or
7983 // All the usual taint-flow steps apply on data-flow before it has been thrown in an exception.
0 commit comments