Skip to content
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

Move origin into policy container. (#8302) #8447

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

wanderview
Copy link
Member

@wanderview wanderview commented Oct 27, 2022

  • At least two implementers are interested (and none opposed):
  • Tests are written and can be reviewed and commented upon at:
  • Implementation bugs are filed:
    • Chromium: …
    • Gecko: …
    • WebKit: …
    • Deno (only for timers, structured clone, base64 utils, channel messaging, module resolution, web workers, and web storage): …
    • Node.js (only for timers, structured clone, base64 utils, channel messaging, and module resolution): …
  • MDN issue is filed: …

(See WHATWG Working Mode: Changes for more details.)


/browsers.html ( diff )
/browsing-the-web.html ( diff )
/document-lifecycle.html ( diff )
/document-sequences.html ( diff )
/dom.html ( diff )
/nav-history-apis.html ( diff )
/webappapis.html ( diff )
/workers.html ( diff )
/worklets.html ( diff )

@wanderview wanderview force-pushed the dev-origin-policy-container branch 9 times, most recently from 0368747 to f5611f9 Compare November 8, 2022 22:31
@wanderview wanderview marked this pull request as ready for review November 8, 2022 22:32
@wanderview
Copy link
Member Author

@annevk can you please take a look at this? It attempts to move origin to the policy container. It removes origin from environment settings object and document. (I have not make a DOM spec PR yet.)

@domfarolino
Copy link
Member

Out of curiosity what is the motivation for this change? Is there some background here?

@wanderview
Copy link
Member Author

wanderview commented Nov 9, 2022

Out of curiosity what is the motivation for this change? Is there some background here?

See #8302. Basically it was decided this was a prerequisite for spec'ing storage partitioning.

@wanderview
Copy link
Member Author

@annevk Gentle review ping. I'm busing looking at some other things at the moment, but I'd like to avoid having this sit too long to avoid bit rot. Thanks.

@annevk
Copy link
Member

annevk commented Dec 9, 2022

Some thoughts:

  • This doesn't introduce the authority struct we discussed. It probably should to avoid having to change everything again in a follow-up PR? Or did you have another idea for that?
  • To keep the number of changes small and make review easier, we keep document's origin as a concept, but redefine it as returning document's policy container's authority's origin. Eventually we'll have to do replacements, but I suspect we rather want to have "same authority" (or some such) operations that take a document/settings object on one side (or both sides).
  • Depending on how many references there are to settings object's origin we do the same there, for now.

@wanderview
Copy link
Member Author

This doesn't introduce the authority struct we discussed. It probably should to avoid having to change everything again in a follow-up PR? Or did you have another idea for that?

You mean create an authority struct with a single item in it for now?

I can do that. My thought was that I could do that in a separate PR to try to keep them smaller and also that it would be weird to have a struct with only one value right now.

@annevk
Copy link
Member

annevk commented Dec 12, 2022

That's also fine I suppose. Especially if we keep document's origin and settings object's origin working for now as there should be a lot fewer changes in general then.

@wanderview
Copy link
Member Author

To keep the number of changes small and make review easier, we keep document's origin as a concept, but redefine it as returning document's policy container's authority's origin.

@annevk just to clarify, this means I should remove all changed reference document-concept-origin here and create a new PR against DOM spec to reference the unlanded origin policy container origin?

I feel like there is going to be some state where the specs are inconsistent until we can land both.

@wanderview
Copy link
Member Author

Work-in-progress push so I can use github diff viewing tools.

@wanderview
Copy link
Member Author

I need to write the associated DOM spec pull request now.

wanderview added a commit to wanderview/dom that referenced this pull request Jan 10, 2023
This change depends on the changes in whatwg/html#8447
which adds origin to policy container.
@wanderview
Copy link
Member Author

Ok, I have tried creating the corresponding DOM pull request over in whatwg/dom#1142.

@annevk can you please take another look?

source Outdated
<code>Document</code> object is created, and can change during the lifetime of the
<code>Document</code> only upon setting <code
data-x-for="Document">origin</dfn> is defined in <cite>DOM</cite>. It currently aliases to
value of its <span data-x=document-concept-policy-container>policy container</span>'s
Copy link
Member

Choose a reason for hiding this comment

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

the value

source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
@annevk
Copy link
Member

annevk commented Jan 11, 2023

Could you address the CI issues? It would be nice to be able to view the rendered HTML.

wanderview added a commit to wanderview/dom that referenced this pull request Jan 11, 2023
This change depends on the changes in whatwg/html#8447
which adds origin to policy container.
Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

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

Looking at the rendered HTML I'm noticing a couple of oddities. I haven't been able to go through all the diffs, but I figured I'd comment here what I found thus far.

@@ -89811,6 +89813,9 @@ location.href = '#foo';</code></pre>
<var>finalSandboxFlags</var>, <var>documentState</var>'s <span
data-x="document-state-initiator-origin">initiator origin</span>, and null.</p></li>

<li><p>Set <var>policyContainer</var>'s <span data-x="policy-container-origin">origin</span>
to <var>responseOrigin</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

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

Looking at this in context this is weird. This really ought to be part of "determine navigation params policy container".

Copy link
Member Author

Choose a reason for hiding this comment

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

I moved setting the origin in the "determine navigation params policy container", but left computing the origin in the caller because its also used in other places by the caller.

Also, I took a bit of a guess that the origin should be unchanged for a history entry policy container.

Let me know what you think.

Copy link
Member

Choose a reason for hiding this comment

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

I spent about 1.5 hours going down this rabbit hole.

I think it's definitely possible to make this easier to read. Now that effectively "determine navigation params policy container" + "determine the origin" are doing one big combined thing, it's pretty bad. They have the combined inputs responseURL, sandboxFlags, sourceOrigin, containerOrigin, historyPolicyContainer, initiatorPolicyContainer, parentPolicyContainer, responsePolicyContainer. Maybe sourceOrigin / containerOrigin /initiatorPolicyContainer / parentPolicyContainer have some redundancy; maybe not.

However, any work here ends up being pretty orthogonal to Ben's PR. I wrote it all out and it consists of a few steps:

  1. Split "determine navigation params policy container" into three algorithms with three inputs, one for each of its call sites. These are much easier to read because, e.g., the srcdoc version is very short, and then there's no srcdoc stuff in the fetching version.

  2. Try to consolidate "determine the origin" and "determine navigation params policy container" as much as possible. Some of this involves ensuring sourceOrigin /containerOrigin / initiatorPolicyContainer / parentPolicyContainer line up; I think they mostly do. I'm unsure yet whether the end state here has them as separate algorithms, or one combined algorithm, or whether we ensure that "determine the origin" is always called by the now-split-up "determine navigation params policy container" instead of having the call sites call both of them in sequence. TBD.

  3. Potentially simplify the inputs to, or split up, "determine the origin" itself.

  4. Potentially consolidate "create a policy container from a fetch response" into the above stuff, since after (1) it should be pretty closely tied with the first variant of "determine navigation params policy container".

I'm going to file a new issue with this. At the start of my journey I thought this should block the refactoring here, but after spending 1.5 hours on this I've convinced myself it's very separable work, it's not obvious how to complete all the steps, and each step needs close review.

source Outdated
<dd><var>policyContainer</var></dd>
<dd>a <span data-x="clone a policy container">clone</span> of <var>policyContainer</var>
with its <span data-x="policy-container-origin">origin</span> set to
<var>initiatorOrigin</var></dd>
Copy link
Member

Choose a reason for hiding this comment

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

This is an existing problem of sorts with this algorithm, but _ initiatorOrigin_ is coming out of nowhere. Perhaps introduced by "the rewrite" @domenic?

It's not clear to me that keeping the policy container but changing the origin is sound.

Copy link
Member

Choose a reason for hiding this comment

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

This is an existing problem of sorts with this algorithm, but _ initiatorOrigin_ is coming out of nowhere. Perhaps introduced by "the rewrite" @domenic?

Oops, yes, will fix. It should be newDocumentOrigin. #8711 to fix this.

It's not clear to me that keeping the policy container but changing the origin is sound.

So, the intent of policy container seems to be to keep together things that are inherited together. I'm not sure if origin is the same as other policy container members in this way. I.e., I'm not sure that whenever you inherit CSP/COEP/referrer policy, you should also inherit origin. @antosart as one of the original policy container people may have thoughts?

Note that https://github.com/antosart/policy-container-explained#the-security-policies never envisioned putting origin in the policy container.

That said, if it works everywhere else and this javascript: URL case is the only suspicious one, then we should be fine for the reasons explained in my next section.


Regarding javascript: URLs in particular, note that initiatorOrigin / newDocumentOrigin will always be same origin-domain with policyContainer's origin, because of the check in https://html.spec.whatwg.org/#navigate-to-a-javascript:-url step 3. So I don't think there's a huge concern here, if the issue is just around same-origin vs. same origin-domain. Maybe browsers don't even implement the spec here in various ways, e.g., maybe they do a same-origin check in that guard step, or maybe they don't overwrite the new document's origin in the cases where they differ. More testing would be ideal.

In any case, I strongly believe we shouldn't block the larger work here on javascript: URL edge cases around same-origin vs. same-origin domain. So if this is the only place where putting origin into policy container is problematic and requires a clone-but-patch-one-member pattern, then let's just slap an XXX box here, file an issue to write some tests and determine what's the most elegant behavior we can all converge on, and move on.

Copy link
Member

Choose a reason for hiding this comment

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

So, the intent of policy container seems to be to keep together things that are inherited together. I'm not sure if origin is the same as other policy container members in this way. I.e., I'm not sure that whenever you inherit CSP/COEP/referrer policy, you should also inherit origin. @antosart as one of the original policy container people may have thoughts?

Note that https://github.com/antosart/policy-container-explained#the-security-policies never envisioned putting origin in the policy container.

FWIW, we did not write it down, but there was the hope that at some point also the origin would end up in the policy container. I am very happy to see that this is finally getting done!

For the rest, I agree with @domenic. This particular point should matter only if the origin's domain was changed. I am not sure how policies like COOP would (and/or should) behave in such case. I don't know all the background here, but this seems an edge case to me (which we might hope to get rid of at some point?) - so I would not block on it.

Copy link
Member

Choose a reason for hiding this comment

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

@antosart your review of this PR would be much appreciated by the way.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've rebased this on top of Domenic's change. Please let me know if there is consensus on doing more here.

@wanderview
Copy link
Member Author

Note, I'll be traveling next week and will have limited time to work on this. I should be able to respond to things tomorrow, however. Just FYI in terms of keeping momentum on this.

@annevk
Copy link
Member

annevk commented Jan 16, 2023

I think this would really benefit from @antosart and @domenic's review as it touches history, navigation, and the policy container.

@antosart
Copy link
Member

I already started having a look but I got blocked because of #8725. Anyway, I'll move forward with a review tomorrow.


<li><p>If <var>responsePolicyContainer</var> is not null, then return
<var>responsePolicyContainer</var>.</p></li>
<var>responsePolicyContainer</var> with its <span data-x="policy-container-origin">origin</span>
set to <var>responseOrigin</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

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

Can we assert these are the same instead of overwriting?

@@ -89811,6 +89813,9 @@ location.href = '#foo';</code></pre>
<var>finalSandboxFlags</var>, <var>documentState</var>'s <span
data-x="document-state-initiator-origin">initiator origin</span>, and null.</p></li>

<li><p>Set <var>policyContainer</var>'s <span data-x="policy-container-origin">origin</span>
to <var>responseOrigin</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

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

I spent about 1.5 hours going down this rabbit hole.

I think it's definitely possible to make this easier to read. Now that effectively "determine navigation params policy container" + "determine the origin" are doing one big combined thing, it's pretty bad. They have the combined inputs responseURL, sandboxFlags, sourceOrigin, containerOrigin, historyPolicyContainer, initiatorPolicyContainer, parentPolicyContainer, responsePolicyContainer. Maybe sourceOrigin / containerOrigin /initiatorPolicyContainer / parentPolicyContainer have some redundancy; maybe not.

However, any work here ends up being pretty orthogonal to Ben's PR. I wrote it all out and it consists of a few steps:

  1. Split "determine navigation params policy container" into three algorithms with three inputs, one for each of its call sites. These are much easier to read because, e.g., the srcdoc version is very short, and then there's no srcdoc stuff in the fetching version.

  2. Try to consolidate "determine the origin" and "determine navigation params policy container" as much as possible. Some of this involves ensuring sourceOrigin /containerOrigin / initiatorPolicyContainer / parentPolicyContainer line up; I think they mostly do. I'm unsure yet whether the end state here has them as separate algorithms, or one combined algorithm, or whether we ensure that "determine the origin" is always called by the now-split-up "determine navigation params policy container" instead of having the call sites call both of them in sequence. TBD.

  3. Potentially simplify the inputs to, or split up, "determine the origin" itself.

  4. Potentially consolidate "create a policy container from a fetch response" into the above stuff, since after (1) it should be pretty closely tied with the first variant of "determine navigation params policy container".

I'm going to file a new issue with this. At the start of my journey I thought this should block the refactoring here, but after spending 1.5 hours on this I've convinced myself it's very separable work, it's not obvious how to complete all the steps, and each step needs close review.

<dd><var>policyContainer</var></dd>
<dd>a <span data-x="clone a policy container">clone</span> of <var>policyContainer</var>
with its <span data-x="policy-container-origin">origin</span> set to
<var>newDocumentOrigin</var></dd>
Copy link
Member

Choose a reason for hiding this comment

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

Let's add <span class="XXX">Does the origin actually change?</span>

@@ -91811,6 +91813,9 @@ location.href = '#foo';</code></pre>
<var>sourceSnapshotParams</var>'s <span data-x="source-snapshot-params-policy-container">source
policy container</span>, null, and <var>responsePolicyContainer</var>.</p></li>

<li><p>Set <var>resultPolicyContainer</var>'s <span
data-x="policy-container-origin">origin</span> to <var>responseOrigin</var></p></li>.
Copy link
Member

Choose a reason for hiding this comment

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

This seems incorrect; the previous step should take the responseOrigin argument.

@@ -94956,7 +94956,8 @@ new PaymentRequest(&hellip;); // Allowed to use
settings object">origin</dfn></dt>

<dd>
<p>An <span>origin</span> used in security checks.</p>
<p>This objects <span data-x="concept-settings-object-policy-container">policy
container</span>'s <span data-x="policy-container-origin">origin</span>.</p>
</dd>
Copy link
Member

Choose a reason for hiding this comment

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

This shouldn't be part of the <dl>. Instead we should define it as a standalone <dfn> similar to "responsible event loop" below.

@@ -107760,6 +107759,18 @@ interface <dfn interface>SharedWorkerGlobalScope</dfn> : <span>WorkerGlobalScope
</dl>
</li>

<li><p><span>Assert</span> that <var>settings object</var>'s <span
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
<li><p><span>Assert</span> that <var>settings object</var>'s <span
<li><p><span>Assert</span>: <var>settings object</var>'s <span

data-x="concept-url-scheme">scheme</span> is not "<code data-x="">data</code>", then set
<var>settings object</var>'s <span data-x="concept-settings-object-policy-container">policy
container</span>'s <span data-x="policy-container-origin">origin</span> to <var>inherited
origin</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

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

Is there a way to fold this stuff into "initialize a worker global scope's policy container"?

Copy link
Member

Choose a reason for hiding this comment

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

+1. Analogously as my comment above for properly initializing a document's policy container's origin in the policy containers section, I think it would be great to encapsulate also this logic within the policy container inheritance. At the end of the day, that's exactly the purpose of the policy container: encapsulating this inheritance logic!

@@ -83572,18 +83588,22 @@ dictionary <dfn dictionary>DragEventInit</dfn> : <span>MouseEventInit</span> {
<li><p><span>Assert</span>: <var>parentPolicyContainer</var> is not null.</p></li>

<li><p>Return a <span data-x="clone a policy container">clone</span> of
<var>parentPolicyContainer</var>.</p></li>
<var>parentPolicyContainer</var> with its <span
data-x="policy-container-origin">origin</span> set to <var>responseOrigin</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

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

Is this necessary? Can't we assert this instead?

data-x="policy container">policy container</span>-or-nulls <var>historyPolicyContainer</var>,
<var>initiatorPolicyContainer</var>, <var>parentPolicyContainer</var>, and
<var>responsePolicyContainer</var>:</p>
policy container</dfn> given a <span>URL</span> <var>responseURL</var>, an <span>origin</span>
Copy link
Member

Choose a reason for hiding this comment

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

I have the impression we don't actually need to pass the origin, and it would make more sense not to do so. The point of this algorithm is to encapsulate the inheritance of policies for local schemes. I think the origin is inherited in exactly the same way (if not, we should understand why and carve out exceptions). Could we omit passing this origin here?

Ideally we would move the algorithm for determining the origin here in the policy containers section, and the origin would follow the same logic as the other policies: the inheritance (i.e. determining the origin based on whether the scheme is local) should be implemented here in "determining navigation params policy container", while responsePolicyContainer's origin should be populated in "creating a policy container from a fetch response", as you are already doing.

data-x="concept-url-scheme">scheme</span> is not "<code data-x="">data</code>", then set
<var>settings object</var>'s <span data-x="concept-settings-object-policy-container">policy
container</span>'s <span data-x="policy-container-origin">origin</span> to <var>inherited
origin</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

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

+1. Analogously as my comment above for properly initializing a document's policy container's origin in the policy containers section, I think it would be great to encapsulate also this logic within the policy container inheritance. At the end of the day, that's exactly the purpose of the policy container: encapsulating this inheritance logic!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: origin topic: policy container The policy container proposal
Development

Successfully merging this pull request may close these issues.

5 participants