Tab Check
"Tab Check" is a developer tool used to check the behavior of HTML links and window.open()
calls in other websites.
Please open this page either via an HTML link or window.open()
call from another website.
On this browser, the window.open()
call or HTML link you've clicked on is...
not vulnerable vulnerable to the window.opener
attack (or you didn't reach this page via a window.open()
call or a link with the target="_blank"
attribute) (click here for details on how to fix it)
not leaking URL data leaking the domain leaking the domain and path leaking the domain, path and query via the HTTP "Referer" header (or you've navigated to this page directly) (click here for details on how to fix that)
What is "Tab Check"?
Tab Check is a free online developer tool for checking whether a website is leaking URL data (domain, path and query) via the HTTP "Referer" header to other sites it links to and if a website's way of opening new windows or tabs (via window.open()
calls or HTML anchor tags with the target="_blank"
attribute) makes it vulnerable to the target="_blank"
/ window.opener
attack.
What is the HTTP "Referer" header and what does it do?
It's a small piece of data sent by your browser as part of an HTTP request that tells the website you're visiting the page or domain you came from. So if you clicked on a link on Website1.test that leads to Website2.test, Website2.test is going to know that you came from Website1.test (in most cases; both the website and browser can be configured to send more or less data than that). This data may be used by a website to adjust the content it serves, however, it's usually just used for website analytics or to gather information about users.
What data can websites leak via the HTTP "Referer" header?
Depending on how the website, HTML document or individual anchor tag is set up, the header can leak:
- Nothing. The website you visit via an HTML link won't be able to tell whether you came from another website or just typed the URL into the browser yourself.
- Just the domain (e.g. https://google.com). While this isn't usually a big deal, it may be one if you're very privacy conscious or if the website you came from itself is sensitive information (e.g. websites that provide adult entertainment content, are related to a specific medical issue, etc.).
- The domain and path (e.g. https://google.com/path/to/specific/page/). If a path contains sensitive information (e.g. page on an embarassing medical issue) or if the website has lackluster security (e.g. usage of secret URLs without page-level access controls), revealing said path may allow a malicious website owner to acquire confidential information or even gain access to certain restricted functionality.
- The domain, path and query (e.g. https://google.com/path/to/page/?secret_value=42). While most query variables don't contain secret information (e.g. page=5 or theme=dark) some do contain data that may be sensitive (e.g. email addresses) or that may be used for certain attacks (e.g. the token used to protect against CSRF attacks).
How do I stop my website from leaking URL data to other websites I link to?
If you're a website owner, there are several different ways to limit the amount of information revealed via the HTTP "Referer" header:
- Make sure your server software serves the correct
Referrer-Policy
header value in every HTTP response:-
Referrer-Policy: same-origin
if you don't want to leak any URL data to external websites. The full URL will only be sent for internal HTTP requests (requests to other pages of your website). -
Referrer-Policy: strict-origin-when-cross-origin
if you're fine with sending the domain. As withsame-origin
, requests to internal pages will have the full referrer URL, but requests to external pages will only have the domain in the header. In addition, if the external request is made via a less secure protocol than your website (e.g. your website uses HTTPS but the website you're linking to uses HTTP) then no URL data will be sent at all. - According to MDN Web Docs, the
Referrer-Policy
header is supported by nearly all commonly used browsers except for Internet Explorer and Safari on iOS. If you wish to set your referrer policy for the browsers that don't support the header, you're going to have to use the<meta>
tag method (described below).
-
- Add a
<meta name="referrer" content="...">
tag with the appropriatecontent
attribute value (eithersame-origin
for no URL data for requests to external websites orstrict-origin-when-cross-origin
for sending just the domain) inside your page's<head>
element. This method is especially useful if your website's visitors use Safari on iOS or Internet Explorer (neither of which, as mentioned previously, support theReferrer-Policy
header) or you wish to set the referrer policy only for certain pages. - Add the
rel="noreferrer"
attribute to your<a>
tags / HTML links. This method is most suited to cases where you want to avoid sending referrer data to only select websites. - Use the
noreferrer
feature in yourwindow.open()
function calls (e.g.window.open("https://ExternalWebsite.test", "_blank", "noreferrer")
). Same advantages as therel="noreferrer"
attribute on HTML anchor tags.
If you're unable (or unwilling) to mess around with all these headers or HTML code, you're in luck - according to MDN Web Docs, nearly all popular browsers (except for IE and Safari) only leak the domain by default. Not a web developer and don't know how to set these things up? No worries, I offer software development services on a freelance basis. If you're interested, click here to get in touch.
What is the target="_blank" / window.opener vulnerability?
When a web page is opened in a new tab, certain browsers by default allow the newly opened page partial access to the window.opener
object for the tab that opened it. With this access, the newly opened page can secretly redirect the user to a (seemingly) identical phishing page (by setting the window.opener.location
property to a malicious URL). Here's a step-by-step breakdown of the attack:
- User goes to GoodWebsite.test in browser tab no. 1.
- User clicks a link on GoodWebsite.test that opens MaliciousWebsite.test in a new tab (browser tab no. 2).
- User's browser automatically switches to the newly opened tab (browser tab no. 2).
- While the user is distracted by the switch and is looking at the content in MaliciousWebsite.test, MaliciousWebsite.test secretly redirects browser tab no. 1 to GoodWebsiteLookalike.test that shows a "You've been logged out" message and a login screen that looks like it's from GoodWebsite.test.
- User switches back to browser tab no. 1 and notices the new page.
- User thinks he's still on GoodWebsite.test and types in his userame and password (not noticing the different URL in his browser's address bar).
- GoodWebsiteLookalike.test uses the username and password to hijack the user's GoodWebsite.test account.
By default, this vulnerability is present in both <a>
tags with the target="_blank"
attribute set and in window.open()
function calls. Obviously, the vulnerability is only relevant if the tag or function call is used to open pages on external websites.
How do I fix the target="_blank" / window.opener vulnerability?
If you're a website owner, there several different ways of mitigating this vulnerability:
- For
<a>
tags with thetarget="_blank"
attribute. Set therel="noopener"
attribute. If you've already added therel="noreferrer"
attribute, you can use both by separating them with a space (rel="noopener noreferrer"
).- If you're unable to modify
<a>
tags, don't fret - according to MDN Web Docs, newer versions of the most popular browsers automatically assumenoopener
for HTML links with thetarget="_blank"
attribute. This assumption doesn't seem to apply towindow.open()
calls at the time of writing.
- If you're unable to modify
- For
window.open()
function calls. Addnoopener
to the window features parameter (e.g.window.open("https://ExternalWebsite.test", "_blank", "noopener")
). If you want to use thenoreferrer
window feature as well, just separate the features with a comma (window.open("https://ExternalWebsite.test", "_blank", "noopener,noreferrer")
)- If you need to support older browsers or to know whether the
window.open()
call was blocked by a popup blocker (e.g. to ask the user to allow popups), simply open an empty window / tab, set the opener tonull
and then set the window's / tab's location to the intended web address (e.g.let win = window.open(); if (win != null) { win.opener = null; win.location = "https://website.test";}
).
- If you need to support older browsers or to know whether the
Not a web developer and don't know how to set these things up? No worries, I offer software development services on a freelance basis. If you're interested, click here to get in touch.
Where can I read more about this stuff?
The MDN Web Docs is a great developer resource for anything web related, be it info on browser support of different HTML, JavaScript and CSS features or detailed documentation of the aforementioned features. Here are the MDN Web Docs pages I used for sourcing (and double checking / verifying for the info I already knew) the information on how certain browser features work:
While writing all of this, I at first wanted to just quote a bunch of excerpts (with proper attribution of course) from the site but decided against it due to how verbose and detailed it is (which may be a bit too much for someone who's just starting out in web development or who just wants a quick summary). As such, my own tl;dr on these topics excludes a lot of asterisks, nuance and leaves out a lot of supplementary info. So if you want a really in-depth overview on how the web works (or just dislike my writing style), be sure to check out the MDN Web Docs.
Where do I send my suggestions / requests / bug reports?
I'm reachable on a number of platforms - click here for the contact links.