A simple but effective method I used on a couple of my clients' sites was the hidden text field with an obvious name.
The field name is usually "email" (actual email field is something like 'user_email') - and hidden via css, not an actual type="hidden". As long as it's submitted and empty, I can be somewhat sure the submission came from my form and probably wasn't filled by a bot. // the form <style> #email { display: none; } </style> <form method="post" action="/processor/"> <input type="text" name="email" value="" id="email" /><br /> <input type="text" name="user_email" value="" /><br /> <input type="submit" /> </form> // the processor if (array_key_exists('email', $_POST) && strlen($_POST['email']) == 0) { // ok } else { // spoofed } Not necessarily hard to beat, but it killed all of the automated form posts my clients were receiving. Mark > -----Original Message----- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On Behalf Of Michael Southwell > Sent: Tuesday, May 01, 2007 11:34 AM > To: talk@lists.nyphp.org > Subject: [nyphp-talk] form spoofing > > I thought I was following best practices ( > http://www.nyphp.org/phundamentals/spoofed_submission.php ) > in creating a comment form for a restaurant client (There is > no security issue here; the comments are emailed): > > I stored a random token in the session: > > session_start(); > if ( ! isset( $_SESSION['secret'] ) ) $_SESSION['secret'] = > uniqid( rand(), TRUE ); > > I hid that token in the form: > > <form action="comments.php" method="post" onSubmit="return > checkForm(this)"> <input type="hidden" name="secret" > value="<?= $_SESSION['secret'] ?>" /> > > Upon submission, I checked for the token: > > if ( $_POST['secret'] !== $_SESSION['secret'] ) die( 'invalid > form submission' ); > > But I still got obvious spoofed submissions, not very many of > them, and all vapid and often nonsensical (a sample: "I > consider that beside Your site there is future!"), but still > maddening. So I added a five-minute timeout: > > if ( ! isset( $_SESSION['timeout'] ) ) { > $timeout = time() + 5 * 60; > $_SESSION['timeout'] = $timeout; > } > > and checked for that as well: > > $now = time(); > if ( $_POST['secret'] !== $_SESSION['secret'] || $now > > $_SESSION['timeout'] ) die( 'invalid form submission' ); > > But this hasn't helped much; I still get a few of them, > though I can't figure out how they can be generated. Any advice? > > > Michael Southwell, Vice President for Education > New York PHP > http://www.nyphp.com/training - In-depth PHP Training Courses > > > _______________________________________________ > New York PHP Community Talk Mailing List > http://lists.nyphp.org/mailman/listinfo/talk > > NYPHPCon 2006 Presentations Online > http://www.nyphpcon.com > > Show Your Participation in New York PHP > http://www.nyphp.org/show_participation.php > _______________________________________________ New York PHP Community Talk Mailing List http://lists.nyphp.org/mailman/listinfo/talk NYPHPCon 2006 Presentations Online http://www.nyphpcon.com Show Your Participation in New York PHP http://www.nyphp.org/show_participation.php