CSRF脚本不起作用

时间:2018-05-27 12:50:49

标签: php html csrf-protection

为什么这个脚本不会保护我的表单免受CSRF攻击?就像我试图添加他们在网站nocsrf网站上的演示形式,这是完美的。当我更改csrf令牌的代码时,没有任何事情发生,它只是将信息处理到我当前表单上的数据库。

这是我的 表单部分,它与html表单在同一页面上:

$editFormAction = $_SERVER['PHP_SELF'];
if (isset($_SERVER['QUERY_STRING'])) {
  $editFormAction .= "?" . htmlentities($_SERVER['QUERY_STRING']);
}

if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) {
  $insertSQL = sprintf("INSERT INTO contact (name, email, topic, `description`, IP, date) VALUES (%s, %s, %s, %s, %s, %s)",
                       GetSQLValueString($_POST['name'], "text"),
                       GetSQLValueString($_POST['email'], "text"),
                       GetSQLValueString($_POST['topic'], "text"),
                       GetSQLValueString($_POST['description'], "text"),
                       GetSQLValueString($_SERVER['REMOTE_ADDR'], "text"),
                       GetSQLValueString(date("Y-m-d H:i:s"), "text"));

  mysql_select_db($database_config, $config);
  $Result1 = mysql_query($insertSQL, $config) or die(mysql_error());

  $insertGoTo = "takk.php";
  if (isset($_SERVER['QUERY_STRING'])) {
    $insertGoTo .= (strpos($insertGoTo, '?')) ? "&" : "?";
    $insertGoTo .= $_SERVER['QUERY_STRING'];
  }
  header(sprintf("Location: %s", $insertGoTo));
}

这是我的html表单部分:

<form action="#" method="post" name="form1" id="form1">

<h4>Navn:</h4>
      <input type="text" class="form-control" name="name" value="" size="32" required>

<h4>Email:</h4>
<input type="email" class="form-control" name="email" value="" size="32" required>


<h4>Kategori:</h4>
<select name="topic" class="form-control">
        <option value="Generelt" <?php if (!(strcmp("Generelt", ""))) {echo "SELECTED";} ?>>Generelle spørsmål</option>
        <option value="Problemer" <?php if (!(strcmp("Problemer", ""))) {echo "SELECTED";} ?>>Problemer</option>
        <option value="Klage" <?php if (!(strcmp("Klage", ""))) {echo "SELECTED";} ?>>Klage</option>
        <option value="Bugs" <?php if (!(strcmp("Bugs", ""))) {echo "SELECTED";} ?>>Bugs</option>
      </select>

<h4>Hva lurer du på?</h4>
      <textarea name="description" class="form-control" cols="50" rows="5" required></textarea>
<br />
      <button type="submit" class="blue-button" style="width:100%;">Send henvendelse</button>
    <input type="hidden" name="csrf_token" value="<?php echo $token; ?>">

  <input type="hidden" name="MM_insert" value="form1" />
</form>

Nocsrf.php

<?php
/**
 * NoCSRF, an anti CSRF token generation/checking class.
 *
 * Copyright (c) 2011 Thibaut Despoulain <http://bkcore.com/blog/code/nocsrf-php-class.html>
 * Licensed under the MIT license <http://www.opensource.org/licenses/mit-license.php>
 *
 * @author Thibaut Despoulain <http://bkcore.com>
 * @version 1.0
 */
class NoCSRF
{
    protected static $doOriginCheck = false;
    /**
     * Check CSRF tokens match between session and $origin. 
     * Make sure you generated a token in the form before checking it.
     *
     * @param String $key The session and $origin key where to find the token.
     * @param Mixed $origin The object/associative array to retreive the token data from (usually $_POST).
     * @param Boolean $throwException (Facultative) TRUE to throw exception on check fail, FALSE or default to return false.
     * @param Integer $timespan (Facultative) Makes the token expire after $timespan seconds. (null = never)
     * @param Boolean $multiple (Facultative) Makes the token reusable and not one-time. (Useful for ajax-heavy requests).
     * 
     * @return Boolean Returns FALSE if a CSRF attack is detected, TRUE otherwise.
     */
    public static function check( $key, $origin, $throwException=false, $timespan=null, $multiple=false )
    {
        if ( !isset( $_SESSION[ 'csrf_' . $key ] ) )
            if($throwException)
                throw new Exception( 'Missing CSRF session token.' );
            else
                return false;

        if ( !isset( $origin[ $key ] ) )
            if($throwException)
                throw new Exception( 'Missing CSRF form token.' );
            else
                return false;
        // Get valid token from session
        $hash = $_SESSION[ 'csrf_' . $key ];

        // Free up session token for one-time CSRF token usage.
        if(!$multiple)
            $_SESSION[ 'csrf_' . $key ] = null;
        // Origin checks
        if( self::$doOriginCheck && sha1( $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'] ) != substr( base64_decode( $hash ), 10, 40 ) )
        {
            if($throwException)
                throw new Exception( 'Form origin does not match token origin.' );
            else
                return false;
        }

        // Check if session token matches form token
        if ( $origin[ $key ] != $hash )
            if($throwException)
                throw new Exception( 'Invalid CSRF token.' );
            else
                return false;
        // Check for token expiration
        if ( $timespan != null && is_int( $timespan ) && intval( substr( base64_decode( $hash ), 0, 10 ) ) + $timespan < time() )
            if($throwException)
                throw new Exception( 'CSRF token has expired.' );
            else
                return false;
        return true;
    }
    /**
     * Adds extra useragent and remote_addr checks to CSRF protections.
     */
    public static function enableOriginCheck()
    {
        self::$doOriginCheck = true;
    }
    /**
     * CSRF token generation method. After generating the token, put it inside a hidden form field named $key.
     *
     * @param String $key The session key where the token will be stored. (Will also be the name of the hidden field name)
     * @return String The generated, base64 encoded token.
     */
    public static function generate( $key )
    {
        $extra = self::$doOriginCheck ? sha1( $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'] ) : '';
        // token generation (basically base64_encode any random complex string, time() is used for token expiration) 
        $token = base64_encode( time() . $extra . self::randomString( 32 ) );
        // store the one-time token in session
        $_SESSION[ 'csrf_' . $key ] = $token;
        return $token;
    }
    /**
     * Generates a random string of given $length.
     *
     * @param Integer $length The string length.
     * @return String The randomly generated string.
     */
    protected static function randomString( $length )
    {
        $seed = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijqlmnopqrtsuvwxyz0123456789';
        $max = strlen( $seed ) - 1;
        $string = '';
        for ( $i = 0; $i < $length; ++$i )
            $string .= $seed{intval( mt_rand( 0.0, $max ) )};
        return $string;
    }
}
?>

0 个答案:

没有答案
相关问题