Надеюсь, этот вопрос не слишком неопределенный, так что …
Мой вопрос заключается в том, когда я должен обращать внимание на то, как я обращаюсь с уязвимыми переменными, а когда нет. Например. очевидно, небезопасно использовать что-то вроде …
echo $_POST['username']; // insecure !!!
в вашем шаблоне. Переменные $ _GET и $ _SERVER также считаются уязвимыми. Поэтому мне придется их продезинфицировать, прежде чем «использовать». Но что значит «использовать» в этом контексте. Небезопасно будет, например, вывести их, например, с echo
, чтобы записать их нефильтрованные в БД или положить их в любой другой открыть контекст. С другой стороны, сравнивая их с другими переменными, как в …
if ($_SESSION['username'] === $_POST['username']) {};
или встраивая их в переменную, как …
$file = 'http://www.example.com/users/' . $_POST['username']; // insecure !!! see Tom's answer
а затем проверка …
if (file_exists($file)) {};
…, другими словами, сохраняя их как-то закрыто контекст безопасен, не так ли? (Мне кажется, что $ file-example может рассматриваться как пограничный с точки зрения безопасности, но при таком использовании, я думаю, это нормально?). Может быть, кто-то знает также о случаях, в которых различие между открыть а также закрыто контекст не так ясен (как я надеюсь, они есть в моих примерах), чтобы обратить на них внимание.
Спасибо
Это зависит от того, что вы собираетесь делать с этим файлом. username
Поле может передавать что-то, что указывало бы на файл не на этом сайте, например:
$_POST['username'] = '@not-the-site-you-want.com/bad_stuff.html';
$file = 'http://www.example.com' . $_POST['username'];
Будет разрешать http://not-the-site-you-want.com/bad_stuff.html
и все еще вернет истину для file_exists($file);
,
Давайте попробуем «реальный мир» пример того, почему вы не хотите просто вводить $_POST
переменные, а затем доверять результатам.
Допустим, мы собираемся получить изображение пользователя из онлайн-источника (например, такого: http://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50) и хранить его локально:
$username = $_POST['username'];
// We expect 'hash' to contain '/avatar/205e460b479e2e5b48aec07710c08d50'
// See @SilverlightFox's comments below for more information.
$image = 'http://www.gravatar.com' . $_POST['hash'];
if (file_exists($file)) {
// Now we have the image stored on our local system
copy($image, 'assets/' . $username);
}
Пользователь предоставляет следующую информацию:
$_POST['username'] = 'shell_script.php';
$_POST['hash'] = '@badwebsite.com/shell_script.txt';
Вы только что загрузили на свой веб-сайт скрипт оболочки, который будет доступен по адресу http://www.mywebsite.com/assets/shell_script.php
Половина безопасности — это знание основ и введение ограничений. Другая половина выясняет, как кто-то может обойти ограничения, которые вы наложили. Ваш код может быть невосприимчив к SQL-инъекциям и XSS, но если вы пропустите is_admin
пометьте в качестве параметра в каждом запросе страницы и соблюдайте его, тогда кто-то найдет его и злоупотребит им.
Вы должны иметь привычку всегда предполагать, что что-то злонамеренное будет применено к коду, который вы пишете, если оно открыто миру. Если вы будете беспокоиться о том, какие входные данные вам нужно дезинфицировать, а какие нет, вы будете делать ошибки, которые делают ваше приложение уязвимым.
Санирование входных данных не займет столько усилий, как только вы научитесь, и если вы привыкнете делать это, вы уменьшите область воздействия, на которую можно нападать. Безопасность приложения заключается не только в «исправлении важных вещей», но и в создании всего приложения с учетом безопасности.
Не облегчайте работу плохим людям.