Saturday, January 19, 2013

Cross-Site Scripting (XSS) Protection

<?php
session_start();// SNIPif($_POST['sent'] && $_SESSION['form']) {
  if(hash_hmac('sha1', $_SERVER['REMOTE_ADDR'], $_SESSION['form']['nonce']) == $_POST['sent']) {
    if(time() - $_POST['form']['birth'] > 2) {
      // Proceed
    } else {
      // Lifetime:  than 3 seconds. Most likely spam.
    }
  } else {
    // Cross-Site Scripting / Cross Site Request Forgery
  }
} else {
  $_SESSION['form'] = array(
    'nonce' => openssl_random_pseudo_bytes(32),
    'birth' => time()
  );
  ?>  <form method="post">
  <!-- snip -->
  <input type="hidden" name="sent" value="<?=hash_hmac('sha1', $_SERVER['REMOTE_ADDR'], $_SESSION['form']['nonce']); ?>" />
  <input type="submit" />
  </form>
  <?php}?>


This code skeleton above does two things:
1. Securely requires that the form be displayed for > 2 seconds before being submitted.
2. Stops XSS/CSRF attacks by using cryptographic signatures