Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

fix($sanitize): do not trigger CSP alert/report in Firefox and Chrome #17013

Closed

Conversation

peruukki
Copy link
Contributor

@peruukki peruukki commented Apr 14, 2020

Default to using DOMParser if it is available and fall back to createHTMLDocument if needed. This is the approach suggested in the related pull request #17013 and used by DOMPurify too. It also safely avoids using an inline style tag that causes CSP violation errors if inline CSS is prohibited.

The related unit tests in sanitizeSpec.js, "should not allow JavaScript execution when creating inert document" and "should not allow JavaScript hidden in badly formed HTML to get through sanitization (Firefox bug)", are left untouched to assert that the behavior hasn't changed in those scenarios.

Fixes #16463.

AngularJS is in LTS mode

We are no longer accepting changes that are not critical bug fixes into this project.
See https://blog.angular.io/stable-angularjs-and-long-term-support-7e077635ee9c for more detail.

Does this PR fix a regression since 1.7.0, a security flaw, or a problem caused by a new browser version?
This fixes a regression that came with commit 7673ca7 that based on its tags appeared in version 1.7.0. It's not clear to me if it's considered a security flaw but it does hinder setting a strict Content-Security-Policy that doesn't allow inline styles.

What is the current behavior? (You can also link to an open issue here)
If ngSanitize is added as a module dependency and the Content-Security-Policy does not allow inline styles, a CSP violation will be reported by at least Firefox and Chrome.

Issue #16463.

What is the new behavior (if this is a feature change)?
No CSP violation is reported.

Does this PR introduce a breaking change?
No.

Please check if the PR fulfills these requirements

  • The commit message follows our guidelines
  • Fix/Feature: Docs have been added/updated
  • Fix/Feature: Tests have been added; existing tests pass

Other information:
Like mentioned above, there are existing unit tests related to this change that test that badly-formatted HTML is sanitized properly, and the behavior shouldn't have changed on that regard. I don't think there is a convenient way to test CSP violations, so I didn't write any new tests.

I submitted the same fix to Angular in angular/angular#36578, it is still being processed.

@koto
Copy link
Contributor

koto commented Apr 16, 2020

The change from <style> to <span> has security consequences. The original payload (similar to what DOMPurify used) was tailored to detect the bug in Firefox HTML parser used in innerHTML. The actual check done after payload processing is kind of wrong (the fact whether img is under svg is irrelevant, what is important is whether any element exists with an onerror attribute), but incidentally - the modified payload will hinder the check even if it was right. style is the symptom that triggers the FF bug, as the parsing context is different - changing to span breaks that - AngularJS would not be testing for the right thing.

A proper patch would be to default to DOMParser without testing. DOMPurify stopped testing for the FF (and Safari) bugs long time ago, and is defaulting to DOMParser for other reasons now.

@peruukki
Copy link
Contributor Author

Thanks for the info @koto, this fix did seem suspiciously simple for an issue that had been waiting for 2 years to be resolved. 😄 So if I understood correctly, we should try to use DOMParser (getInertBodyElement_DOMParser) and fall back to createHTMLDocument (getInertBodyElement_InertDocument) if DOMParser is not available, and drop getInertBodyElement_XHR altogether. I'll see if I can achieve that.

peruukki added a commit to peruukki/angular.js that referenced this pull request Apr 16, 2020
…ection

We now default to DOMParser if it is available and fall back to
createHTMLDocument if needed. This is the approach suggested in the
related pull request angular#17013 and used by DOMPurify too. It also safely
avoids using an inline style tag that causes CSP violation errors if inline
CSS is prohibited.
@peruukki
Copy link
Contributor Author

I made the changes, now DOMParser is used in modern browsers and the fallback was used at least on my Internet Explorer 11 virtual machine. I don't think there is still any practical way to write a test for this change as the changes are internal.

…ection

Default to using DOMParser if it is available and fall back to
createHTMLDocument if needed. This is the approach suggested in the
related pull request angular#17013 and used by DOMPurify too. It also safely
avoids using an inline style tag that causes CSP violation errors if inline
CSS is prohibited.

The related unit tests in `sanitizeSpec.js`, "should not allow JavaScript
execution when creating inert document" and "should not allow JavaScript
hidden in badly formed HTML to get through sanitization (Firefox bug)", are
left untouched to assert that the behavior hasn't changed in those scenarios.

Fixes angular#16463.
@peruukki peruukki force-pushed the sanitize-inert-remove-inline-style branch from 51166c9 to 7f57c68 Compare April 16, 2020 16:57
@peruukki peruukki changed the title fix($sanitize): remove inline style from sanitization Firefox bug detection fix($sanitize): remove browser bug detections from inert strategy selection Apr 16, 2020
peruukki added a commit to peruukki/angular that referenced this pull request Apr 23, 2020
Default to using DOMParser if it is available and fall back to
createDocument if needed. This is the approach used by DOMPurify and
suggested in the related Angular.js pull request
angular/angular.js#17013. It also safely
avoids using an inline style tag that causes CSP violation errors if inline
CSS is prohibited.

The related unit tests in `html_sanitizer_spec.ts`, "should not allow
JavaScript execution when creating inert document" and "should not allow
JavaScript hidden in badly formed HTML to get through sanitization (Firefox
bug)", are left untouched to assert that the behavior hasn't changed in
those scenarios.

Fixes angular#25214.
@peruukki
Copy link
Contributor Author

One detail I noticed: the Angular repository already has an isDOMParserAvailable function that uses a simpler method for the detection, !!(window as any).DOMParser, whereas I actually test the DOMParser functionality using !!getInertBodyElement_DOMParser(''). I chose the latter because the parseFromString method with HTML support seems to be less supported than just the DOMParser property but I don't know if it makes any real-life difference and which one would be preferable.

@koto
Copy link
Contributor

koto commented Apr 23, 2020

It sounds like a good choice. Thanks!

peruukki added a commit to peruukki/angular that referenced this pull request Apr 25, 2020
angular#36687)

Default to using DOMParser if it is available and fall back to
createDocument if needed. This is the approach used by DOMPurify and
suggested in the related Angular.js pull request
angular/angular.js#17013. It also safely
avoids using an inline style tag that causes CSP violation errors if inline
CSS is prohibited.

The related unit tests in `html_sanitizer_spec.ts`, "should not allow
JavaScript execution when creating inert document" and "should not allow
JavaScript hidden in badly formed HTML to get through sanitization (Firefox
bug)", are left untouched to assert that the behavior hasn't changed in
those scenarios.

Fixes angular#25214.
@Splaktar
Copy link
Member

The test failures just appear to be caused by connection flakiness with Saucelabs. Can someone on the @angular/angular-1-contributors team restart Travis?

Copy link
Member

@Splaktar Splaktar 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'm thankful for the great input from @koto and to @peruukki for posting this PR and getting the discussion started.

@petebacondarwin petebacondarwin added this to the 1.8.x milestone May 20, 2020
peruukki added a commit to peruukki/angular that referenced this pull request May 21, 2020
angular#36687)

Default to using DOMParser if it is available and fall back to
createDocument if needed. This is the approach used by DOMPurify and
suggested in the related Angular.js pull request
angular/angular.js#17013. It also safely
avoids using an inline style tag that causes CSP violation errors if inline
CSS is prohibited.

The related unit tests in `html_sanitizer_spec.ts`, "should not allow
JavaScript execution when creating inert document" and "should not allow
JavaScript hidden in badly formed HTML to get through sanitization (Firefox
bug)", are left untouched to assert that the behavior hasn't changed in
those scenarios.

Fixes angular#25214.
@petebacondarwin
Copy link
Contributor

@koto could you give this your approval if you feel it is a safe change to make?

@koto
Copy link
Contributor

koto commented Jun 2, 2020

This looks good, thanks Harri!

peruukki added a commit to peruukki/angular that referenced this pull request Jun 4, 2020
angular#36687)

Default to using DOMParser if it is available and fall back to
createDocument if needed. This is the approach used by DOMPurify and
suggested in the related Angular.js pull request
angular/angular.js#17013. It also safely
avoids using an inline style tag that causes CSP violation errors if inline
CSS is prohibited.

The related unit tests in `html_sanitizer_spec.ts`, "should not allow
JavaScript execution when creating inert document" and "should not allow
JavaScript hidden in badly formed HTML to get through sanitization (Firefox
bug)", are left untouched to assert that the behavior hasn't changed in
those scenarios.

Fixes angular#25214.
@petebacondarwin
Copy link
Contributor

Thanks @peruukki - I'm changed the commit message to refer to the thing it is fixing rather than the detail of the implementation. Closed via 2fab3d4

@peruukki peruukki changed the title fix($sanitize): remove browser bug detections from inert strategy selection fix($sanitize): do not trigger CSP alert/report in Firefox and Chrome Jun 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ngSanitize triggers CSP alert/report in Firefox
5 participants