npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

blankshield

v0.6.3

Published

Prevent reverse tabnabbing phishing attacks caused by _blank

Downloads

1,666

Readme

blankshield

Prevent reverse tabnabbing based phishing attacks that take advantage of _blank targets. Demo. The library has been tested and is compatible with the latest versions of Chrome, Firefox, Safari, Opera, as well as IE6-11. This is a cross-browser solution for browsers that do not support noopener.

Overview

Tabs or windows opened using JavaScript or target="_blank" have some limited access to the parent window, ignoring cross-origin restrictions. Among that is the ability to redirect the parent tab or window using window.opener.location.

While it may seem harmless, a phishing attack is possible when web applications permit or make use of user-submitted anchors with target="_blank" or window.open(). Consider the following scenario:

You're an admin using some forum or chat software. You're currently logged into the app, and view a message left by a user. The user asks or convinces you to click a link in his message, which opens in a new tab. While the new page may look completely safe - perhaps just a screenshot or bug report in some HTML, it executes the following JS:

window.opener.location.assign('https://yourcompanyname.phishing.com');

What you don't realize is that while dealing with this illegitimate customer or user complaint, your application's tab was redirected in the background. To what? An identical phishing website, simply requesting that you enter your credentials to log back in.

Is there a chance you might not check the URL? That you didn't notice the tab icon refresh? While many are suspicious of links they click and new tabs they open - what about existing tabs?

demo

Vulnerable browsers

The following table outlines the scope of affected browsers:

[1] IE is not vulnerable to the attack by default. However, this can change depending on security zone settings.

Installation

The library can be installed via npm:

npm install --save blankshield

Or using bower:

bower install blankshield

Usage

blankshield.js works in global, CommonJS and AMD contexts.

blankshield(target)

blankshield is the main function exported by the library. It accepts an anchor element or array of elements, adding an event listener to each to help mitigate a potential reverse tabnabbing attack. For performance, any supplied object with a length attribute is assumed to be an array.

// It works on a single element
blankshield(document.getElementById('some-anchor'));

// Array-like objects such as HTMLCollections
blankshield(document.getElementsByClassName('user-submitted-link'));
blankshield(document.getElementsByTagName('a'));
blankshield(document.querySelectorAll('a[target=_blank]'));

// As well as jQuery
blankshield($('a[target=_blank]'));

// But make sure not to bind listeners to the anchors that would stop event
// propagation. In the example below, blankshield is not able to intercept the
// click behavior.
var anchor = document.getElementById('some-anchor')
anchor.addEventListener('click', function(e) {
   e.stopImmediatePropagation();
});
blankshield(document.getElementById('some-anchor'));

blankshield.open(strUrl, [strWindowName], [strWindowFeatures])

Accepts the same arguments as window.open. If the strWindowName is not equal to one of the safe targets (_top, _self or _parent), then it opens the destination url using "window.open" from an injected iframe, then removes the iframe. This behavior applies to all browsers except IE < 11, which use "window.open" followed by setting the child window's opener to null. If the strWindowName is set to some other value, the url is simply opened with window.open().

// To open an url with blankshield, instead of window.open()
blankshield.open('https://www.github.com/danielstjules');

// To bind a listener using jQuery with event delegation
// (Assumes no other listeners prevent propagation)
$('body').on('click', 'a[target=_blank]', function(event) {
  var href = $(this).attr('href');
  blankshield.open(href);
  event.preventDefault();
});

blankshield.patch()

Patches window.open() to use blankshield.open() for _blank targets.

blankshield.patch();

Solutions

A handful of solutions exist to prevent this sort of attack. You could:

  • Remove or disallow target="_blank" for any anchors pointing to a different origin.
  • Append rel="noreferrer" to any links with target="_blank". When done, window.opener will be null from the child window. It's well supported among webkit-based browsers, though you'll fall short with IE and Safari. And of course, it prevents sending the referrer in the request headers. You could fall off as an identifiable source of traffic for some friendly sites.
  • Append rel="noopener" to any links with target="_blank". When done, window.opener will be null from the child window. See caniuse for current browser support.
  • Listen for the click event and prevent the default browser behavior of opening a new tab. Then, call window.open() with the href and set the the child's opener to null. Unfortunately, this does not work for Safari. Safari's cross-origin security prevents the modification of window.opener of a child window if it lies on a different origin, yet still allows the child window to access window.opener.location.
  • Listen for the click event and prevent the default browser behavior of opening a new tab. Inject a hidden iframe that opens the new tab, then immediately remove the iframe. This is what blankshield does.