Skip to content

JS: Add unsafe-html-construction query#5769

Merged
codeql-ci merged 16 commits into
github:mainfrom
erik-krogh:libXss
May 10, 2021
Merged

JS: Add unsafe-html-construction query#5769
codeql-ci merged 16 commits into
github:mainfrom
erik-krogh:libXss

Conversation

@erik-krogh
Copy link
Copy Markdown
Contributor

@erik-krogh erik-krogh commented Apr 26, 2021

Gets a TP for CVE-2020-7750

The idea (and structure) of the query is the same as js/shell-command-constructed-from-input:

  • Taint-track library input to some input transformation.
  • This input transformation can be:
    • Construct some HTML string (found some TPs from that).
    • Parse as XML (CVE-2020-7750)
    • Parse as markdown in an unsafe way. (I haven't found any real results for this, but I want to keep it anyway).
  • Type-track the transformed input to an XSS sink.

The TP rate is good.
I had some FPs from a run-on-all, but almost all where removed with the remove flowpaths that has a return without a matching call commit and the not this = JQuery::dollarSource() check.

I'll look into promoting classFieldStep to a SharedTaintStep after this PR has been merged.

Performance evaluation:
part 1 looks good
part 2 (and a redo) looks good. It seems performance on the workers got more unstable 🤷
The new results look like TPs (or at least bad style).

@erik-krogh erik-krogh force-pushed the libXss branch 2 times, most recently from b4fbde1 to f662ddd Compare May 6, 2021 08:59
@erik-krogh erik-krogh marked this pull request as ready for review May 6, 2021 09:09
@erik-krogh erik-krogh requested a review from a team as a code owner May 6, 2021 09:09
Copy link
Copy Markdown
Contributor

@esbena esbena left a comment

Choose a reason for hiding this comment

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

Generally LGTM. Here's half a review. I would very much like to give it a second read-through, but in the interest of progress, I am submitting some comments now.

Comment thread javascript/ql/src/Security/CWE-079/UnsafeHtmlConstruction.ql Outdated
class ExternalInputSource extends Source, DataFlow::ParameterNode {
ExternalInputSource() {
this = Exports::getALibraryInputParameter() and
not this = JQuery::dollarSource()
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.

Please add a comment about why we need to exclude dollarSource

Comment thread javascript/ql/src/Security/CWE-079/UnsafeHtmlConstruction.qhelp Outdated

<p>
Alternatively, use a HTML sanitizer to escape/remove unsafe content.
</p>
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.

Unlike the command-injection variant of this query, I think it is (more) reasonable to do some ad hoc HTML concatenation in a library.
Experience from the unsafe jquery plugins tells that some library maintainers do not feel responsible for these kinds of XSS vectors, and some of them just update their README to tell clients that they are responsible for sanitizing HTML before using the library.

Can we angle the qhelp such that additional documentation is a known fix type (a fix that won't remove the "FP").

Perhaps some qhelp fragments should be shared between this query and js/unsafe-jquery-plugin.

<overview>
<p>
Library plugins, such as those for the jQuery library, are often
configurable through options provided by the clients of the
plugin.
Clients, however, do not know the implementation details
of the plugin, so it is important to document the capabilities of each
option. The documentation for the plugin options that the client is
responsible for sanitizing is of particular importance.
Otherwise, the plugin may write user input (for example, a URL query
parameter) to a web page without properly sanitizing it first,
which allows for a cross-site scripting vulnerability in the client
application through dynamic HTML construction.
</p>
</overview>
<recommendation>
<p>
Document all options that can lead to cross-site scripting
attacks, and guard against unsafe inputs where dynamic HTML
construction is not intended.
</p>
</recommendation>

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.

I like the idea, but I don't think we can share fragments as the terms used are different
(plugin vs library and options vs input).

I'm rewriting the qhelp to focus more on unsafe endpoints being properly documented.

Comment thread javascript/ql/src/Security/CWE-079/UnsafeHtmlConstruction.qhelp Outdated
erik-krogh and others added 3 commits May 6, 2021 21:55
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
Copy link
Copy Markdown
Contributor

@esbena esbena left a comment

Choose a reason for hiding this comment

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

Thanks.
Here are some additional comments.

Comment on lines +7 to +12
Dynamically constructing HTML with inputs from library functions that are
available to external clients may inadvertently leave a client open to XSS attacks.

Clients using the exported function may use inputs containing unsafe HTML,
and if these inputs end up in the DOM, the client may be vulnerable to
cross-site scripting attacks.
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.

XSS attacks

cross-site scripting attacks

Pick one.

Dynamically constructing HTML with inputs from library functions that are
available to external clients may inadvertently leave a client open to XSS attacks.

Clients using the exported function may use inputs containing unsafe HTML,
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.

Suggested change
Clients using the exported function may use inputs containing unsafe HTML,
Clients using the exported function may use inputs containing unsafe HTML fragments,

<recommendation>

<p>
If possible, use safe APIs when inserting HTML into the DOM.
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.

Suggested change
If possible, use safe APIs when inserting HTML into the DOM.
If possible, use safe APIs when modifying the DOM.

When the suggestion below is to use innerText, it is confusion to see "when inserting HTML".

}
module Markdown {
/**
* A taint-step that parses a markdown document, but preserves taint.import
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.

Suggested change
* A taint-step that parses a markdown document, but preserves taint.import
* A taint-step that parses a markdown document, but preserves taint.

?

call = markdownIt().getMember(["use", "set", "configure", "enable", "disable"]).getACall() and
result = call.getReturn() and
not call.getParameter(0).getAValueReachingRhs() =
DataFlow::moduleImport("markdown-it-sanitizer")
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.

Should this negation be in the preservesHtml predicate?

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.

I think that would require adding a boolean isSanitized parameter to the markdownIt() predicate.

The MarkdownStep::step predicate is documented as being a taint-step.
And if markdown-it-sanitizer is used, then there is no taint-step.
So I think it's fine.

sink = mid.getASuccessor() and
mid.getPathSummary().hasReturn() = false
)
UnsafeHtmlConstruction::requireMatchedReturn(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.

Can we move this step to a shared library.
I the step already existed in UnsafeShellCommandConstruction.qll , and was simply referenced from UnsafeHtmlConstruction.qll I would be more inclined to shrug this off, but now we are introducing a dependency on a new query instead.

@codeql-ci codeql-ci merged commit a3d17a1 into github:main May 10, 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.

3 participants