This is really, really, really old. The general principles are still somewhat useful, so I'm leaving it up.
Provide a simple, transparent authorization mechanism to insure submission authenticity. This example prevents resource abuse, automated and/or remote access. Simply put, it prevents CSRF, unwanted access to sensitive application resources as well as preventing bot activity (spam).
Replaces CAPTCHA and other CSRF form tokenization techniques, the latter still being susceptible to scraping the form input and submission. By using client side events attached to elements (form submit & link clicks) to store a cookie on the client, we eliminate the ability of a vast majority of tools & techniques to access protected resources. Best of all, it's transparent to the user, replacing the need for CAPTCHA's and other annoying human tests.
- Using Ajax
$_GETURL's to retrieve a user's profile information exposes the URL and can be accessed by copying the URL directly into the address bar. Allowing the exposed data to be scraped or exploited (DoS, trickle attacks, etc). Past and current solutions include checking
$_SERVER['HTTP_X_REQUESTED_WITH'](easily spoofed) or using the
$_POSTmethod. This technique will protect any URL using any method.
- You might have links like:
- Another "solution" I've seen is checking the referer to ensure actions taken are verified to be on the local domain. Some browsers and/or firewalls block the referer from being sent, and it can also be easily spoofed. This technique ensures the event was fired on the domain the cookie was created.
- Change the encryption. I swiped that bit off the internets because I didn't want to deal with noting PHP versions, modules, algorithms, etc.
- You might still want to think about double clicks. You could check if a click has happened and just return
falseinstead of creating another token which would prevent extra clicks from propagating and having any effect.
- You could, if you were crafty enough, set tokens by name (eg:
OBJ.setToken('foo');) and check them by name (eg:
valid_ajax_token('foo');). It'd be useful if you wanted to fire multiple protected events.
Examples included. Load up index.php and go.
Copyright 2009 Devin Hayes, Public Domain License