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

noopener header #2122

Closed
AliceWonderMiscreations opened this issue Nov 30, 2016 · 12 comments
Closed

noopener header #2122

AliceWonderMiscreations opened this issue Nov 30, 2016 · 12 comments

Comments

@AliceWonderMiscreations

We need a standard header that will cause browser to apply rel="noopener" to every link on a web page served with that header whether or not the rel attribute is specified with links.

This header could easily be used to update web applications that were coded before the rel="noopener" attribute was proposed and for archived web pages. Something like

<IfModule mod_headers.c>
Header set window.opener "none"
</IfModule>

Doesn't have to be that syntax precisely, but that's the concept. Websites that do not ever want to have their pages vulnerable to the broken window.opener() specification could then send that header with every http request and compliant browsers would not allow window.opener()

Alternatively websites who want to only allow window.opener() from certain domains could include a list of white-listed domains. For example

<IfModule mod_headers.c>
Header set window.opener "none +google.com +*.haxor.net"
</IfModule>

When the header is not sent, then the current behavior would remain. That should avoid any breakage of existing web applications.

I propose that this header should NOT be allowed as a meta tag.

I would appreciate it if someone who already understands the politics of how to get stuff pushed through write up actual RFC or whatever is needed. I'm not good at that sort of thing (or good with people in general).

@domenic
Copy link
Member

domenic commented Nov 30, 2016

This is a great idea that is already being worked on as part of the CSP spec: w3c/webappsec#139 :). As such I'll close this issue, but if for some reason you feel more comfortable discussing here than in that issue thread, feel free to use the closed issue for such discussion.

@domenic domenic closed this as completed Nov 30, 2016
@AliceWonderMiscreations
Copy link
Author

As much as I love CSP it is not practical to include a default CSP header in apache/nginx packages shipped by distributions.

A header specifically disabling window.opener() could easily be shipped with the apache/nginx packaging of linux distributions so that the vast majority of web servers out there could be secured without needing to worry about CSP.

@AliceWonderMiscreations
Copy link
Author

Also the last time I looked at CSP specification I believe it was only applicable on HTTPS. If window.opener() is not restricted to HTTPS then a header disabling it should not require HTTPS.

@AliceWonderMiscreations
Copy link
Author

Maybe I'm out of line, but given how much Google has invested in OAuth and that OAuth seems to be problem with securing window.opener() I have to suspect there is a serious conflict of interest when a WhatWGm moderator who works for Google (the biggest tracking company on the Internet) closes my attempt at a compromise within 10 minutes without any discussion having taken place.

It certainly has the appearance of a serious conflict of interest.

CSP is a difficult concept for many to properly apply which is why it isn't very widely deployed.

A header that is complex and difficult to apply really isn't the right place for fixing a dangerous default behavior.

Please re-open this issue so that it can be seen and receive actual discussion before being closed.

Thank you.

@AliceWonderMiscreations
Copy link
Author

AliceWonderMiscreations commented Nov 30, 2016

Also use of Content Security Policy forbids any inline CSS or script nodes in the body, hence why a lot of sites can do not run CSP and Google's own webmaster tools will ding your score if all your scripts are in the head - something you have to do with CSP.

Thus CSP is the wrong place to turn off this dangerous behavior because CSP is far more restrictive than many sites are able to cope with. WordPress for example can't use CSP.

I also seem to recall Google AdSense not working with CSP.

@zcorpan
Copy link
Member

zcorpan commented Nov 30, 2016

Unless you have evidence for your accusations, yes, you are out of line. Please stick to technical discussion here.

The open/closed status indicates whether there is something actionable for the editors; not whether discussion is allowed to take place. If the discussion turns out that there is something actionable, the issue will be re-opened.

Thanks!

@AliceWonderMiscreations
Copy link
Author

There IS something actionable for the editors. A specification for a header a web server can send to tell browsers that window.opener() is not supported on the page.

Completely opt-in so there is no backwards compatibility issues, much easier to consistently implement than adding a rel attribute to every link with a target, and would work extremely well with archived content.

Marking the issue as closed takes it out of the view of editors who look at the current Issues unless those editors specifically look for closed issues. It suppresses discussion on this very serious issue and that is out of line and yes, it smells to me like an incredible conflict of interest.

I'm here because I want a secure Internet, not to make friends.

@AliceWonderMiscreations
Copy link
Author

From https://www.w3.org/TR/html-design-principles/#priority-of-constituencies

3.2. Priority of Constituencies

In case of conflict, consider users over authors over implementors over specifiers over theoretical purity. In other words costs or difficulties to the user should be given more weight than costs to authors; which in turn should be given more weight than costs to implementors; which should be given more weight than costs to authors of the spec itself, which should be given more weight than those proposing changes for theoretical reasons alone. Of course, it is preferred to make things better for multiple constituencies at once.
3.3. Secure By Design

Ensure that features work with the security model of the web. Preferrably address security considerations directly in the specification.


That seems to indicate that users should take priority over OAuth etc. - but the window.opener() is dangerous to users.

It also seems to indicate that security is important and needs to be properly addressed within the specification.

Therefore the logical thing to do is make the specification secure for Internet users, either by requiring a header to whitelist domains that can use window.opener() as I would prefer, or by implementing a header that allows a page to say no one can use it, as I proposed in this compromise.

Failure to do so seems to me to be a violation of the W3C HTML Design Principles.

Leaving it to Content Security Policy is not good enough because Content Security Policy is too complex for many webmasters to implement and is know to cause frustrating issues with many very popular and extensively used Internet applications.

Something needs to be done.

I tried contacting the browsers, they said they will only do something if the specifications calls for it. So we need to have the specification call for it.

@foolip
Copy link
Member

foolip commented Nov 30, 2016

There IS something actionable for the editors. A specification for a header a web server can send to tell browsers that window.opener() is not supported on the page.

@clelland, have you considered something like this for Feature Policy?

@AliceWonderMiscreations
Copy link
Author

I am going to make some points and then I will shut up unless specifically asked. My people skills are not good and I'm afraid my people skills are getting in the way. Please try to see beyond them. It is a bonafide disability.

Some things to note regarding rel="noopener"

A) I've been involved in web programming since 1997. I can't recall a single case in history where the official way to apply a scripting (or other) security measure was through a node attribute. I suppose you could argue the password attribute that causes bullets instead of letters, but that's strictly display.

B) I also can't recall a single case where scripting permissions differed based upon what part of the DOM the element was in, but that's what rel="noopener" does.

That doesn't mean they don't exist, just that I can't recall them. This attribute appears to be a first.

C) This vulnerability isn't freshly discovered but I just found out about it last week. Usually I pay more attention to TLS related vulnerabilities, etc. but I usually hear about most vulnerabilities fairly quickly. Had I not stumbled upon this one I wouldn't know and may of my sites would still be insecure because of ignorance. I am guessing that many webmasters haven't heard. That is why defaults need to be secure, and the default behavior of window.opener() is NOT secure. That's why it really needs to be changed. It's equivalent to servers that default to the export ciphers, it really is. Yes when Apache / OpenSSL shipped with SSLv2 and export ciphers, a system administrator in the know could secure it - but the default configuration was safer with SSLv2/3 disabled and export ciphers disabled because a lot of system administrators don't know better.

The same really needs to be the case with window.opener(). The default needs to be secure, one should have to take action to reduce security. That's almost always the way security should be, that's a fundamental concept of security. Back in the late 90s, you could install Red Hat 5 and wait 10 minutes and it would be owned, guaranteed, because the defaults weren't secure, resulting in unpatched vulnerable daemons listening. They learned their lesson, now system administrators have to enable a service giving opportunity to patch first.

Defaults need to be secure. That is fundamentally more important than backwards compatibility.

D) Using an attribute to secure an insecure default is a fundamentally flawed approach. I literally do not understand how that was ever approved. It frustrates me that it was, probably as much as my complete inability to socially interact with most people frustrates them.

Think about it. Even if a website tried to do it, there is a good chance there are some anchor tags missed somewhere. Just an example - I thought I had done it with one of my web apps, I use DOMDocument for everything so I added the following to my code that serves pages:

private function sanitizeTargetLinks() {
  $nodelist = $this->xmlBody->getElementsByTagName('a');
  $n = $nodelist->length;
  for($j = $n; --$j >= 0;) {
    $node = $nodelist->item($j);
    if($node->hasAttribute('target')) {
      $target = trim(strtolower($node->getAttribute('target')));
      if($target == "_blank") {
        if($node->hasAttribute('rel')) {
          $relString = preg_replace('/\s+/', ' ', trim(strtolower($node->getAttribute('rel'))));
          $relTags = explode(' ', $relString);
        } else {
          $relTags = array();
        }
        if(! in_array('noopener', $relTags)) {
          $relTags[] = 'noopener';
        }
        if(! in_array('noreferrer')) {
          $relTags[] = 'noreferrer';
        }
        $relString = implode(' ', $relTags);
        $node->setAttribute('rel', $relString);
      }
    }
  }
}

It seemed to work - until I realized there were links being created by Ajax that didn't go through that filter. And that filter wouldn't work on archived static pages, unless I first imported them into a DOM object, and that doesn't always go cleanly.

I found my bug, but I bet others who think they have taken care of the issue haven't found all cases where it still adds a link with a target but no rel tag.

That's why an attribute really is the wrong approach. A header is something you can add to a single configuration file (e.g. .htaccess) and it applies everywhere.

E) CSP is not the right solution either.

CSP may be easy for some people to implement correctly but it is very difficult for many to implement so they don't. Look at how hard it is just to get people using TLS, and TLS is a lot easier to configure and troubleshoot than CSP. If CSP is the only way to secure a server with a header, then most servers will remain vulnerable.

Also, *nix distributions can't ship with a default CSP header because it would break too many websites, the webmasters would just disable it. They can however ship with a default header securing sites from window.opener() if that is all the header did - and the only sites it would break are the few that actually need window.opener().

If we really can't be secure by default in the web browser, then we need a single header that specifically disables window.opener() so that web servers can secure the pages by default.

-=-=-

It really frustrates me to no end that these are things I have to explain. I do not understand why they are not obvious points, and I do not understand why there is resistance to them.

Probably the same way most people don't understand why I can't master even the most basic social skills.

That's why I'm hoping someone who does have social skills will understand where I'm coming from and advocate for a proper fix to this fubar default, because rel="noopener" most certainly is not a proper fix.

Thank you for your time, I will try not to be abrasive in the future, it's worst when I am passionate about something.

-=-

With all my love for all things TLS one of the most important encryption concepts is that most breaches don't involve breaking the encryption. They involve vulnerabilities like this one. The best encryption in the world won't protect users from this issue.

@clelland
Copy link
Contributor

clelland commented Dec 1, 2016

@foolip, that's an interesting idea; that would make possible something like

Feature-Policy: {"opener": ["self", "https://friendly-domain.com"]}

We haven't talked much yet about propagating policies to new browsing contexts; we've really only considered nested contexts, but it's worth discussing.

Opened w3c/webappsec-permissions-policy#50

@annevk
Copy link
Member

annevk commented Apr 24, 2019

This is #3740 now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

6 participants