CSRF на търсачка

pro12

Registered
Добавил съм CSRF токен към формата на търсачката най отгоре във всяка стр имам.
PHP:
<head>
       <?php     use Lib\Csrftoken; //get token
       $token = new Csrftoken(); 
       var_dump($_SESSION['toksearch']);
      ?>
Формата на търсачката
HTML:
<form action="/search" method="GET" name="searchf">
               <input type="text" id="searchpole" size="15" maxlength="25" name="search">
               <br/><input type="hidden" name="tokens" value="<?php  echo $token->searchtoken(); ?>">
            <input type="submit" name="searchf" id="btnsearch" value="search" />

            </form>
Така проверявам токена
PHP:
if (isset( $_GET['searchf'] )  ) {
		     $searchdata['search'] = $_GET['search'];
                   $token = $_GET['tokens']; 
            

              if(isset($_SESSION['toksearch']) && $token === $_SESSION['toksearch']) {
                  echo 'ok'; } else {
                        echo  'try again';
                      }
Когато имам най отгоре във всяка стр
PHP:
       var_dump($_SESSION['toksearch']);
всичко е ок, но като махна
PHP:
       var_dump($_SESSION['toksearch']);
дава try again. Някаква идея да имате?
 
Fakeheal каза:
Офтопик (може би), но не ти трябва csrf защита на GET request.
Ти ще го кажеш офтопик, но аз ще го кажа направо. Като цяло не му е нужен CSRF token особено пък така структуриран... Толкова е лесно да е заобиколи значението му, че направо е излишен. Ако ме питате защо и как просто си представете че влизам в страницата сканирам изходният код вадя си го, чрез регулярен израз и го пращам директно към сървъра със следващата заявка... И каква е файдата от тази защита? Никаква... Вижте CAPTCHA е по-различно нещо. Четох другата тема, но тя много се разводни и не пожелах да опиша защо е излишен особено структуриран по този начин, който е в примера.
Не виждам тук да имаш поставен session_start();
PHP:
session_start();

if (isset( $_GET['searchf'] )  ) {
                     $searchdata['search'] = $_GET['search'];
                   $token = $_GET['tokens']; 
            

              if(isset($_SESSION['toksearch']) && $token === $_SESSION['toksearch']) {
                  echo 'ok'; } else {
                        echo  'try again';
                      }

Отделно би трябвало да проверяваш така:
$token == $_SESSION['toksearch']
не така:
$token === $_SESSION['toksearch']

PHP:
<?php
session_start();

if (isset( $_GET['searchf'] )  ) {
    $searchdata['search'] = $_GET['search'];
    $token = $_GET['tokens']; 
    if(isset($_SESSION['toksearch']) AND ($token == $_SESSION['toksearch'])) {
		echo 'ok'; 
	} else {
        echo  'try again';
    }  
}
 
Fakeheal каза:
Какъв е проблема на 3-те равнота?
Принципно никакъв не е проблема, но не го знам какво прави точно и може да се получава при него един частен случай. Ще ти го дефинирам с пример, че по-лесно ще ме разбереш:
PHP:
<?php
$one = 1;
$two = "1";

if ($one == $two) {
	print 'OK if 1';
}

if ($one === $two) {
	print 'OK if 2';
}
 
Е нали при всяка заявка са генерира нов токен и ако подадеш фалшива заявка тя ще бъде с токен по различен от записан в сесията. Имам и
PHP:
session_start();
А начин за защита от фалшиви заявки има ли по различен начин от моя?
PHP:
    if(isset($_SESSION['toksearch']) AND ($token == $_SESSION['toksearch'])) {
И така проблема си остава.
 
Той нека си се генерира нов ключ, проблема ти е в това, че какъвто и ключ да генерираш и запазиш в сесията за последващо сравняване аз ще го взема от странисата с парсване и ще го подам при структуриране на заявката ми от локалната машина и ще излъжа системата ти, че реално аз съм на страницата през браузъра ти и попълвам формата. И в предната тема имаше намек по въпроса, но не ти беше обяснено, а ти изцяло яхна вълната относно идеята ти да се защитиш. Използвай хубава CAPTCHA и ще решиш проблемите си.
 
@dakata__92
Това не е проблем, а е правило. Трите равнота освен стойностите проверява и типа данни.

Само, че той има стригн (идващ от гет) и сравнява със стойност в сесията (която пак е стринг).



@pro12
Отново казвам, няма нужда да подаваш csrf токен за GET заявка.

Относно проблема, може ли да пуснеш кода, който генерира токен-а и го записва в сесията. Според мен си го сложил преди кода, в който проверяваш токена от гет (който е от предното сетване).

Ако аз ползвам търсачката ти и искам да споделя резултата с приятел (копирам линка) и му го пратя. Той няма да може да го отвори, защото токена е expire-нал :)
 
dakata__92 каза:
Той нека си се генерира нов ключ, проблема ти е в това, че какъвто и ключ да генерираш и запазиш в сесията за последващо сравняване аз ще го взема от странисата с парсване и ще го подам при структуриране на заявката ми от локалната машина и ще излъжа системата ти, че реално аз съм на страницата през браузъра ти и попълвам формата. И в предната тема имаше намек по въпроса, но не ти беше обяснено, а ти изцяло яхна вълната относно идеята ти да се защитиш. Използвай хубава CAPTCHA и ще решиш проблемите си.
Аз не съм писал др тема!!
 
Fakeheal каза:
Това не е проблем, а е правило. Трите равнота освен стойностите проверява и типа данни.

Само, че той има стригн (идващ от гет) и сравнява със стойност в сесията (която пак е стринг).
Знам, но пак повтарям, че не знам дали колегата с темата, има такова несъответствие. Ако проблема не е в операторите и частните им случаи, то идват последващите изводи. Или двата стринга не са равни (да принтира $_SESSION['toksearch'] и $token) преди да прави проверките, за да види сам дали са еднакви, или сесията не съдържа нищо.
 
dakata__92 каза:

Просто исках да кажа, че няма смисъл да предлагаш нещо, което не е много от помощ. Без дори да обясниш каква е разлиакта. Тук сме да се учим.

Иначе чисто логически погледнато. Щом токена е успял да го подаде на URL (и го взима с $_GET) е стринг.

Ако го е подал на страницата, която е сложила URL-a, значи е стринг.

Автоматично изключваме проблем в операторите за сравнение.

Поне това е моя начин на мислене.
 
<form action="/search" method="GET" name="searchf">
<input type="submit" name="searchf" id="btnsearch" value="search" />

Две структури с едно име...
 
И двата стринга имат различни стоиности. Но щом е безсмислена защитата я махам.
 
Fakeheal каза:
dakata__92 каза:

Просто исках да кажа, че няма смисъл да предлагаш нещо, което не е много от помощ. Без дори да обясниш каква е разлиакта. Тук сме да се учим.

Иначе чисто логически погледнато. Щом токена е успял да го подаде на URL (и го взима с $_GET) е стринг.

Ако го е подал на страницата, която е сложила URL-a, значи е стринг.

Автоматично изключваме проблем в операторите за сравнение.

Поне това е моя начин на мислене.

За трети път ще визирам, че нашият начин на мислене е различен. Самият му код не е структуриран правилно (поне от към имена на променливите и масивите) и се поставям на негово място. Той ако пробва нещата, които му давам като информация и ми върне отговор ще получи и обяснение какъв е проблема му. Това дали е стринг или не, няма как да знаем защото, ако GET му е стринг, то не се знае дали пък сесията не му е била число, примерно. Така, че не е нужно да се хващаш за това, че не съм му обяснил в дълбочина, защо му предложих да пробва различен оператор, защото реално исках просто да отметна този казус като причина. Тръгвам от проблема. Щом това условие не отговаря и не влиза в него, търся защо с най-простите средства и след това с по-завързаните неща. Не е нужно да го насмитаме излишно, поне в началото.
 
dakata__92 каза:
<form action="/search" method="GET" name="searchf">
<input type="submit" name="searchf" id="btnsearch" value="search" />

Две структури с едно име...
Това грешно ли е?
 
Fakeheal каза:
dakata__92 каза:
<form action="/search" method="GET" name="searchf">
<input type="submit" name="searchf" id="btnsearch" value="search" />

Две структури с едно име...


name атрибута на форма не се подава в гета...
Пак ми е ясно, но това беше забележка към автора.

pro12 каза:
И двата стринга имат различни стоиности. Но щом е безсмислена защитата я махам.

Мое си е виждането, че няма файда от тази защита, поне в този и вид. Относно разликите, проблема ти вероятно е при генерирането и сетването на сесията в класът. Някъде си объркал логиката там. Не се вижда къде и как я презаписваш или унистожаваш. Ако все пак искаш да си ползваш тази защита драсни и кода на класът тук.
 
pro12 каза:
dakata__92 каза:
<form action="/search" method="GET" name="searchf">
<input type="submit" name="searchf" id="btnsearch" value="search" />

Две структури с едно име...
Това грешно ли е?
Може да доведе, до последващи обърквания след време ако ползваш парсъри и други неща примерно с визуализацията или някакъв последващ JS.
 
Това е класа
PHP:
class Csrftoken{
   
    public function generetetoken() {
        $token = md5(uniqid(rand(), true));
        return $token;
    }
    
  
    
    public function searchtoken() {//search token
        $token = $this->generetetoken();
         
        return $_SESSION['toksearch'] = $token;
         //
     
          
    }
}
 

Горе