dou70260 2013-08-05 07:49
浏览 73

提交后ajax登录csrf键输入更改

my login .php

<?php
    require "../includes/nonce.php";// nonce tokens for forms not sessions
    ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html class="no-js" dir="rtl" lang="he-IL" xml:lang="he" xmlns="http://www.w3.org/1999/xhtml">
<head>

  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta name="generator" content="editplus" />
  <meta name="author" content="" />
  <meta name="keywords" content="" />
  <meta name="description" content="" />
  <meta name="csrf-param" content="authenticity_token"/>
  <meta name="csrf-token" content="<?php echo ulNonce::Create('meta');?>"/>
    <title>finest  - מערכת ניהול</title>



    <link rel="stylesheet" href="stylelogin.css" type="text/css" />
    <script type="text/javascript" src="js/modernizr.custom.49650.js"></script>
    <script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="js/jquery-ui-1.10.0.custom.min.js"></script>
    <!--for login hash pass-->
    <script type="text/javascript" src="secure/sha512.js"></script>


<script type="text/javascript">


$(document).ready(function() {

$('.inplaceError').each(
                function(i) {
                    $(this).focus(function(e){
                        $("#errorMessage").html("");
                    });
                }
            );

$('#container').fadeIn();

function sale() {
    $('#footer').fadeIn(200);
}

setTimeout(sale, 500);

});
</script>

<script type="text/javascript">

$(document).ready(function(){ 
$('form input:submit').bind('click', validLogin);

});

function validLogin(){

     if($.trim($("#password").val()) == '')
    {
        var p = '';
    }
    else
    {
        $("#p").val(   hex_sha512(  $("#password").val() ) );
        var p = $("#p").val();
    }

    var key = $('#key').val();
    var nonce = $('#nonce').val();
    var email = $.trim($('#email').val());

    var dataString = 'email='+ email + '&key='+ encodeURIComponent(key) + '&nonce='+ nonce + '&p='+ p;


     $.ajax({  
     url: "processed.php",
      type: "POST",  
      data: dataString,
      dataType:'json',
      cache: false,
      success: function(data)
      {  
               if(data.login == true) 
                {  
                    window.location = "index.php";

                }
                else
                  {
                 $("#siimage").trigger("click");
                 $("form input:submit").effect("shake", {times:2}, 100);
                 $("#errorMessage").html(data.message); 
                  get_nonce();
                  }




             if(data.cblocked == true)
             {
             $("#email").prop('disabled', true);
             $("#password").prop('disabled', true);
             $('input[type="submit"]').attr('disabled','disabled');
             document.getElementById("Submit").value = 'נעול';

             }
              if(data.csrf == true)
             {
             $("#email").prop('disabled', true);
             $("#password").prop('disabled', true);
             $('input[type="submit"]').attr('disabled','disabled');
             document.getElementById("Submit").value = 'נעול';

             }


      }
    });  
        return false;
} 

function get_nonce(){

        $.ajax({  
         url: "../includes/nonce.php",
          type: "POST", 
          dataType:'json',
          async: false,
          data: {ajax:"true"},
          success: function(response)
          {  

               $("#nonce").val(response.nonce);
               $("#key").val(response.key);
          }
        });
}

</script>

    </head>
    <body>
<!--[if lte IE 7]><script src="ie6/warning.js"></script><script>window.onload=function(){e("ie6/")}</script><![endif]-->


                     <?php
                      if($session->checkbruteGuest(ulUtils::GetRemoteIP(false), $func->mysqli) == true)
                      { 
                       $disabled = 'disabled';
                      } 
                       else
                      {
                       $disabled = '';
                      }

                     ?>
    <div id="wrapper" align="center">
        <div id="container" align="center">
        <?php if($session->admin_logged_in){
            header('location: index.php');
              }
              else
              {
            ?>
        <form accept-charset="UTF-8" action="#" method="post">
            <input type="hidden" id="p" name="p" value="">

            <?php $n->generateFormFields(); ?>

            <img style="position:absolute;float:left;top:53px;left:22px;" src="images/1369318943_secure-server-px-png.png" width="75" height="75" alt="" />

                <img style="float:right;position:absolute;left:310px;top:8px;" src="images/header-object.png" width="260" height="90" alt="" />
                <div class="login">ברוך הבא למערכת הניהול!</div>
                <div class="username-text">שם משתמש:</div>
                <div class="password-text">סיסמא:</div>
                <div class="username-field">
                    <input type="text" name="email" id="email" onclick="this.value='';" value="לדוגמא: a@test.com" class="inplaceError" <?php echo htmlentities(@$disabled);?>/>
                </div>
                <div class="password-field">
                    <input type="password" name="password" id="password" class="inplaceError" <?php echo htmlentities(@$disabled);?> onclick="this.value='';"/>     
                </div>



                <div id="errorMessage">
                <?php 
                     if($session->checkbruteGuest(ulUtils::GetRemoteIP(false), $func->mysqli) == true)
                      {
                       echo ucwords(htmlentities('ההתחברות נחסמה ל- 10 דקות עקב יותר מידי ניסיונות התחברות כושלים.')); 
                      }
                      ?>

                <img id="loader" src="images/ajax-loader.gif" width="16" height="16" />
                </div>
                <div class="forgot-usr-pwd">שכחת&nbsp;<a href="forgotuser.php">שם משתמש</a>&nbsp;או&nbsp;<a href="forgotpass.php">סיסמא</a>?</div>
                <?php
                 if($session->checkbruteGuest(ulUtils::GetRemoteIP(false), $func->mysqli) == true)
                      { 
                       echo '<input type="submit" id="Submit" name="Submit" value="נעול" disabled />';
                      } 
                 else
                      {
                       echo '<input type="submit" id="Submit" name="Submit" value="כניסה" />';
                      }
                ?>
            </form>
            <?php } ?>
        </div>

        </div>

<div id="footer">
            *בעת תקלה ניתן לשלוח מייל : ravgrg@gmail.com ,או להתקשר לאחראי האתר.
        </div>
    </body>
</html>

And the nonce.php:

<?php


class Nonce
{
  /**
   * How long in seconds the nonce will be good for. If you don't want the token to expire use -1.
   *
   * @var int
   **/

  protected $expire = 43200; // 12 Hours

  /**
   * A secret string that is hashed with a unique id and time. The longer
   * and more complex this is the better.
   *
   * @var string
   **/
  private $secret = "skldjfhsalkdjhfkwj3543soafsdnflasnhjkjk";

  /**
   * The hashing type used to create the nonce. 
   *
   * @var string
   **/
  protected $hash = 'sha256';

  /**
   * The amount of iternations done on a hash. This is done to enhance security. Larger 
   * numbers will be more secure but will increase the time needed to create the hash.
   *
   * @var int
   **/
  protected $iter = 100;

  /**
   * If true nonces will be stored in a database to ensure only one use.
   *
   * @var boolean
   **/
  protected $store = true;

  /**
   * The database username. Only used if $store is set to true.
   *
   * @var string
   **/
  private $db_user = "root";

  /**
   * The database password. Only used if $store is set to true.
   *
   * @var string
   **/
  private $db_pass = "";

  /**
   * The database name. Only used if $store is set to true.
   *
   * @var string
   **/
  private $db_name = "ibids";

  /**
   * The database table name. Only used if $store is set to true.
   *
   * @var string
   **/
  private $db_table = "all_nonce";

  /**
   * The database host. Only used if $store is set to true.
   *
   * @var string
   **/
  private $db_host = "127.0.0.1";

  /**
   * Is a PDO database handler object. Only used if $store is set to true.
   *
   * @var object
   **/
  protected $dbh;


  public function __construct()
  {



    if(!$this->secret) throw new Exception("You cannot leave \$secret blank. Please set it to a random string.");
    if(strlen($this->secret) < 32) throw new Exception("Your secret key should be at least 32 characters");
    $this->secret = hash('sha224', $this->secret);

    if($this->store){
      try{
        $this->dbh = new PDO('mysql:host=' . $this->db_host . ';dbname=' . $this->db_name, $this->db_user, $this->db_pass);
        $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      }catch (PDOException $e){
        throw new Exception($e);
      }
    }
  }


  /**
   * Checks the validity of a nonce. If valid (and $store is true) the nonce 
   * will become 'used' and invalid (meaning it cannot be used again).
   *
   * @param int $timestamp the time in the form of the unix epoch
   * @param float $uid a unique id created by php's uniqid() function (although this can technically be anything). 
   * @param string $content optional additional content supplied by the user. 
   * @param float $uid a unique id created by php's uniqid() function (although this can technically be anything). 
   * @return Boolean true on success or will throw exception on error.
   **/
  public function validateAndUseNonce($timestamp, $uid, $content = '', $nonce)
  {
    $hash = $this->getNonce($timestamp, $uid, $content, strlen($nonce));

    // Check to see if nonce has been used. Only checks if nonce's are being stored.
    if($this->store && $this->nonceExists($nonce)){
      throw new Exception("This form has already been submitted once.");
    }

    // Check to see if time has expired
    if($this->expire > -1){
      if(time() > $timestamp + $this->expire){
        throw new Exception("This form has expired. Please reload the page and try submitting again.");
      }
    }

    if($nonce == $hash){
      if($this->store) $this->storeNonce($nonce);
      return true;
    } else {
      throw new Exception("Invalid form request. Please try again.");
    }
  }

  /**
   * Creates a unique nonce string with an optional length. Max length is dependent upon hashing algorithm.
   * @param int $timestamp the time in the form of the unix epoch
   * @param float $uid a unique id. 
   * @param string $content optional additional content supplied by the user. 
   * @param int length optional the length of the returned nonce. Max Dependent upon hashing algorithm.
   * @return string the nonce.
   **/
  public function getNonce($timestamp, $uid, $content = '', $length = NULL)
  {
    global $site;
    $hash = hash($this->hash, $timestamp . $this->secret . $uid . $content);
    $i = 0;
    do{
      $hash = hash($this->hash, $hash);
      $i++;
    } while ($i < $this->iter);

    if($length){
      $hash = substr($hash, 0, $length);
    }

    return $hash;
  }

  /** 
   * Store the nonce in the database.
   * @param string $nonce
   * @return boolean true on success false on failure 
   **/
  private function storeNonce($nonce)
  { 
    $sql = "INSERT INTO " . $this->db_table . " (nonce) VALUES (:nonce)";
    $q = $this->dbh->prepare($sql);
    return $q->execute(array(":nonce" => $nonce));
  }

  /** 
   * Checks the existence of a nonce in a database
   * @param string $nonce
   * @return mixed boolean false if does not exist, or int 1 if it does 
   **/
  private function nonceExists($nonce)
  {
    if(!$this->store) throw new Exception("Cannot determine if this nonce has been used since \$store is set to false. Set \$store to true in order to track nonce usage.");

    $sql = "SELECT COUNT(*) FROM " . $this->db_table . " WHERE nonce = :nonce LIMIT 1";
    $q = $this->dbh->prepare($sql);
    $q->execute(array(":nonce" => $nonce));
    return $q->fetchColumn();
  }

  /**
   * This may be called to validate a form that was generated using generateFormFields()
   *
   * @param string $content optional the additional content that was provided when 
   * generateFormFields() was called
   *
   * @return boolean true if valid
   **/
  public function validateForm($content = '')
  {
    $plain = $this->fnDecrypt($_POST['key']);
    $plain = explode(' ', $plain, 2);

    $time = $plain[0];
    $uid = $plain[1];

    if($content && $content !== $plain[2]){

    }

    return $this->validateAndUseNonce($time, $uid, $content, $_REQUEST['nonce']);
  }
  /**
   * Generates 2 hidden fields to add nonce capability to a form. Forms using this method
   * can be validated using validateForm().
   *
   * @param integer $length optional The length of the nonce
   * @param string $content optional content that will be hashed into the nonce.
   * This might be useful if you want to include a user id. Remeber anything added here
   * must also be included as an argument when validateForm() is called.
   *
   * @return string
   **/

  public function generateFormFields($content = '', $length = NULL)
  {
    $time = time();
    $uid = $this->generateUid();
    $key = $time . " " . $uid;

    // We'll need this info later so we don't want to simply hash it. We could just send it in plain
    // text but this is a little more secure and makes things very difficult to break.
    $key = $this->fnEncrypt($key);
    $nonce = $this->getNonce($time, $uid, $content, $length);

        //The ajax variable decides if ajax wants the keys or page being loaded first time.
$ajax = isset($_POST['ajax']) ? $_POST['ajax'] : "false";

        if($ajax=="false"){
              echo "
<input type='hidden' id='nonce' name='nonce' value='$nonce'>
";
              echo "<input type='hidden' id='key' name='key' value='$key'>
";


        } else {
            echo json_encode(array("key" => $key, "nonce" => $nonce));

              //This would work when ajax called.
        }


  }


  /**
   * Checks to see if a form was posted that contains fields generated by generateFormFields().
   *
   * @return boolean true if form was posted
   **/
  public function isFormPosted()
  {
    if(isset($_REQUEST['key']) && isset($_REQUEST['nonce'])) return true;
  }

  /**
   * Creates a cryptographically secure random string. Tries first using urandom (for *nix systems),
   * then tries openssl_random_pseudo_bytes and as a last resort mt_rand.
   *
   * @return string a random string
   **/
  public function generateUid($length = 32)
  {
    // Best option, but only on *nix systems. Also some web servers don't have access to this.
    if(is_readable('/dev/urandom')){
      $f = fopen('/dev/urandom', 'r');
      $seed = fgets($f, $length); // note that this will always return full bytes
      fclose($f);
      return base64_encode($seed);
    }

    // Next best thing but requires openssl
    if(extension_loaded('openssl')){
      $seed = bin2hex(openssl_random_pseudo_bytes($length));
      return base64_encode($seed);
    }

    // Last resort, mt_rand
    for ($i = 0; $i < $length; $i++) {
        $seed = chr(mt_rand(0, 255));
    }

    return base64_encode($seed);
  }

  private function fnEncrypt($sValue)
  {
    return trim(
      base64_encode(
        mcrypt_encrypt(
          MCRYPT_RIJNDAEL_256,
          hash($this->hash, $this->secret, true), $sValue, 
          MCRYPT_MODE_ECB, 
          mcrypt_create_iv(
            mcrypt_get_iv_size(
              MCRYPT_RIJNDAEL_256, 
              MCRYPT_MODE_ECB
            ), 
            MCRYPT_RAND
          )
        )
      )
    );
  }

  private function fnDecrypt($sValue)
  {
    return trim(
      mcrypt_decrypt(
        MCRYPT_RIJNDAEL_256, 
        hash($this->hash, $this->secret, true), 
        base64_decode($sValue), 
        MCRYPT_MODE_ECB,
        mcrypt_create_iv(
          mcrypt_get_iv_size(
            MCRYPT_RIJNDAEL_256,
            MCRYPT_MODE_ECB
          ), 
        MCRYPT_RAND
        )
      )
    );
  }

  /**
   * Deletes any nonce's from the DB that are older than $expire. Nonce's older than $expire
   * can be safely deleted since they cannot be used anymore.
   *
   * @return boolean true on success
   **/
  public function cleanUpDb()
  {
    $sql = "DELETE FROM " . $this->db_table . " WHERE timestamp < DATE_ADD(now(), INTERVAL -:expire second)";
    $q = $this->dbh->prepare($sql);
    return $q->execute(array(":expire" => $this->expire));
  }
};
$n = new Nonce;

my proccsed.php

<?php

include "../includes/session.php";
require_once '../xsspro/library/HTMLPurifier.auto.php';
require "../includes/nonce.php";// nonce tokens for forms not sessions.

$config = HTMLPurifier_Config::createDefault();
$purifier = new HTMLPurifier($config);

header('Cache-Control: no-cache, must-revalidate');
header('content-type: application/json; charset=utf-8');

$msg = '';

 if($n->isFormPosted()){
  try{
    // Wil return true if valid.
    $msg = $n->validateForm();
  }catch (Exception $e){
    $msg = $e->getMessage(); 
  }
}


if($msg === true) : 

        foreach($_POST as $key => $value) {
            if (!is_array($key)) {
                // sanitize the input data
                if ($key != 'ct_message') $value = strip_tags($value);
                $_POST[$key] = $purifier->purify($value);
            }
        }


function cleanPost($val) {
  if(!isset($_POST[$val])) {
    $_POST[$val] = NULL;
    return;
  }
  $_POST[$val] = trim(htmlentities($_POST[$val], ENT_QUOTES, 'UTF-8'));
}


if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
  cleanPost('email');
  cleanPost('p');
  $message[]='לא ניתן להתחבר עם פרוקסי.';
}

if ($_SERVER["REQUEST_METHOD"] <> "POST") 
 die("You can only reach this page by posting from the html form");

$message=array();



if(isset($_POST['email']) && !empty($_POST['email']))
    {

        if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))
            {
            $email = $purifier->purify(@$_POST['email']);
            }
            else
            {
            $message[]='האימייל שהזנת שגוי או לא תקין נסה שוב';
            }
    }
    else
    {
        $message[]='אנא הכנס אימיל';
    }

if(isset($_POST['p']) && !empty($_POST['p']))
                {
                   $password = $purifier->purify(@$_POST['p']); 
                }
                else if($_POST['p'] == '')
                {
                  $message[]='אנא הכנס סיסמא';

                }

if(get_magic_quotes_gpc()){
   $password = stripslashes($password);
   $email = stripslashes($email);
}   


$countError=count($message);

   if($countError > 0)
     {

                 $errmsg = '';
      foreach($message as $key => $error) {

              if($key > 0)
              $errmsg .= " ,";
              $errmsg .= "{$error}";
             }
              $return = array('error' => 1, 'message' => $errmsg);
             echo json_encode($return);

    }
    else
    {

    if($session->admin_login($email, $password, $func->mysqli) == true) 
      {
              $return = array('login' => true);
              echo json_encode($return);

      } 
      else 
      {
           //return the errors from the function

      }
    }
elseif($msg):

              $return = array('message' => $msg);
              echo json_encode($return);
endif;
?>

nonce.php , proccsed.php , login.php

that all the files.

iv added the all codes i am stuck so hard cant figure to fix it, thanks allot and sry very very thanks for help!

  • 写回答

2条回答 默认 最新

  • dskvfdxgdo2422392 2013-08-05 09:08
    关注

    You did not include your jQuery success function. It should look something like this though.

    success: function(data) {
        // Get the key from the response
        var generatedkey = data['key'];
    
        // Set the appropiate field to the new key
        $("input[name=key]").val(generatedkey);
    }
    

    And the response of a 'valid' response should, look something like.

    echo json_encode(array("key" => $newkey));
    
    评论

报告相同问题?

悬赏问题

  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 Revit2020下载问题
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 单片机无法进入HAL_TIM_PWM_PulseFinishedCallback回调函数
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线