What do you believe to be the real reason of most spam messages? What's the motivation of e-mails that invite you to buy colorful pills, drugs, cars, mortgages for impossibly low prices? Just to induce you to click to increase some sort of counter and click-through rate? There's probably more than that. One of the possible answers is one-click attack.
A one-click attack is when a completely unaware user is induced to click on a link to an unknown page. Apparently, the user (you) doesn't see anything special or anything that looks suspicious or blameworthyust a normal page. Is that all? If you've just been the ignorant victim of a one-click attack, by clicking to see that page, you triggered a more dangerous process. But not dangerous to you!
Imagine you're a hacker willing to perform an illicit action on a web site that you know very well (and that you can access yourself). You prepare an HTTP post packet with a well-known sequence of input fieldsthe fields you know the page under attack requires, accepts, and more importantly, processes. You can send this packet in many ways; for example, from a fake page hosted on your web site. In this case, if the attack succeeds, you could be logged.
What if you induce someone else to launch the attack on your behalf? You write a luring click in an e-mail and see if someone swallows the bait.
What are the mechanics of this attack and what's the hole it exploits? The bad news is that there's no patent programming error to avoidthe page has no way to distinguish legitimate traffic from one-click attacks. Yet attacks happen.
One thing you can do is identify potentially critical operations and implement a sort of validation layer to filter incoming requests. A simple but effective approach is checking the referer variable of the request. It has to match your site; if not, you should block the call to be on the safe side. However, in this way, you have chances to block certain totally legitimate calls such as those that originate out of a window.open or document.location script.
A better approach is relying on ASP.NET 1.1 magic (it doesn't work with 1.0) and setting the ViewStateUserKey property on the Page class. In the Init event, you set the property to a string value that is not null and unique to the usertypically, the session ID. What's the effect of this?
The session ID is (normally) a server-side value that an attacker has no way to guess. The best (and only) line of defense against this attack is using input fields whose value can't be guessed or set on the client. Attackers who target ASP.NET pages have to provide a valid viewstate field. If ViewStateUserKey is set, this value is used to generate the MAC key of the viewstate. If the property is set to a server-side, hard-to-guess value (like the session ID), the attacker will have a hard time reproducing it.
For example, if you set ViewStateUserKey to session ID, the attacker has to figure out you're using the session ID, then has to guess the session ID and find a way to inject the bogus call in just that session. It's theoretically possible, but definitely hard and probably enough to discourage attackers.
Dino Esposito is Wintellect's ADO.NET and XML expert, and a trainer and consultant
based in Rome, Italy. Dino is a contributing editor to Windows Developer
Network and MSDN Magazine, and the author of several books for Microsoft
Press including Building Web Solutions with ASP.NET and ADO.NET
and Applied XML Programming for .NET. Contact Dino at [email protected].