Skip to content

Yet another SSRF query for Javascript#6714

Merged
codeql-ci merged 14 commits into
github:mainfrom
valeria-meli:javascript/ssrf
Nov 4, 2021
Merged

Yet another SSRF query for Javascript#6714
codeql-ci merged 14 commits into
github:mainfrom
valeria-meli:javascript/ssrf

Conversation

@valeria-meli

Copy link
Copy Markdown
Contributor

This query finds SSRFs (Server Side Request Forgeries). This is intended to be an alternative to the current Request Forgery query.

Why a new query?

We use codeql queries at Mercado Libre to block pull requests. We need them to be very precise.
We recommend input validation, not URL escaping, when fixing a SSRF. Some NGINx based routing tend to decode before routing, making our URL escape useless. But input validation always works.
So we adapted the original query to this blocking context and to accept different forms of input validation.

@intrigus-lgtm

Copy link
Copy Markdown
Contributor

Please auto-format your (QL) code.
You can do this by running codeql query format --in-place on the changed files or by using the CodeQL extension for VS Code (I think it's called Format Document in VS Code).

Comment on lines +33 to +36
exists(DataFlow::Node falseNode |
this.getAPredecessor+() = falseNode and
falseNode.asExpr().(BooleanLiteral).mayHaveBooleanValue(false)
) and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You should be able to simplify this to this.getAPredecessor+().asExpr().(BooleanLiteral).mayHaveBooleanValue(false), I think.

@asgerf asgerf self-assigned this Sep 20, 2021

@asgerf asgerf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍 Thanks for the submission. It's very valuable to get feedback on our queries like this, and in time we'll most likely incorporate the new sanitizers into the standard library.

For now, please see my inline comment regarding the heuristic that was supposedly removed. I'd like to get clarity on what happened here and that the query works as described.

Comment on lines +17 to +19
override predicate isSanitizerEdge(DataFlow::Node source, DataFlow::Node sink) {
sanitizingPrefixEdge(source, sink)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In the related issue, you wrote this:

The original query has a heuristic where this case ​​request(http://example.com/${base}${tainted}`);` is assumed OK to avoid false positives. We removed such heuristic. Our query flags this same case as SSRF.

However, the sanitizingPrefixEdge predicate actually includes the heuristic you meant to remove.

I've included a suggestion below which makes the query behave as you described (removing the heuristic):

Suggested change
override predicate isSanitizerEdge(DataFlow::Node source, DataFlow::Node sink) {
sanitizingPrefixEdge(source, sink)
}
private predicate hasSanitizingSubstring(DataFlow::Node nd) {
nd.getStringValue().regexpMatch(".*[?#].*")
or
hasSanitizingSubstring(StringConcatenation::getAnOperand(nd))
or
hasSanitizingSubstring(nd.getAPredecessor())
}
private predicate strictSanitizingPrefixEdge(DataFlow::Node source, DataFlow::Node sink) {
exists(DataFlow::Node operator, int n |
StringConcatenation::taintStep(source, sink, operator, n) and
hasSanitizingSubstring(StringConcatenation::getOperand(operator, [0 .. n - 1]))
)
}
override predicate isSanitizerEdge(DataFlow::Node source, DataFlow::Node sink) {
strictSanitizingPrefixEdge(source, sink)
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right. Sorry, I mixed it up with a similar query for Go (we did a more significant change there and I though we'd done that for Javascript too). Now I remember, we tried to remove that heuristic but couldn't make it work.
We're testing your suggestion now :)

@valeria-meli

Copy link
Copy Markdown
Contributor Author

Is it normal for "Checks (Github Actions)" to last so long? It's been stuck there for a month now, and I don't know how to relaunch it.

@valeria-meli valeria-meli requested a review from asgerf October 28, 2021 11:50
@asgerf

asgerf commented Oct 29, 2021

Copy link
Copy Markdown
Contributor

Hi again @valeria-meli,

Sorry for the long wait. It took longer than expected to assess the precision of the query.

I've started the tests (for external contributions the tests need to be triggered by staff) and will proceed with a merge decision shortly.

@asgerf

asgerf commented Nov 3, 2021

Copy link
Copy Markdown
Contributor

@valeria-meli could you run the auto-formatter one more time? That's the only failing check. Otherwise LGTM.

@asgerf asgerf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks! 👍

@codeql-ci codeql-ci merged commit 2895428 into github:main Nov 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants