Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the "disown-opener" Content Security Policy directive do?

CSPv3 specifies a new disown-opener policy:

The disown-opener directive ensures that a resource will disown its opener when navigated to.

The linked WHATWG spec isn't very helpful either:

The opener IDL attribute on the Window object, on getting, must return the WindowProxy object of the browsing context from which the current browsing context was created (its opener browsing context), if there is one, if it is still available, and if the current browsing context has not disowned its opener; otherwise, it must return null. On setting, if the new value is null then the current browsing context must disown its opener; if the new value is anything else then the user agent must call the [[DefineOwnProperty]] internal method of the Window object, passing the property name "opener" as the property key, and the Property Descriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true } as the property descriptor, where value is the new value.

like image 270
Indolering Avatar asked Nov 04 '16 22:11

Indolering


1 Answers

It causes window.opener to be set to null on any new windows or tabs that get navigated to from any document served with a CSP header containing the disown-opener directive.

The use case is similar to the one for rel=noopener.

The class of attack both are meant to prevent is caused by the fact that when you have links in your document A to a document B (potentially at another origin), any script at document B can through the value of window.opener access and control the window object at document A.

So document B’s script can change the window.opener.location for the window document A is in to the URL of document C, so that window navigates away from document A to that URL.

If document C is designed to look exactly like document A—e.g., including a spoofed login form—it could be used to trick the user and phish user credentials.

Mathias Bynens covers this in detail in About rel=noopener: What problems does it solve?.

Setting window.opener to null on the document being navigated to prevents the problem.

Without disown-opener for the use case it addresses, document A first would need to open a new tab/window to a document/location it controls, then use script to set window.opener to null, then have the script at the document in that tab/window navigate it to document B.

Update 1: I’ve raised a PR against the HTML spec to add informative notes to the spec for this.

Update 2: The patch from the PR above was merged into the HTML spec, so it now says this:

If a browsing context is disowned, its window.opener attribute is null. That prevents scripts in the browsing context from changing any properties of its opener browsing context's Window object (i.e., the Window object from which the browsing context was created).

Otherwise, if a browsing context is not disowned, then scripts in that browsing context can use window.opener to change properties of its opener browsing context's Window object. For example, a script running in the browsing context can change the value of window.opener.location, causing the opener browsing context to navigate to a completely different document.

like image 110
sideshowbarker Avatar answered Sep 24 '22 08:09

sideshowbarker