Intent to Implement and Ship: Changes to CSP's model for dedicated web workers.

94 views
Skip to first unread message

Mike West

unread,
Nov 30, 2016, 8:03:36 AM11/30/16
to blink-dev, Brian Smith, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org

# Contact Emails

# Spec

# Summary
Based on discussion at https://github.com/w3c/webappsec-csp/issues/146, CSP3 makes a few changes to the model for workers:

1. It introduces a `worker-src` directive, which governs loading {,Shared,Service}Workers.

2. Workers (and `worker-src`) no longer default to `child-src`, but instead `script-src`.

3. Dedicated workers inherit policy from their creator, and no longer get their own policy distinct from that context.

# Motivation
Currently, we ship `child-src`, which restricts both frames and workers. This seemed like a great idea, but turns out to be both not granular enough for developers, and simply the wrong model. CSP3 deprecates `child-src` by undeprecating `frame-src` (which we've already done) and adding `worker-src`.

# Interop Risk
Folks on the last webappsec call agreed that this was the right way forward. There's still some questions about how and when shared and service workers should inherit policy, so I'm holding off on making changes there, but we had general agreement on dedicated workers. I don't think we'll change our minds again (again).

CCing folks from other browsers who were on the call, along with the change's instigators, just in case I'm misrepresenting the level of agreement.

# Compat Risk
1. `worker-src` is new: CSP implementations ignore directives they don't understand; adding new directives will not break existing sites.

2. The risk here is low: ~0.0012% of page views try to load a worker which `child-src` allows, but `script-src` doesn't. I think we'd be alright just eating that risk, but since we've already jerked developers around on this once (to introduce `child-src`), I'd like to temporarily treat both `script-src` and `child-src` as allowing workers, and introduce a deprecation message that we can disable in a release or three. We will not break existing sites. If the new `worker-src` is present, we'll assume that developers know what they're doing, and treat `child-src` as deprecated for workers.

3. The risk here turns out to be zero, because our implementation is broken. In investigating things, I discovered that we're currently applying _both_ the policy delivered with a dedicated worker _and_ the policy delivered with the page that loaded the worker. *cough* I'll fix that (also, anecdotally, this behavior is what a plurality of developers in a totally scientific poll already think is happening).

I've upstreamed a number of worker tests to https://github.com/w3c/web-platform-tests/tree/master/content-security-policy/worker-src. Once the updates in https://codereview.chromium.org/2533313002 land, I'll upstream them as well.

# Technical Constraints
None.

# All Blink Platforms?
Yes.

# OWP Bug

# Chromestatus

# Requesting approval to ship?
Yes.

-mike

Philip Jägenstedt

unread,
Nov 30, 2016, 10:18:40 AM11/30/16
to Mike West, blink-dev, Brian Smith, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
On the compat risk, will you still change script-src and/or child-src work to mitigate the risk measured by the use counter, or does the third point mean that this isn't needed after all?

Mike West

unread,
Nov 30, 2016, 10:30:56 AM11/30/16
to Philip Jägenstedt, blink-dev, Brian Smith, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
On Wed, Nov 30, 2016 at 4:18 PM, Philip Jägenstedt <foo...@chromium.org> wrote:
On the compat risk, will you still change script-src and/or child-src work to mitigate the risk measured by the use counter, or does the third point mean that this isn't needed after all?

They're two different things: one controls whether a worker loads at all, the other controls what the worker itself can do.

For the first: Given a document with a policy of `child-src https://example.com; script-src https://cdn.example.com`, we allow workers to be loaded from `https://example.com` today because `child-src` allows that origin (e.g. `new Worker('https://example.com/worker.js');`). The metric at https://www.chromestatus.com/metrics/feature/timeline/popularity/258 is measuring cases like this one in which `script-src` would disallow a load that `child-src` allows. It doesn't happen all that often; if we hadn't already pulled the rug out from under developers once, I'd say we could simply make the change. Since we did, however, I'd prefer to be nicer.

For the second, we're talking about the policy that applies to the things that the WorkerGlobalScope does. Due to reasons, dedicated worker's fetches end up going through the FrameFetchContext of the document that created them, which means its CSP applies. This means that the dedicated worker can only fetch the union of its policy and the document's policy today, which is stricter than intended.

-mike

Philip Jägenstedt

unread,
Nov 30, 2016, 10:53:11 AM11/30/16
to Mike West, blink-dev, Brian Smith, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
Let's see if I get it. A worker load currently uses `child-src`. That will change to `worker-src`, which will default to `script-src`. In order to note break stuff, `worker-src` will initially default to the union of `child-src` and `script-src`, and then later `child-src` bit of that will be deprecated and removed?

As long as the intermediate state isn't deemed terrible so that being trapped there is acceptable, that sounds OK.

LGTM1 (even if I didn't get the details quite right)

Jochen Eisinger

unread,
Nov 30, 2016, 10:57:32 AM11/30/16
to Philip Jägenstedt, Mike West, blink-dev, Brian Smith, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
lgtm2

Brian Smith

unread,
Nov 30, 2016, 11:01:56 AM11/30/16
to Philip Jägenstedt, Mike West, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
Philip Jägenstedt <foo...@chromium.org> wrote:
Let's see if I get it. A worker load currently uses `child-src`. That will change to `worker-src`, which will default to `script-src`. In order to note break stuff, `worker-src` will initially default to the union of `child-src` and `script-src`, and then later `child-src` bit of that will be deprecated and removed?

Let me try:

CSP2 introduced child-src, which applies a policy to both iframes and {dedicated, shared, service} workers. Then it was recognized that iframes and workers may need separate policies, so worker-src was introduced, defaulting to child-src. Then it was realized that child-src was a bad idea so it is deprecated. So, we should all pretend that child-src never happened.

Also, it was realized that there's no significant security reason to treat dedicated workers differently than the script that spawns them, but we still think shared workers and service workers need special handling. Thus, worker-src will no longer affect dedicated workers; it will only affect shared workers and service workers. Now script-src controls dedicated workers.

I am hopeful that later there will be an agreement to replace worker-src for shared workers and service workers too, but if/when that happens, that will be dealt with in a separate implement-and-ship thread.

Cheers,
Brian
--

Mike West

unread,
Nov 30, 2016, 11:03:20 AM11/30/16
to Philip Jägenstedt, blink-dev, Brian Smith, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
On Wed, Nov 30, 2016 at 4:52 PM, Philip Jägenstedt <foo...@chromium.org> wrote:
Let's see if I get it. A worker load currently uses `child-src`. That will change to `worker-src`, which will default to `script-src`.

Yes!
 
In order to note break stuff, `worker-src` will initially default to the union of `child-src` and `script-src`, and then later `child-src` bit of that will be deprecated and removed?

1. I plan to add a console warning that `child-src` is deprecated along with the checks we'll talk about in a moment. I don't plan to stay in this intermediate state long, just long enough to not make developers sad. (again, we're talking about 0.0012% of page views).

2. If `worker-src` is present, then we assume that developers know what's up (since it's new, and no one is using it today). `worker-src` -> `script-src` -> `default-src`, done. If `worker-src` is not present, then I plan to introduce a weird intermediate state where either `child-src` or `script-src` can allow a worker to load. The code is around line 779 of https://codereview.chromium.org/2533313002/diff/40001/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp. It's probably easier just to look at that conditional than to sketch out various policies.

Mike West

unread,
Nov 30, 2016, 11:11:45 AM11/30/16
to Brian Smith, Philip Jägenstedt, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
On Wed, Nov 30, 2016 at 5:01 PM, Brian Smith <br...@briansmith.org> wrote:
Let me try:

CSP2 introduced child-src, which applies a policy to both iframes and {dedicated, shared, service} workers. Then it was recognized that iframes and workers may need separate policies, so worker-src was introduced, defaulting to child-src. Then it was realized that child-src was a bad idea so it is deprecated. So, we should all pretend that child-src never happened.

Yup.
 
Also, it was realized that there's no significant security reason to treat dedicated workers differently than the script that spawns them, but we still think shared workers and service workers need special handling. Thus, worker-src will no longer affect dedicated workers; it will only affect shared workers and service workers. Now script-src controls dedicated workers.

This isn't what I thought we were converging on. I agree that there's no significant security reason to treat dedicated workers differently than the script that spawns them, but it's in keeping with CSP's general granularity to allow folks to control worker loads separately from scripts. Workers have to be same-origin, for instance, so a developer who wishes to place as little trust in their server as possible might allow `worker-src https://example.com/workers/this-specific-worker.js` on the specific page that needs it, while pushing general script out to `script-src https://super-fast-and-speedy.cdn.net/all-my-script/`.

The plan documented in the spec at the moment is to tie dedicated, shared, and service workers to `worker-src`, which defaults to `script-src`, which defaults to `default-src`.
 
I am hopeful that later there will be an agreement to replace worker-src for shared workers and service workers too, but if/when that happens, that will be dealt with in a separate implement-and-ship thread.

That seems strange to me. Glad I CC'd you. :)

-mike

Anne van Kesteren

unread,
Nov 30, 2016, 11:51:23 AM11/30/16
to Mike West, Brian Smith, Philip Jägenstedt, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, John Wilander, dba...@webkit.org
On Wed, Nov 30, 2016 at 5:11 PM, Mike West <mk...@chromium.org> wrote:
> Workers have to be same-origin, for instance,

This is not true for module workers. (They have to be CORS-same-origin though.)


--
https://annevankesteren.nl/

Brian Smith

unread,
Nov 30, 2016, 12:38:11 PM11/30/16
to Mike West, Philip Jägenstedt, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
Mike West <mk...@chromium.org> wrote:

Brian Smith <br...@briansmith.org> wrote:
Also, it was realized that there's no significant security reason to treat dedicated workers differently than the script that spawns them, but we still think shared workers and service workers need special handling. Thus, worker-src will no longer affect dedicated workers; it will only affect shared workers and service workers. Now script-src controls dedicated workers.

This isn't what I thought we were converging on.

I see. I misread your "{,Shared,Service} Workers" syntax as "{Shared,Service} Workers."

Rather than continue this thread of discussion in this email thread, let's discuss it in the webappsec-csp issue, since it isn't Chrome-specific. I'll follow up there in a day or so.

Brian Smith

unread,
Nov 30, 2016, 3:42:25 PM11/30/16
to Mike West, Philip Jägenstedt, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
To minimize the latency in making progress that I've caused, I've posted some preliminary thoughts here:

I'm probably wrong but I'm clueless as to why.

Cheers,
Brian
--

Lucas Garron

unread,
Nov 30, 2016, 4:10:59 PM11/30/16
to Brian Smith, Mike West, Philip Jägenstedt, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
At the risk of asking something naive, how does this interact with web workers?

»Lucas

»Lucas Garron

Brian Smith

unread,
Nov 30, 2016, 5:16:49 PM11/30/16
to Lucas Garron, Mike West, Philip Jägenstedt, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
On Wed, Nov 30, 2016 at 11:10 AM, Lucas Garron <lga...@google.com> wrote:
At the risk of asking something naive, how does this interact with web workers?

I use "dedicated worker," "web worker," and "worker" (with no "shared" or "service") interchangeably. 

Cheers,
Brian
--

Lucas Garron

unread,
Nov 30, 2016, 7:16:09 PM11/30/16
to Brian Smith, Mike West, Philip Jägenstedt, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
Thanks!

Now I understand the `{,` in `{,Shared,Service}Workers` :-P

Is it intentional that all are lumped into one for this?
I can imagine only wanting service workers from the local domain, but allowing pages with web workers from elsewhere.
(But perhaps that's a job for feature policy?)

»Lucas

Mike West

unread,
Dec 1, 2016, 3:09:45 AM12/1/16
to Lucas Garron, Brian Smith, Philip Jägenstedt, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, dba...@webkit.org
Looks like I overestimated the agreement on `worker-src`, sorry for jumping the gun. Let's put this intent on hold for a bit longer. I'll ping the thread again when we're actually on the same page. :)


-mike

Mike West

unread,
Mar 17, 2017, 4:42:58 AM3/17/17
to Lucas Garron, Brian Smith, Philip Jägenstedt, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, Daniel Bates
Hey folks!

I've closed out the GitHub discussion, and I think there's agreement (or at least, lack of disagreement) on the model proposed in the spec. To re-summarize in the hopes of gaining y'all's approval, CSP3 makes a few changes to the model for workers:

1. It introduces a `worker-src` directive, which governs loading Workers, Shared Workers, and Service Workers.

2. Workers (and `worker-src`) are no longer governed by `child-src` (along with frames), but instead `script-src` (along with scripts).

3. Dedicated workers inherit policy from their creator, and no longer have their own policy distinct from that context.

I still intend to ship #1 and #3 nowish, and phase in #2 with an intermediate stage which allows both `script-src` and `child-src` to ensure that pages which rely on the existing behavior (0.002% of page views at the moment) have a clear migration path. Logic for that is contained in https://codereview.chromium.org/2533313002 which I need to rebase and revive.

What say ye, API OWNERS? (Should I file a new I2I&S for the scripts?)

-mike

Dimitri Glazkov

unread,
Mar 17, 2017, 10:30:26 AM3/17/17
to Mike West, Lucas Garron, Brian Smith, Philip Jägenstedt, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, Daniel Bates
LGTM1, and yes, please file a new intent+chromestatus entry for things you'd like to do separately.

Chris Harrelson

unread,
Mar 17, 2017, 11:07:41 AM3/17/17
to Dimitri Glazkov, Mike West, Lucas Garron, Brian Smith, Philip Jägenstedt, blink-dev, Brad Hill, Dan Veditz, Ted Dinklocker, Anne van Kesteren, John Wilander, Daniel Bates
Hi Mike, are you saying that the spec discussion ended up concurring with your original intent? (Just making sure I understand the latest state.)

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscribe@chromium.org.

Mike West

unread,
Mar 17, 2017, 11:39:50 AM3/17/17
to Chris Harrelson, Dimitri Glazkov, Anne van Kesteren, Brad Hill, Brian Smith, Dan Veditz, Daniel Bates, John Wilander, Lucas Garron, Philip Jägenstedt, Ted Dinklocker, blink-dev
That's correct. We clarified some things around the edges, but the broad strokes are the same.

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
--
-mike

Chris Harrelson

unread,
Mar 17, 2017, 11:56:04 AM3/17/17
to Mike West, Dimitri Glazkov, Anne van Kesteren, Brad Hill, Brian Smith, Dan Veditz, Daniel Bates, John Wilander, Lucas Garron, Philip Jägenstedt, Ted Dinklocker, blink-dev
Ok, then DImitri is actualy LGTM3, as Jochen and Philip approved the original plan upstream.

LGTM4 FWIW :)

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscribe@chromium.org.
--
-mike

Reply all
Reply to author
Forward
0 new messages