-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Java: Promote XPath Injection query from experimental #5774
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
Conversation
928e180
to
8f91fd3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From dom4j there might be other interesting classes as well:
- Constructor
DefaultXPath(String)
AbstractNode
methodscreateXPathFilter
andcreatePattern
, not sure if they are problematic as well.DocumentFactory
methodsDocumentHelper
methodsXPathPattern
constructorProxyDocumentFactory
methods
Though maybe this is out of scope for this pull request. These are only suggestions; I am not a member of this project.
Also the .expected
file is currently empty, but you are probably still working on it.
The inline expectation test system requires the |
These are great suggestions @Marcono1234, thank you! I refactored the |
@github/codeql-java I consider this ready for a final review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for considering my review comments!
There are only a few more minor things.
java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many thanks for including a change note for this pull request ✨
I was unable to comment on the Qhelp file or associated .java
file as they are simply renamed. For the Qhelp file suggestions, I ended up raising: #5837.
My only other real feedback is that it would be good to include an example of a good dom4J expression and not only a bad one. Otherwise the user-facing content looks good to me.
@@ -0,0 +1,2 @@ | |||
lgtm,codescanning | |||
* The query "XPath injection" (`java/xml/xpath-injection`) has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @SpaceWhite](https://github.com/github/codeql/pull/2800) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One question here - has the query been added to the query suite files for LGTM and Code scanning? I don't see any changes to .qls
files in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't there a PR check for that at some point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've lost track of how query suite files are managed these days.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That rings a bell but I've also forgotten. Maybe it hasn't been reimplemented after we moved to Actions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that new queries are added to code scanning suites automatically (via https://github.com/github/codeql/blob/main/misc/suite-helpers/code-scanning-selectors.yml and similar "helpers")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Shati 😄 That's great to know.
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
fa75a48
to
926fedb
Compare
Force-pushed to rebase the changes suggested by in #5837. |
@felicitymay this was included in 7646855, thanks for the suggestion! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many thanks for adding the extra example @atorralba ✨
Two final comments on the user-facing text, but otherwise this is a 👍🏻 from the docs side. I'll leave it to the CodeQL Java team to decide when the whole PR is ready to merge.
Co-authored-by: Felicity Chapman <felicitymay@github.com>
@@ -11,10 +11,10 @@ | |||
*/ | |||
|
|||
import java | |||
import DataFlow::PathGraph |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really minor and not something I think we actually ever talked about, but we tend to put the import DataFlow::PathGraph
last in the sequence of imports. As I said, it's really not very important (putting import java
first is important, though, but that's another matter entirely), but the reason I mention this is to highlight that the PathGraph
import is a different kind of import than the others: the other imports reference file-modules, whereas PathGraph
is a module in scope and this import statement merely opens it to the top-level scope. (There might even have been discussions about whether this ought to have been a different keyword than import
, such as perhaps open
.)
Also, for completeness of information, importing an in-scope module mostly affects naming, i.e. we can import DataFlow
if we want to write Node
rather than DataFlow::Node
, but in this case there's a separate reason: The PathGraph
module contains two predicates annotated with query
and putting such predicates in the top-level scope makes them part of the query on the same level as the select
statement (and those query predicate
s contain the graph that's required for a path-problem
query).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's really interesting, thank you for taking the time to explain it with so much detail!
I moved the import down as you suggested (see b69be30) - now that I know the reason, it makes a lot of sense.
|
||
import java | ||
import semmle.code.java.dataflow.DataFlow | ||
import semmle.code.java.dataflow.ExternalFlow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ExternalFlow
import needs to be bidirectional. I.e. add a private import semmle.code.java.security.XPath
inside the private module Frameworks
in ExternalFlow.qll
. This is important to ensure that ExternalFlow.qll
always sees the same set of csv rows to enable efficient caching. Otherwise, a lot of things will be recomputed based on which csv rows are transitively imported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in b69be30. Another "gotcha" to keep in mind, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really want to make this a compilation error, but we'll need a little bit of additional language support for that.
@@ -1 +1 @@ | |||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/jdom-1.1.3:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/simple-xml-2.7.1:${testdir}/../../../stubs/jaxb-api-2.3.1 | |||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/jdom-1.1.3:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/simple-xml-2.7.1:${testdir}/../../../stubs/jaxb-api-2.3.1:${testdir}/../../../stubs/jaxen-1.2.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like the only change in the CWE-611 directory. Was this committed by mistake?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed this because tests for CWE-611 started failing when I introduced a Jaxen import in a stub used both in CWE-611 and CWE-643 (here 7646855#diff-da791bf0774d1d6fe164bf5fa3cae3cec838ee5f8a7218737364701624c5716bR95)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some inline comments, otherwise LGTM.
|
||
new DefaultXPath("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection | ||
new XPathPattern("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection | ||
new XPathPattern(new PatternStub(user)); // Jaxen is not modeled yet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this ought to be reported, the inline expectations test has an annotation for that:
new XPathPattern(new PatternStub(user)); // Jaxen is not modeled yet | |
new XPathPattern(new PatternStub(user)); // Jaxen is not modeled yet $ MISSING: hasXPathInjection |
That way, the qltest error, if this does get modelled, will list this as "Fixed" rather than "Spurious new result".
(I think you can leave the "Jaxen is not modeled" comment before the $
, but I'm actually not sure about that part - best look into the internals of inline expectations to check or simply test it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps just move the regular comment to its own line in order to not mix it with the expectation syntax.
new XPathPattern(new PatternStub(user)); // Jaxen is not modeled yet | |
// Jaxen is not modeled yet | |
new XPathPattern(new PatternStub(user)); // $ MISSING: hasXPathInjection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently, it needs to start with $ MISSING:
to work properly:
* `$ MISSING: tag=expected-value` // Missing result |
codeql/java/ql/test/TestUtilities/InlineExpectationsTest.qll
Lines 162 to 165 in ef0ea24
* RegEx pattern to match a comment containing one or more expected results. The comment must have | |
* `$` as its first non-whitespace character. Any subsequent character | |
* is treated as part of the expected results, except that the comment may contain a `//` sequence | |
* to treat the remainder of the line as a regular (non-interpreted) comment. |
I tested it that way and indeed the test result shows Fixed missing result
instead of Unexpected result
(assuming the line raises an alert).
Added in 2a50195. Another cool thing to know, thanks!
PR to promote the XPath injection query created in #2800
Changes
experimental
XPathl.qll
file was created. The existing XPath injection sinks wee moved here, and were refactored to use the new CSV sink model.dom4j
and the standard library.InlineExpectationsTest
and new stubs fordom4j
andjaxen
Evaluation
After the changes, the query produces alerts from 31 projects. After review, all seem TPs, but: