Always “hover” before you click? Wrong.
frameloss.org
frameloss.org
<a href="http://google.com" id="link">Google</a>
and some JavaScript running like this: document.querySelector("#link").addEventListener('click', function(e) {
e.preventDefault();
document.location = 'http://evil.com';
}, false);
And this is a valid use case - perhaps we're in a web app and if the user clicks the link, we want to perform an AJAX call for the data instead of the normal link action - unless they're opening the link in a new tab, in which case it should load as usual (from the URL given in the link). So this isn't really a easily fixable problem.Rather than crippling JavaScript, we should focus on implementing a different security principle: Merely visiting a web page should never be dangerous or harmful. This has always been a goal of browser developers. Browsers run in a sandbox for this reason. Although they will execute arbitrary, untrusted code (i.e. JavaScript), by design that code has no access to your hard drive, other web pages you visit, etc..
Were this principle implemented perfectly, the OP's concerns would mostly be alleviated. Sure, some people will still download and run malware EXEs, or enter their private data on a phishing site. But those who do will probably not benefit much from hovering over a URL anyway. If you don't know better than to hand the keys to the castle to random web pages, you probably don't know how to spot a suspicious URL.
Seriously, though; while Linux seems to typically be less of a target, and thus a malicious executable is less likely, the level of security that things like running as a non-root user buy me aren't that huge on a desktop machine. Most of the interesting things are things that my non-root user can read and write, by necessity and design. With a proper SELinux setup, this might change a bit, but that's not "simply" a matter of running Linux.
The sad part is that a lot of web developers cannot even imagine a different architecture that wouldn't have these problems. The discussions are mostly about more of the same. More permissions. More low-level APIs.
i don't believe that's a fair assessment. A bit of javascript that "subverts" the href of an anchor tag to perform some _other_ task other than loading the page at that href, is functionally indistinguishable from having that same task performed _after_ the said href page is loaded.
Sure, the technical side of this is indeed very different. One is an ajax call plus some DOM manipulation. The other is loading a different page, in an entirely different execution context. But to an end user, a link is something that you click on, and somethign happens. What happens is also quite predictable (provided the site/web app is designed with usability in mind). I dont think somethign is fundamentally broken at all.
And to the people that use "return false;" in their JS to prevent default actions from happening, i.e. a click on a link or submitting a form, don't, stop using it, e.preventDefault(); is the way to go, as posted by timothya.
Command-click it to open in new tab, as expected.
https://chrome.google.com/webstore/detail/remove-google-redi...
(I should have used a gist. I'm hungry and now I want a pasty)
So it seems... Google could learn a thing or two; or maybe they decided not to be evil.
I'm sure I've successfully copied links directly from Google's search results before, but I've only recently (past few months?) noticed the URL mangling.
Of course, once you're willing to run arbitrary javascript code you can't trust any mouse click anymore. Doesn't matter if the click is on a link or a button or anywhere else. Disallowing href attribute modification doesn't help one bit.
So the "hover" hint you get for links is still highly useful, especially on sites you trust.
I'd think writing a cheap algorithm to track those posts and who upvotes them would be easy. Maybe they are doing a honeypot?
So, sometimes I am wrong. This attack does work, but it’s irrelevant, and here’s why: if someone has control of the DOM the game is already over, there’s nothing the browser can do for you in that case. It doesn’t really matter that the hover-status can be spoofed at that point. I’ll leave the post up so you can marvel in my stupid, but to summarize–nothing to see here. (At least I’m not throwing banner ads at you.)
It is often necessary to attach click handlers to anchor tags. For example, let's say you have a link to an image, but when a user clicks on that link, you don't want to navigate to the raw image - you want to open it in a shadowbox. But if someone right clicks and copies the links URL, that will take them to the raw image.
In terms of browsers "allowing" this to happen - anything beyond the ham-fisted approach of just disallowing click handlers on all anchor tags would be prohibitively complicated.
It is something worth being aware of though - just because that link says it's taking you to Google doesn't mean it won't take you somewhere less savory!
[0] https://developer.mozilla.org/en-US/docs/DOM/window.status
One interesting lesson here is if you reverse the logic. What if you have an Ajax action triggered by JavaScript? My point is, you should generally trigger actions from linked content instead of random controls like buttons (you can of course place a button inside a link or style the link as a button). This way, bots and non-JS browsers will still be able to follow it.
If phishing, it's much more important to look at at the URL after the page is loaded. URL shorteners already obscure the actual destination much of the time.
If malicious pages, well, if an attacker can present a link with a JavaScript onclick handler they can most likely already inject an iframe or redirect you to a malicious page.
So even if you enable JavaScript on a site, RequestPolicy is a good second line of defence.
The attack: This completely misses the point. If a site wants to mess with you it doesn't need a link for that, it can just directly execute Javascript code and do whatever it wants to do.
Deleted comment
It's interesting though, that they bother to resolve the click event URL so, in a sense, they're evaluating the code before the click event fires and the code is actually executed.
I'm not a security guy, but there seems like a potential for exploit there, though I'm guessing there's probably a very good explanation why there isn't.
In summary, I am wrong, and you are right. Thanks for pointing it out, as I was genuinely confused there for a moment.
Most of the time I have seen sites do this so that the link is clear and easy to read for the user, while adding utm_campaign codes and other junk that the user does not care about.
However I am sure some sites use this behavior to .... trick users.
So we need to ask ourselves which is the greater good?
There might be a UX solution here, in how those links are shown, and maybe there should be some rules about HTTPS links in pages. Maybe users could set a setting that if the link is changed on click, that maybe, it would not automatically go to the site, but would prompt the user, or at least inform them on the landing page with some form of notification.
For example:
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i)) || (navigator.userAgent.match(/Android/i))) {
$("a").bind('touchstart', function(){
$(this).addClass('hover');
});
$("a").bind('touchend', function(){
$(this).removeClass('hover');
});
}This should work in theory.
Open a new browser window and type in PayPal.com rather than clicking any links in that "You need to update your information or your account will be shut down" e-mail.
Once you're actually on PayPal.com (or whatever), looking at the hover URLs is pointless.
<script>
window.location = 'http://example.com';
</script>
Redirected.Its not a bug, its a feature. What you should be worried about is what http://www.example.com can do, can it execute arbitrary code, post to facebook/twitter etc.?
$('#element').mouseover(function(){ window.location .... });I do this in a few webapps where I cancel href events or redirect them to a hash tag. It's actually quite useful.
onclick="window.location='<badurl>';return false;"
If you want to be even more shady you can use the 'onmouseover' event with the same redirect as above. Which defeats the look before you leap approach of hovering before clicking.
onmouseover="window.location='<badurl>';return false;"
The script the OP uses replaces the href, so once you click it, it'll reflect the true destination.
As others have mentioned, you can get around that by doing a redirect and cancelling the link action instead. Then it will always show the fake target.
If this 'attack' didn't work then a large amount of what I do every day would become a lot more complicated.