Adding rel=”noopener” to Sitecore

Some say target="_blank" is one of most underestimated vulnerabilities on the web. When you make a link to an external into a new tab or window, that site gets access to your site. If it’s a design flaw in browsers or something else is debatable, but luckily there is a simple fix for it by adding rel="noopener" to external links.

Update: The latest update of Sitecore 8.2 already have this implemented, so if you’re on the current version, you’re already covered and don’t need to bother about this. However, you need to be aware of the potential vulnerability to ensure any links not rendered by Sitecore fields are made correct as well.

How it works
When you have a link on a website that opens a new tab or window, like <a href="external.url" target="_blank">, the linked page gets access to the source page in the original tab through the window.opener property. This means an attacker could change the visible content, or even the url, of the source page. This could be used for phishing attacks etc. Here is an example of this in action.

To prevent this, we can add the rel="noopener" attribute to links, like <a href="external.url" target="_blank" rel="noopener">. This will makes the window.opener property null on the target site. If you’re opening windows using javascript, you’ll have to set the opener property to null manually, such as var win=window.open(); win.opener=null; win.location = url;.

Even if you’re linking legit website, you can’t be sure the target sites aren’t hacked and could leverage from this vulnerability. Besides, there are rarely a required need for external sites to access the DOM of your site, so always adding the noopener option rarely causes any trouble.

Solving it in Sitecore
Besides any static links, we can let Sitecore add the rel="noopener" attribute to all content author created links. We essentially have two kind of links: The Sitecore field types “General Link” and “General Link with Search”, and links within Rich Text fields. The General Link (with Search) field types can be fixed at render time and the content for Rich Text fields can be updated at save time.

We can extend the <renderField> pipeline by adding the the attribute to the render field parameters when rendering links that are external.

For rich text fields, it would be quite time consuming to do this runtime, so instead we can hook into the item:saving event of all rich text fields. By parsing the rich text with HtmlAgilityPack we can easily load all links and update the link attributes accordingly.

Sample code for solving this is available here: https://github.com/mikaelnet/Sitecore.RelNoOpener

Let me know what you think about this solution.

Leave a Reply