{"id":16323097,"url":"https://github.com/danielstjules/blankshield","last_synced_at":"2025-04-09T12:07:12.929Z","repository":{"id":26777636,"uuid":"30235775","full_name":"danielstjules/blankshield","owner":"danielstjules","description":"Prevent reverse tabnabbing phishing attacks caused by _blank","archived":false,"fork":false,"pushed_at":"2019-02-20T22:30:40.000Z","size":62,"stargazers_count":140,"open_issues_count":3,"forks_count":22,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-01T04:03:09.914Z","etag":null,"topics":["javascript","noopener","phishing-attacks","security","tabnabbing"],"latest_commit_sha":null,"homepage":"http://danielstjules.github.io/blankshield/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danielstjules.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-02-03T09:44:02.000Z","updated_at":"2024-02-23T23:04:52.000Z","dependencies_parsed_at":"2022-06-27T11:03:43.544Z","dependency_job_id":null,"html_url":"https://github.com/danielstjules/blankshield","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstjules%2Fblankshield","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstjules%2Fblankshield/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstjules%2Fblankshield/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstjules%2Fblankshield/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielstjules","download_url":"https://codeload.github.com/danielstjules/blankshield/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248036067,"owners_count":21037092,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","noopener","phishing-attacks","security","tabnabbing"],"created_at":"2024-10-10T22:53:57.314Z","updated_at":"2025-04-09T12:07:12.897Z","avatar_url":"https://github.com/danielstjules.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# blankshield\n\nPrevent [reverse tabnabbing](https://sites.google.com/site/bughunteruniversity/nonvuln/phishing-with-window-opener)\nbased phishing attacks that take advantage of _blank targets.\n[Demo](http://danielstjules.github.io/blankshield/). The library has been tested\nand is compatible with the latest versions of Chrome, Firefox, Safari, Opera,\nas well as IE6-11. This is a cross-browser solution for browsers that do not\nsupport [noopener](http://caniuse.com/#feat=rel-noopener).\n\n* [Overview](#overview)\n* [Vulnerable browsers](#vulnerable-browsers)\n* [Installation](#installation)\n* [Usage](#usage)\n  * [blankshield(target)](#blankshieldtarget)\n  * [blankshield.open(strUrl, \\[strWindowName\\], \\[strWindowFeatures\\])](#blankshieldopenstrurl-strwindowname-strwindowfeatures)\n  * [blankshield.patch()](#blankshieldpatch)\n* [Solutions](#solutions)\n\n## Overview\n\nTabs or windows opened using JavaScript or `target=\"_blank\"` have some limited\naccess to the parent window, ignoring cross-origin restrictions. Among that\nis the ability to redirect the parent tab or window using\n`window.opener.location`.\n\nWhile it may seem harmless, a phishing attack is possible when web applications\npermit or make use of user-submitted anchors with `target=\"_blank\"` or\n`window.open()`. Consider the following scenario:\n\nYou're an admin using some forum or chat software. You're currently logged\ninto the app, and view a message left by a user. The user asks or convinces\nyou to click a link in his message, which opens in a new tab. While the new\npage may look completely safe - perhaps just a screenshot or bug report in some\nHTML, it executes the following JS:\n\n``` JavaScript\nwindow.opener.location.assign('https://yourcompanyname.phishing.com');\n```\n\nWhat you don't realize is that while dealing with this illegitimate customer or\nuser complaint, your application's tab was redirected in the background. To\nwhat? An identical phishing website, simply requesting that you enter your\ncredentials to log back in.\n\nIs there a chance you might not check the URL? That you didn't notice the tab\nicon refresh? While many are suspicious of links they click and new tabs they\nopen - what about existing tabs?\n\n![demo](http://danielstjules.com/github/blankshield-chrome-demo.gif)\n\n## Vulnerable browsers\n\nThe following table outlines the scope of affected browsers:\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eBrowser\u003c/td\u003e\n    \u003ctd\u003eClick\u003c/td\u003e\n    \u003ctd\u003eShift + click\u003c/td\u003e\n    \u003ctd\u003eMeta/Ctrl + click\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eChrome 40\u003c/td\u003e\n    \u003ctd\u003ex\u003c/td\u003e\n    \u003ctd\u003ex\u003c/td\u003e\n    \u003ctd\u003ex\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eFirefox 34\u003c/td\u003e\n    \u003ctd\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eOpera 26\u003c/td\u003e\n    \u003ctd\u003ex\u003c/td\u003e\n    \u003ctd\u003ex\u003c/td\u003e\n    \u003ctd\u003ex\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eSafari 7, 8\u003c/td\u003e\n    \u003ctd\u003ex\u003c/td\u003e\n    \u003ctd\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eIE6...11\u003c/td\u003e\n    \u003ctd colspan=\"3\"\u003e\u003csup\u003e[1]\u003c/sup\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003csup\u003e[1]\u003c/sup\u003e IE is not vulnerable to the attack by default. However, this can\nchange depending on security zone settings.\n\n## Installation\n\nThe library can be installed via npm:\n\n``` bash\nnpm install --save blankshield\n```\n\nOr using bower:\n\n``` bash\nbower install blankshield\n```\n\n## Usage\n\nblankshield.js works in global, CommonJS and AMD contexts.\n\n#### blankshield(target)\n\nblankshield is the main function exported by the library. It accepts an\nanchor element or array of elements, adding an event listener to each to\nhelp mitigate a potential reverse tabnabbing attack. For performance, any\nsupplied object with a length attribute is assumed to be an array.\n\n``` JavaScript\n// It works on a single element\nblankshield(document.getElementById('some-anchor'));\n\n// Array-like objects such as HTMLCollections\nblankshield(document.getElementsByClassName('user-submitted-link'));\nblankshield(document.getElementsByTagName('a'));\nblankshield(document.querySelectorAll('a[target=_blank]'));\n\n// As well as jQuery\nblankshield($('a[target=_blank]'));\n\n// But make sure not to bind listeners to the anchors that would stop event\n// propagation. In the example below, blankshield is not able to intercept the\n// click behavior.\nvar anchor = document.getElementById('some-anchor')\nanchor.addEventListener('click', function(e) {\n   e.stopImmediatePropagation();\n});\nblankshield(document.getElementById('some-anchor'));\n```\n\n#### blankshield.open(strUrl, \\[strWindowName\\], \\[strWindowFeatures\\])\n\nAccepts the same arguments as window.open. If the strWindowName is not\nequal to one of the safe targets (_top, _self or _parent), then it opens\nthe destination url using \"window.open\" from an injected iframe, then\nremoves the iframe. This behavior applies to all browsers except IE \u003c 11,\nwhich use \"window.open\" followed by setting the child window's opener to\nnull. If the strWindowName is set to some other value, the url is simply\nopened with window.open().\n\n``` JavaScript\n// To open an url with blankshield, instead of window.open()\nblankshield.open('https://www.github.com/danielstjules');\n\n// To bind a listener using jQuery with event delegation\n// (Assumes no other listeners prevent propagation)\n$('body').on('click', 'a[target=_blank]', function(event) {\n  var href = $(this).attr('href');\n  blankshield.open(href);\n  event.preventDefault();\n});\n```\n\n#### blankshield.patch()\n\nPatches window.open() to use blankshield.open() for _blank targets.\n\n``` JavaScript\nblankshield.patch();\n```\n\n## Solutions\n\nA handful of solutions exist to prevent this sort of attack. You could:\n\n* Remove or disallow `target=\"_blank\"` for any anchors pointing to a\n  different origin.\n* Append `rel=\"noreferrer\"` to any links with `target=\"_blank\"`. When done,\n  `window.opener` will be null from the child window. It's well supported among\n  webkit-based browsers, though you'll fall short with IE and Safari. And of\n  course, it prevents sending the referrer in the request headers. You could\n  fall off as an identifiable source of traffic for some friendly sites.\n* Append `rel=\"noopener\"` to any links with `target=\"_blank\"`. When done,\n  `window.opener` will be null from the child window. See\n  [caniuse](http://caniuse.com/#feat=rel-noopener) for current browser support.\n* Listen for the click event and prevent the default browser behavior of\n  opening a new tab. Then, call `window.open()` with the href and set the\n  the child's opener to null. Unfortunately, this does not work for Safari.\n  Safari's cross-origin security prevents the modification of `window.opener` of a\n  child window if it lies on a different origin, yet still allows the child\n  window to access `window.opener.location`.\n* Listen for the click event and prevent the default browser behavior of\n  opening a new tab. Inject a hidden iframe that opens the new tab, then\n  immediately remove the iframe. This is what blankshield does.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielstjules%2Fblankshield","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielstjules%2Fblankshield","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielstjules%2Fblankshield/lists"}