views:

55

answers:

1

This article about php form security:

http://nedbatchelder.com/text/stopbots.html

... mentions a "spinner" as:

The spinner is a hidden field used for a few things: it hashes together a number of values that prevent tampering and replays, and is used to obscure field names. The spinner is an MD5 hash of:

* The timestamp,
* The client's IP address,
* The entry id of the blog entry being commented on, and
* A secret.

The field names on the form are all randomized. They are hashes of the real field name, the spinner, and a secret. The spinner gets a fixed field name, but all other fields on the form, including the submission buttons, use hashed field names.

Does anyone have a code sample of how to implement this on a php page containing a form and the associated php form submission script?

I don't want to use AJAX, just PHP.

A: 

You could implement the following:

  On Page Submit:
  <?php
    $spinnerKey = 'spin';
    $spinner = $_POST[$spinnerKey];
    $values = array();

    foreach ($_POST as $key=>$value)
    {
      if ($key !== $spinnerKey)
      {
        $values[deHash($key, $spinner)] = $value;
      }
    }
?>

A 'deHash' example:
<?php

    # You have to define deHash based on your hash but it 
    # would look something like this:
    var $_rainbowTable = array();
    var $_expectedKeys = array();

    function deHash($hashedkey, $spinner)
    {
        $rt = $this->getRainbowTable($spinner);

        return isset($rt[$hashedKey])
          ? $rt[$hashedKey])
          : NULL;
    }

    function getRainbowTable($spinner)
    { 
        if (count($this->_rainbowTable) > 0)
            return $this->_rainbowTable;

        foreach ($this->_expectedKeys as $key)
        {
            $this->_rainbowTable[hash($key, $spinner)] == $key;
        }

        return $this->_rainbowTable;
    }
  ?>

Ultimately though I don't see how this stops bots submitting your page - it just stops people's "email/user/pass" remember browser plugin from working.

Graphain
You're missing the point of "hash function" if you refer to reversing one. I think you mean encryption / decryption.
Slartibartfast
I'm using reversible in the same sense you are when you say the key can be worked out from the hash function. deHash would use a rainbow table generated from the hash of your spinner and the expected field names and then use your hashedkey as a lookup in that table to return the actual key, or a null otherwise.
Graphain
See my updated example. I corrected the terminology because I got the impression you meant encyrption/decryption since you talked about reversing.
Graphain