Profruit banner

Умен звънец в openHAB

16 декември 2023

Телефонът е винаги с мен и сега, където и да се намирам получавам известие от openHAB, че някой е позвънил и чака пред вратата. А ако ме няма вкъщи става ясно часа и датата на последното позвъняване.

Tasmota Multipress

30 септември 2023

Идеята е Sonoff Touch T1 US 2 в салона, да управлява освен своето осветление и това в кухнята, а още вентилатора.

DIY 12V 1A WiFi Router UPS

22 април 2023

При поредно прекъсване на захранването вкъщи, батерията на нoтбука и двата UPS автоматично превключват на аварийно захранване и едновременно полита съобщение за конфуза

Zigbee2MQTT клониране

21 януари 2023

... как да клонираме съществуваща настройка на Zigbee2MQTT без да се налага последвало интервю на zigbee-устройствата.

LD2410 - бюджетен датчик присъствие в openHAB

11 февруари 2023

Цената на HLK-LD2410 зададе име на поредната тема в моя блог. С негова помощ се постига "народен" датчик присъствие в домашната автоматизация. . ...


Web-формата е входяща точка на вашето web-приложение. Там става взаимодействие между потребителите и вашия сайт. Те попълват полета и отправят информация. Наред с тях се нарежда и робота. В резултат предложения за ненужни неща, спам и т.н. Този процес у спамърите е автоматизиран. Те не ходят от сайт на сайт, да попълват форми на ръка , а създават скриптове, които вършат тази работа вместо тях. Противодействието от наша страна налага защита от автоматическо попълване.

Frank Borell - Wake Up In Paradise Dream Spirit Mix
Има много способи за бариера. Най-известен се явява CAPTCHA (абревиатура, означаваща автоматизиран тест за различаване на машина от човек). На практика това е картинка с размазан текст, който трябва да се различи и въведе в обособено поле.

Аз намирам CAPTCHA за непрактична. Идеята й е да отсява спам-бота, но същия успех тя постига сред доброжелателния потребител. Има CAPTCHA доведена до състояние на "разшифроване" и нещата се свеждат до гадаене, и проба-грешка. При неуспех, смятайте този потребител изгубен за каузата на вашия проект. По-важното е, че спамърите включиха в своята атака човешки ресурс - кликъри. За 1000 разпознати CAPTCHA те плащат по 1$. Индия и Китай са първенци в това отношение. Други спамъри пък предлагат безплатно порно, след като покажат същата CAPTCHA на порноманиаците. Изобретения, които занижават смисъла на CAPTCHA.

В този ред на мисли, реших да споделя начин за проста CAPTCHA, която се базира на математически израз. Колко прави 2 + 3. Правилен отговор и формата събмитната.

Алгоритъмът на подобна реализация е прост. Генериране на две числа в диапазон от 0 до 10. Съхраняване в сесионна-променлива резултата от техния сбор. При отправяне на данните от потребителя сравняване на резултатите - съхранения и потребителския. При съвпадение - имаме човек, иначе не издържана проверка и генерация на нови две числа с предложение за нова проба.

Очакваната критика е, че възможните комбинации от сбора на две числа в подобен диапазон е много малък. Висшата математика разглежда този въпрос в раздели комбинаторика и теория на вероятностите.

Да, малък е. Съгласете се, че предложението за смятане на двуцифрени числа затруднява потребителя, особено трицифрени и нагоре. Тогава позволете да насоча мислите в друга посока.

Потребителят винаги първоначално посещава страницата с HTML-форма, а после бива пренасочен към обработчика й, намиращ се на адрес различен от Web-формата. Общото в два случая е един и същи IP, и един и същи user agent (браузър). Роботите не спазват това правило. Те сканират страницата и се насочват към целевата страница указана в action="" на формата. Защо да не впрегнем тази особеност? Конкретно за нашата форма, Spambot е длъжен да ползва един и същи IP и агент ID при сканиране, и атака.

В скрито поле слагам хеш от IP адреса уловен при зареждане на Web-формата. Събмита на формата изпраща това значение, а на страницата на обработчика подлагам на сравнение. Друга идея е да се добави мним Input, който да бъде скрит от CSS (display:none;). Потребителят няма да вижда това поле, докато робота ще се опита да го запълни. Съдържанието му проверяваме с функция empty(). А още, да се зададе задължителен интервал от време. На човек му е нужно време да осмисли и запълни формата, преди да я изпрати, докато робота атакува веднага.

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

Обратна връзка

1 + 1 =



В крак с времето впрегнах новостите на HTML5. За да ги усетите, трябва да сте с браузър различен от IE.

Web-формата e изложена с учебна цел. Спартански вид, без стилове. Тя никъде не води и подписването й ще презарежда страницата на блога ми. Не се заигравайте с бутон "Юруш". Кой не е гледал екшън филма "Юруш на маслините", значи никога не е мечтал за двукасетъчен магнетофон.

Претендирам полетата да съдържат миниум два символа. Името ограничавам до 32 символа, а текста до 2048. Едва ли желаете, да получавате фермани и супер-дупер имена. При успех пращам данните на електронната си поща. Без JavaScript. Истинската проверка винаги на страна на сървъра извършвайте. JavaScript като помощно средство, като съветник и ни повече.

Код на формата
<?php
session_start();

 $a = rand(0,9);
 $b = rand(0,9);
 $_SESSION['res'] = $a + $b;
 $_SESSION['adrress'] = $_SERVER['PHP_SELF'];
 $_SESSION['agent'] = $_SERVER['HTTP_USER_AGENT'];
 $ip = md5($_SERVER['REMOTE_ADDR']);
?>

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>ProCapcha</title>
 
</head>
 <body>

 <form action="processor.php" method="POST">
 <fieldset><legend>Обратна връзка</legend>
  <p><label>Потребител <input type="text" name="name" size="17"  placeholder="Вашето име"></label></p>
  <p><label>Коментар <textarea name="comment" rows="10" placeholder="Напишете коментар"></textarea></label></p>
  <p><?php echo $a. ' + ' .$b.' = ';?><input type="text" name="res" size="1" maxlength="2" placeholder="?" required></p>
  <p><input type="submit" name="submit" value="Юруш"> <input type="reset" value="Изчисти"></p>
  <input type="hidden" name="tracker" value="<?= $ip ?>">
 <?php
  echo $_SESSION['mes'];
  unset($_SESSION['mes']);
 ?>
 </fieldset>
 </form>
  
 </body>
</html>

Генерацията на две числа присвоявам на съответни променливи, а техния сбор на сесионна променлива $_SESSION['res'].

Елемент $_SERVER['PHP_SELF'] съдържа името на скрипта, отчитайки корневата директория на хоста, Като правило, това е част от друг фрагмент $_SERVER['SCRIPT_NAME']. Ползата от него, е че името на скрипта търпи произволна смяна при бъдещи манипулации. Не хардкодвам името на скрипта. Присвоявам го на поредна сесионна променлива.

С $_SERVER['HTTP_USER_AGENT'] засичам браузъра на госта. Идеята описана горе, а съдържанието на $_SERVER['REMOTE_ADDR'] хеширам, за да го предам на скритото поле на формата.

Следва Web-формата в стил HTML5, като в тялото й добавям място за извеждане на съобщения, който биват в последствие анихилирани.

Просто като боб!

Код на обработчика
<?php
session_start();
header ('Content-type:text/html;charset=utf-8');

if($_POST['track'] == md5($_SERVER['REMOTE_ADDR'])){

 if($_SESSION['agent'] == $_SERVER['HTTP_USER_AGENT']){
 
 if((int)trim($_POST['res']) == $_SESSION['res']){
  
 $name = trim($_POST['name']);
 $comment = trim($_POST['comment']);
 
 if((mb_strlen($name, 'utf-8') > 2) && (mb_strlen($comment, 'utf-8') > 2)) {
   $name = mb_substr($name, 0, 32, 'utf-8');
   $comment = mb_substr($comment, 0, 2048, 'utf-8');
 }
 else {
  $_SESSION['mes'] = '<p>Моля, запълнете формата!</p>';
  header("Location: {$_SESSION['adrress']}");
  exit;
  }

 $to = 'profruit@abv.bg';//вашия e-mail адрес
 $subject = 'Коментар от сайта';// заглавие на писмото
 $body = $comment;//тяло
 $headers = 'From:'.$name.' <you@example.com>' . "\n";
 $headers .= 'Content-type:text/plain; Charset=utf-8';
  
  if(mail($to, $subject, $body, $headers)){
   $_SESSION['mes'] = '<p>Писмото изпратено!</p>';
   header("Location: {$_SESSION['adrress']}");
   exit;
  }
  else{
   $_SESSION['mes'] = '<p>Моля, опитайте пак по-късно!</p>';
   header("Location: {$_SESSION['adrress']}");
   exit;
  }
 }
 else{
   $_SESSION['mes'] = '<p>Въведен грешен отговор!</p>';
   header("Location: {$_SESSION['adrress']}");
   exit;
  }
 }
 else{
   exit('Huston, You have a problem!');
  }
}
else if(!empty($_SESSION['adrress'])){
  header("Location: {$_SESSION['adrress']}");
  exit;
 }
else{
 exit('Huston, You have a problem!');
 }

Потребителят попълва формата и натиска юруш, а това стартира анализа. Първата проверка сравнява IP-тата. При разногласие, плюем съобщение "Huston, You have a problem!".

Има маргинали, които гледат изходния код и подобно на роботите се обръщат към адреса на обработчика. Ако има сесия го пренасочваме обратно към формата. Ако няма сесия и него плюем с "Huston, You have a problem!".

Втората проверка сравнява версията браузъри. Няма равно, пак плюем "Huston, You have a problem!".

Ако до тук е издържано, сравняваме какво получаваме от пресмятането. При неуспех пренасочваме към формата. Всичко започва отначало, като старите променливи се презаписват от само себе си. При успех обработваме информацията. Режем празни символи и сравняваме дължини. Обработката присвояваме на променливи, които предаваме като параметър на функция mail(). Подготовка за писмо един вид. При неуспех с дължините връщаме на изходна позиция.

Функция mail() в моята система Ubuntu 10.04 се обслужва от пощенски трансферен агент Exim4. Той предава на smpt сървър на Google, а от там на посочен от мен електронен адрес. Неща описани в тази тема. Удобно и практично.

При успех/неуспех вадим съобщения и връщаме обратно към формата.

Резултатът няма да влиза в база данни и това обезсмисля функции: addslashes(), mysql_real_escape_string(). Под въпрос е функция htmlspecialchars(). Сървърите обработват спецсимволи, с цел да не допуснат тъпи шеги с писма, съдържащи JS-код. Тук най-вече според случая.

неуспешен опит

успешен опит

На печелившите честито. На мен браво!





до нови срещи   ^.^

19.11.2011 profruit 

|

0 Response to "Captcha за Web-форма"

Публикуване на коментар

Този блог е реинкарнация на първите ми опити за споделяне в нета. На времето започнах с къси разкази на преживяното. После се обезсмисли и превърнах блога си в системно радио. Пиша единствено неща, които карат душата ми да живее: openHAB, Ubuntu, Споделено и т.н. Това е моето системно радио, разбирате ли? Моята вълна и вие сте на нея сега.

Архив на блога