Java: Fix performance of the query User-controlled bypass of sensitive method#6600
Conversation
d8edb62 to
0640b41
Compare
| not cb.controls(any(SensitiveExecutionMethod sem).getAReference().getBasicBlock(), | ||
| cond.booleanNot()) and | ||
| not cb.controls(any(ThrowStmt t).getBasicBlock(), _) and | ||
| not cb.controls(any(ReturnStmt r).getBasicBlock(), _) and |
There was a problem hiding this comment.
You've made 3 changes here. The first line seems sensible and is covered by a test case, but the other two are less clear. Could you elaborate on those choices and add some tests for them? In particular, why is the branch not important for throw and return statements?
There was a problem hiding this comment.
During the evaluation I saw a lot of FP that matched the following pattern:
if (!taintedCondition) {
throw new Exception();
// or
return errorCode;
}
doLogin();
doOtherSensitiveStuff();Before the change, the query was assuming that the if block was a way of bypassing the authentication, but actually it interrupts the execution flow with an error and nothing sensitive is executed.
Of course this approach has tradeoffs (since the heuristic nature of the query makes it hard to be 100% precise), in which a block containing a return or throw statement does something sensitive first, but it seemed that the FP reduction was worth a limited FN increase. Happy to discuss it further, though.
In any case, I wanted to add tests for this but I forgot, I'll do it now.
There was a problem hiding this comment.
So for this example it seems like you want
not cb.controls(any(ThrowStmt t).getBasicBlock(), cond.booleanNot())
in order to say that the throw statement is in the other branch, right?
I'm a little less convinced by the return statement, but if it really does help to filter FPs then I guess it should also specify the branch to be cond.booleanNot(), right?
There was a problem hiding this comment.
Good catch! By adding this, a MISSING test case gets fixed, so thank you :) See 21079a1.
Regarding the return statement, I can run one evaluation with the query as-is and one without the exception for return statements to see what's its real impact on FP, if you think it makes sense.
There was a problem hiding this comment.
Yeah, if it should be there it should probably be not cb.controls(any(ReturnStmt r).getBasicBlock(), cond.booleanNot()), but an evaluation to check its impact is probably good.
There was a problem hiding this comment.
I ran this, and when the return exception is not applied, the results go up from 155 to 365 projects. After a cursory review, most of those 210 extra projects' results seem to be FPs.
There was a problem hiding this comment.
Thanks for checking. Makes sense to keep it then.
Note that a FN test case was added
Exceptions for throw and return statements were missing the appropriate condition
The query User-controlled bypass of sensitive method (
java/user-controlled-bypass) has shown bad performance on certain projects.This PR aims to solve that by, mainly, changing the sources from
UserInputtoRemoteFlowSource, i.e. stop considering local inputs. This should have a positive impact in FP ratio as well.General improvements are added in this PR too, namely creating the
ConditionalBypassQuery.qlllibrary and refactoring the query tests to useInlineExpectationsTest.Also, some improvements were made to the heuristics used to find sensitive (i.e. authentication/authorization) actions (added some exceptions for things like
author) and to theconditionsControlMethodpredicate, to not consider conditions that exit with athroworreturnwithout actually executing the important parts after the "bypassed" authentication.Evaluation
After the changes, a subset of 1077 projects with results was reduced to 155. All the removed results seemed to be FP.
A differences job run to see the actual reduction on performance is needed.