Christian Cunningham's Personal Site

Last Tick Link Swap

Setup

Consider the following link: Amazon.

If you hover over the link, you will see that it points to https://amazon.com. We then expect that the browser should take you to Amazon once you click it. But, if you click the link, you may be suprised where it takes you...

Motivation

The other day, I was listening to Security Now while driving. In the episode I was listening to, they were talking about password managers, and Tavis Ormandy's excellent essay about how password managers may insecurely interface with the website. This discussion made me suddenly have the question: What triggers first, the onclick JavaScript event or the anchor tag's href? This question has lead to this post and proof-of-concept.

With this question in mind, I crafted this page to use JavaScript to assign an onclick listener to the document and attempt to redirect the click to an unexpected page! If the onclick event triggers before the href anchor is triggered and redirects, then the browser could be redirected to a page that the user is not expected!

The Vulnerability

This page has been specially crafted to intercept, using some javascript, the target anchor tag's href and redirect the click to an unexpected page! Say that we had a malicious advertisement which injected these ~10 lines of JavaScript. The advertisement can then take over all of the links on a page and take you to unexpected pages. Another way to smuggle this in is from using an untrusted third party tracker suite. Some ways this may be abused:

  1. Website Redirects high-profile sites (e.g. Amazon, Facebook, etc.) to a phishing site that has been made to look the same but steal user credentials
  2. Phishing email contains a link to phishing site that looks like the actual site, and the links on hover look all like legitimate links but are then redirected after to the phishing site's next page
  3. Insert and/ or remove affiliate codes from links, similar to this bleeping computer article: Malicious browser extensions targeted almost 7 million people
  4. Extract cookies from a user viewing a website by redirecting them to an attacker's site with the cookies in the heading
  5. Data leakage from sending the current page's contents to an attackers' site which is set up to automatically redirect to the intended target but log the data that was transferred

Expected Behavior

From the HTML living standard 15.7.1: "User agents are expected to allow users to discover the destination of hyperlinks and of forms before triggering their navigation.".
It is important that the link that browsers display is the link that the tags navigate to so that this interception does not occur. If this is allowed to occur, then attackers can redirect sensitive queries to their own space, and thus bypass any potential CORS and MITM policies that the browser has in place. As it is currently implmented in many browsers, this specification is violated since the JavaScript of a page is allowed to execute before link navigation and so the assumption that the reference does not change is not always held.

Tested Browsers

Browser Platform Version Vulnerable
Firefox Desktop 107.0.1 (64 bit) Yes
Safari Desktop 15.5 Yes
Ungoogled Chromium Desktop 88.0.4324.150 (x86_64) Yes
It appears that all major browsers are vulnerable to this. I have been able to reproduce this for desktops' left and right click events as well as mobile taps.
So far from my testing, when you long press on a mobile device and then navigate to the link from the context menu, the browser navigates to the correct location. I have implemented the click and contextmenu JavaScript events but there still may be a mobile device long press context menu JavaScript event that may still allow this to be violated, further testing is needed.

Mitigations

  1. Disabling JavaScript
  2. Disabling JavaScript hosted externally*

Proof-of-Concept Script

let documentOnClickSuper = document.onclick;
document.onclick = function(evt) {
	//  Ensure it is the anchor tag, and in this case,
       	// ensure that we only redirect the amazon link.
	if (evt.target.tagName == "A" && evt.target.id == "pwn") {
		let href = evt.target.href;
		// Execute javascript on click event
		//evt.target.href = "javascript:alert('PWNED!');";
		evt.target.href = "ad_jack_pwned.html";
		setTimeout(() => {evt.target.href=href}, 500);
	} else {
		//  If this is not the target anchor,
		// then use the regular onclick function to not arise any suspicion!
		if (documentOnClickSuper === null) {}
		else {
			documentOnClickSuper(evt);
		}
	}
	// Change all anchor tags
	//let anchors = document.getElementsByTagName('a');
	//for (let i = 0; i < 1; i++) {
	//	anchors[i].href = "/poc/ad_jack_pwned.html";
	//}
}
			
This is a simpler form, and has some commented out regions that propose other methods. The full script is found at Script.

Other Examples

Stealing Cookies

Example Cookie: Send Money with Auth Cookie!

Thank you to Sergey Bilovytskyy for hosting the off origin page to exemplify this PoC.

Run Javascript Instead

Search!