2014-09-20 10 views
0

Я читаю книгу Криса Шиффлет, «Основная безопасность PHP». Существует глава о CSRF, где автор рекомендует использовать токен для предотвращения CSRF. Код в книге говорит, чтобы добавить маркер в виде мы используемКод CSRF не работает

<?php 

session_start(); 
$token = md5(uniqid(rand(), TRUE)); 
$_SESSION['token'] = $token; 
$_SESSION['token_time'] = time(); 

?> 

<form action="buy.php" method="POST"> 
<input type="hidden" name="token" value="<?php echo $token; ?>" /> 
<p> 
Item: 
<select name="item"> 
    <option name="pen">pen</option> 
    <option name="pencil">pencil</option> 
</select><br /> 
Quantity: <input type="text" name="quantity" /><br /> 
<input type="submit" value="Buy" /> 
</p> 
</form> 

и маркер можно проверить с помощью простого условного оператора.

<?php 

if (isset($_SESSION['token']) && $_POST['token']== $_SESSION['token']) 
    { 
     echo $_POST['token']; 
     echo "form passed"; 
    } 

Но приведенный выше код не работает. Сообщение «form прошло» не отображается. Что не так с приведенным выше кодом ?. Первый набор кодов генерирует токен, но сообщение об успехе отсутствует.

ответ

0

Вам необходимо добавить session_start(); верху этого кода в buy.php. Пример ...

session_start(); 
if (isset($_SESSION['token']) && $_POST['token']== $_SESSION['token']) 
{ 
    echo $_POST['token']; 
    echo "form passed"; 
} 
+0

спасибо. Это сработало. Интересно, почему они публикуют книги с такой большой ошибкой. Еще раз спасибо. – 2014-09-20 16:43:24

+0

@ManishB Добро пожаловать! – MH2K9

0

Я предлагаю вам сделать это в функции эффективным образом:

session_start(); 
function generate_token(){ 
    $token = uniqid(rand(), true); 
    $_SESSION['token'] = $token; 
    $_SESSION['token_time'] = time(); 
} 


//avoid putting script at bottom until required 
if($_SERVER['REQUEST_METHOD']=='POST' && !empty($_POST)){ 
if(isset($_SESSION['token']) && isset($_SESSION['token_time']) && 
isset($_POST['token'])) 
    { 

if($_SESSION['token'] == $_POST['token']) 
{ 

    $timestamp_ancien = time() - (15*60); 
    //Si le jeton n'est pas expiré 
    if($_SESSION['token_time'] >= $timestamp_ancien) 
    { 
     //here Instruction 
     generate_token();//for next call 


    }else{echo"error3";} 
    }else{echo"error2";} 
    }else{echo"error1";} 
} 
generate_token(); 

Причина: вы можете поместить эту функцию в любом месте общего в проекте и включают или требуют файл использовать этот код, не записывая его где угодно.

Смежные вопросы