-
Notifications
You must be signed in to change notification settings - Fork 1.9k
JS: Handle jQuery $() sink in a separate data-flow configuration #4506
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
esbena
left a comment
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.
Very nice.
I am glad that this multi-Configuration pattern still scales.
| * An argument to the jQuery `$` function, which is interpreted as either a selector | ||
| * or as an HTML string depending on its first character. | ||
| */ | ||
| class JQuerySelectorSink extends Sink { |
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.
Two things here:
- naming: this is a sink because it could interpret the argument as HTML rather than a benign selector.
- reuse: could we unify this with
AmbiguousHtmlOrSelectorArgument?codeql/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
Lines 34 to 37 in 3587235
/** * An argument that may act as a HTML fragment rather than a CSS selector, as a sink for remote unsafe jQuery plugins. */ class AmbiguousHtmlOrSelectorArgument extends DataFlow::Node {
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.
Renamed to JQueryHtmlOrSelector... and shared some logic with AmbiguousHtmlOrSelectorArgument.
| /** | ||
| * DEPRECATED. Use `HtmlInjectionConfiguration` or `JQuerySelectorInjectionConfiguration`. | ||
| */ | ||
| deprecated class Configuration = HtmlInjectionConfiguration; |
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.
Have you considered mentioning this deprecation explicitly in the change notes? I would expect this particular Configuration instance to be the one that is most commonly imported in external queries.
| from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink | ||
| where | ||
| ( | ||
| cfg instanceof HtmlInjectionConfiguration or |
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.
In these BDD-times, could you perhaps also check if the compiler stays happy if you include a few more (dummy) configurations in this disjunct?
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.
Adding two more configs seems to trigger the memory limit 😬
fadc465 to
c91cdb5
Compare
esbena
left a comment
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. I think we should merge regardless of the newly discovered compilation limit, that is not the fault of this PR after all.
I have one more optional comment on the change note.
| ## Changes to libraries | ||
| * The predicate `TypeAnnotation.hasQualifiedName` now works in more cases when the imported library was not present during extraction. | ||
| * The class `DomBasedXss::Configuration` has been deprecated, as it has been split into `DomBasedXss::HtmlInjectionConfiguration` and `DomBasedXss::JQueryHtmlOrSelectorInjectionConfiguration`. Unless specifically working with jQuery sinks, uses of that | ||
| class should be replaced with `HtmlInjectionConfiguration`. |
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.
Could we also point the reader towards our Xss.ql for how to use both configurations at once? That is after all how you would work around this deprecation with a customized XSS query.
The jQuery
$()function interprets its input as HTML only if it starts with<.To avoid FPs from an expression like
$(location.hash)which always starts with#, the XSS query treated the.hashproperty specially, but in a way that could cause FNs for other kinds of sinks, likeinnerHTMLassignments, where it doesn't matter what the string starts with.This PR moves handling of the jQuery sink into a separate data-flow configuration. Most importantly, this allows us to tweak the jQuery sink handling without interfering with other sinks. We now handle the jQuery sink by requiring that any value derived from
.hashmust have undergone some transformation before reaching$().Evaluation (internal link) was quiet.