БлогNot. Как защититься от обращения к файлу минуя HTML-форму?

Как защититься от обращения к файлу минуя HTML-форму?

Всё тот же вечный вопрос :) И корректный ответ - один. Капча. Всё остальное можно подделать программно, в том числе, любые данные, передаваемые по открытому протоколу HTTP.

Показанный ниже код source.php генерирует действительно маленькую капчу (нужна включённая GDLib на сервере, см. по ссылке), сохраняет её код в сессии, а потом передаёт файлу-приёмнику destination.php. При этом используется "библиотечный" файл img.php, который, собственно, и генерирует картинку.

Файл source.php
<?php
  $alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; //символы для капчи
  $secret = ""; //ключ для капчи
  for($i=0;$i<5;$i++) $secret.= $alpha[rand(0,strlen($alpha)-1)];  //Делаем 5 символов капчи
  session_id(md5(microtime()*rand()));  //и новый случайный SESSIONID
  session_start(); //Запускаем сессию
  $_SESSION['secret'] = $secret;   //и сохраняем в ней ключ капчи
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
 <meta content="text/html; charset=Windows-1251" http-equiv="content-type">
 <title>Отправка формы с капчей для проверка источника</title>
</head>
 <body>
   <form action="destination.php" method="post"> 
    <p>Имя : <input type="text" name="name"> </p>
    <p>Пароль : <input type="text" name="pass"> </p>
    <p>Число на картинке : <input type="text" name="secret"> </p>
    <p><input type="submit" name="send" value="Отправить"> </p>
   </form> 
   <img src="img.php?sid=<?php echo session_id()?>">
 </body>
</html>
Файл destination.php
<?php
 session_start(); 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
 <meta content="text/html; charset=Windows-1251" http-equiv="content-type">
 <title>Приём формы с проверкой источника</title>
</head>
<body>

<?php
 if (strtoupper($_POST['secret']) == $_SESSION['secret']) { 
    echo '<p>Имя = '.$_POST['name'].
         '<br>Пароль = '.$_POST['pass'].'</p>'; 
 } 
 else { 
  echo '<p>Неверный источник данных или неправильный ввод числа на картинке</p>';
 } 
?> 

</body></html>
Файл img.php
<?php
 session_id($_GET['sid']); //Запуск сессии с полученным SESSIONID 
 session_start(); 
 $img = imagecreate(88,31); //Пустая картинка указанного размера
 imageColorAllocate($img,204,204,204); //Фон картинки
 $color2 = imageColorAllocate($img,0,0,0); //Цвет линий
 imageline($img,10,0,87,31,$color2); //Дополнительные линии, чтоб затруднить автораспознавание
 imageline($img,0,20,60,0,$color2); 
 imageline($img,40,31,87,11,$color2); 
 imageline($img,0,31,87,0,$color2); 
 $color = imageColorAllocate($img,0,128,0); //Цвет букв
 imagestring ($img,6,15,8,$_SESSION['secret'],$color); //Вывод текста
 imageGif($img); //Показать картинку
 header("Content-Type: image/gif"); //и вернуть нужный тип контента
?>

Так как в мире нет ничего совершенного, это тоже может не работать - например, если у юзера выключены Cookie, а с ними вместе и сессии.

А в остальном код проверен и работает :)

26.09.2014, 14:10 [9804 просмотра]


теги: php безопасность

К этой статье пока нет комментариев, Ваш будет первым