Является ли этот метод хорошим / безопасным для отображения ошибок пользователям? - PHP - PullRequest
2 голосов
/ 19 февраля 2009

Я занимаюсь разработкой веб-сайта, и из-за ввода данных пользователем или по другой причине мне нужно показать некоторые сообщения об ошибках. Для этого у меня есть страница с именем error.php , и я получаю номер ошибки, используя $ _GET. Все сообщения об ошибках хранятся в массиве.

Пример:

header( 'Location: error.php?n=11' ); 

Но я не хочу, чтобы пользователи вводили код ошибки в URL и видели все другие сообщения об ошибках. Чтобы предотвратить это, я подумал, что могу внести в белый список страницу реферера и отображать сообщение об ошибке только в том случае, если реферер найден в моем белом списке.

Это должно быть примерно так (еще не проверял;))

$accept = false;
$allowedReferer = array (0=>'page1.php', 'page2.php');
if (in_array($_SERVER['HTTP_REFERER'], $allowedReferer )) {$accept = true;}
if ($accept) { $n=$_GET['n'];echo "Error: " . $errorList[$n];}

Достаточно ли хорош этот метод, чтобы избежать пользователей-шпионов ?

Я делаю это с PHP5

Спасибо

Ответы [ 7 ]

8 голосов
/ 19 февраля 2009

Нет, он не защищен удаленно: заголовок HTTP Referer тривиален для подмены и также не является обязательным заголовком. Я предлагаю вам прочитать эту статью для примера использования кода (написанного на PHP) или загрузить это дополнение для Firefox, чтобы сделать это самостоятельно, не выходя из собственного браузера.

Кроме того, ваш массив $allowedReferer должен содержать полные URL-адреса, а не только имя скрипта, в противном случае код также будет доступен для удаленных ссылок, например, от

http://www.example.org/page1.php

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

5 голосов
/ 19 февраля 2009

Вместо перенаправления вы можете просто отобразить ошибку «на месте» - например, что-то такое простое, как адаптация вашего нынешнего кода с чем-то вроде

if ($error_condition)
{
    $_GET['n']=11;
    include "/path/to/error.php";
    exit;
}

На практике это может быть немного сложнее, но идея та же - пользователю выдается сообщение об ошибке без перенаправления. Убедитесь, что вы выводите какой-то заголовок ошибки, например заголовок («HTTP / 1.0 401 Bad Request»), чтобы сообщить браузеру, что он не видит запрошенную страницу.

Если вы хотите перенаправить, вы можете создать защищенный от несанкционированного доступа URL-адрес, включив в него хэш номера ошибки с солью, известной только вашему коду, например

$n=11;
$secret="foobar";
$hash=md5($n.$secret);
$url="http://{$_SERVER['HTTP_HOST']}/error.php?n={$n}&hash={$hash}";

Теперь ваш error.php может проверить, правильно ли был создан предоставленный хэш. Если это так, то, по всей вероятности, он был создан вашим кодом, а не пользователем.

4 голосов
/ 19 февраля 2009

Вы не должны использовать внешнее перенаправление, чтобы попасть на страницу с ошибкой. Как я структурирую свой PHP так:

У меня есть общий файл, включенный в каждую страницу, с общими функциями: обработка входа / выхода из системы, настройка констант и тому подобное. При наличии функции error () вы можете передать информацию об ошибке, которая покажет страницу с ошибкой и завершится. Альтернатива - использовать идиому index.php? Include = pagename.php для достижения общей функциональности, но я считаю, что это гораздо более странно и подвержено ошибкам.

Если вы перенаправляете клиента извне (что вам, очевидно, иногда требуется), никогда не полагайтесь на информацию, переданную через этот механизм. Как и любой пользовательский ввод, он по своей сути ненадежен и должен подвергаться санитарной обработке и лечению с особой осторожностью. Также не используйте куки (та же проблема). Используйте сеансы, если вам нужно сохранить информацию между запросами.

1 голос
/ 19 февраля 2009

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

if ($error) {
    ob_clear();
    $errorCode = 11;
    include 'error.php';
    exit;
}
1 голос
/ 19 февраля 2009

HTTP_REFERER могут быть подделаны тривиально теми, у кого достаточно стимулов (telnet - это инструмент выбора там), и им нельзя доверять.

Сообщения об ошибках никогда не должны раскрывать что-либо критическое, поэтому я бы посоветовал вам спроектировать свои сообщения об ошибках таким образом, чтобы их можно было показывать кому угодно.

Это или использовать случайные хеш-коды для выявления ошибок (вместо 11, используйте 98d1ud109j2 и т. Д.), Которые будут храниться в центральном месте в ассоциативном массиве где-то:

$errors[A_VERY_FATAL_ERROR] => "308dj10ijd"
0 голосов
/ 19 февраля 2009

Если вы обрабатываете ошибки перед отправкой заголовков, вы можете легко создать функцию, которая выводит базовую html-страницу с содержимым и выходит сразу после нее. Таким образом, нет никакой особой необходимости в какой-либо другой странице (кроме страницы функций, я думаю).

Это так же просто, как проверить, есть ли проблема, и если есть проблема, просто вызовите функцию.

Я использую такую ​​функцию, которая даже записывает данные при ее вызове, поэтому у меня есть собственные журналы ошибок ...

0 голосов
/ 19 февраля 2009

Вместо перенаправления на страницу с ошибкой, почему бы не включить страницу с ошибкой. Вы можете ограничить доступ к каталогу, содержащему php-файлы, содержащие содержимое ошибки, с помощью .htaccess:

RedirectMatch 404 ^error-pages/*$

и внутри страниц ошибок вы можете иметь включаемые страницы, которые отображают ошибки.

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

...