Skip to content

JavaScript: Add new query UnvalidatedDynamicMethodCall. #555

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 28, 2018

Conversation

xiemaisi
Copy link

This complements the Unsafe dynamic method access query to flag cases of method name injection that can result in a crash (as opposed to code injection). Such cases are less problematic (hence the new query has severity "warning"), but still worth flagging.

I've further restricted the "Remote property injection" query to no longer flag any dynamic method calls, so there should be no overlap in results.

Running on our default benchmarks yields good results (internal link); query runtimes look reasonable for a security query.

As discussed with @pavgust, I am making this a hotfix since it is customer-motivated and fixes what to an end-user would look like a regression from 1.18, where remote property injection results were shown by default.

@xiemaisi xiemaisi added the JS label Nov 28, 2018
@xiemaisi xiemaisi added this to the 1.19 milestone Nov 28, 2018
@xiemaisi xiemaisi requested a review from a team as a code owner November 28, 2018 08:39
@xiemaisi
Copy link
Author

Ping @mc-semmle for doc review. I'd like to get this merged today if at all possible so it is ready for LGTM testing day. If you don't have time today I can put up a separate doc review PR later.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I think this can be merged today.

The try-block comment is not critical, but a small discussion would be good.

The qhelp examples are missing the usual GOOD/BAD annotations, and ditto for OK/NOT OK for their twins in the query-tests directory.

}

app.get('/perform/:action/:payload', function(req, res) {
let action = actions[req.params.action];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing // BAD: ... annotation


app.get('/perform/:action/:payload', function(req, res) {
if (actions.has(req.params.action)) {
let action = actions.get(req.params.action);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing // GOOD: ... annotation

if (actions.hasOwnProperty(req.params.action)) {
let action = actions[req.params.action];
if (typeof action === 'function') {
res.end(action(req.params.payload));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing annotation

CalleeAsSink() {
this = invk.getCallee().flow() and
// don't flag invocations inside a try-catch
not invk.getASuccessor() instanceof CatchClause
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is meant to whitelist calls that guarded with a dedicated try-catch right?

The whitelist seems brittle to me, and it does not capture the "dedicatedness" very well: the check only holds if the call is the last expression in the try-block, and it holds regardless of the size of the try-block.
Could we perhaps check if the enclosing try-statement is "small" instead ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the check only holds if the call is the last expression in the try-block

Oh? It's meant to hold for anything inside the try block. Why does it only hold for the last expression?

This is meant to whitelist calls that guarded with a dedicated try-catch right?

I hadn't thought about it in terms of dedicatedness. It's more that the query help emphasises the possibility of the call throwing an unhandled runtime exception, and this whitelists the case where there is, in fact, a handler. It's not a complete whitelist, of course (not inter-procedural, and it gets confused by intervening finally blocks), but I think in practice it's probably good enough.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh? It's meant to hold for anything inside the try block. Why does it only hold for the last expression?

Ehh, nevermind. The successor that you use is the exceptional successor. I was thinking that the ordinary successor to the last expression of a try block would be the catch-clause, but that would be silly.

I am happy with this as it is then. We can experiment with dedicatedness later.

@xiemaisi
Copy link
Author

GOOD/BAD annotations added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants