Предотвращение инъекций JavaScript в веб-приложении PHP

какие меры необходимы для предотвращения или остановки инъекций JavaScript в веб-приложении PHP, чтобы конфиденциальная информация не выдавалась (лучшие практики в PHP, HTML / XHTML и JavaScript)?

4 ответов


хорошим первым шагом является применение методов, перечисленных в вопрос Герт G связан. Это подробно охватывает различные функции, которые могут быть использованы в различных ситуациях для очистки ввода, в том числе mysql_real_escape_string, htmlentities(), htmlspecialchars(), strip_tags() и addslashes()

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

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

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

вы также можете использовать параметризованные запросы (он же подготовленные операторы с переменными bind) для ваших взаимодействий sql, где это возможно. Это скажет вашему серверу баз данных, что все входные данные-это просто значение, поэтому он смягчает многие потенциальные проблемы от инъекционных атак. Во многих ситуациях это может даже охватывать приложения в свободной форме.


обработайте любое значение, которое вы выводите в html с помощью htmlspecialchars () by по умолчанию.

единственное оправдание для не использования htmlspecialchars () - это когда вам нужно вывести в html строку, которая сама содержит html. В этом случае вы должны быть уверены, что эта строка является полностью безопасным источником. Если у вас нет такой уверенности, вы должны передать ее через html-фильтр белого списка, который позволяет только для тщательно ограниченного набора тегов, атрибутов и значение атрибута. Вы должны быть особенно осторожны со значениями атрибутов. Вы никогда не должны позволять всему проходить как значение атрибута, особенно для таких атрибутов, как src, hef, style.

вы должны знать все места в вашем веб-приложении, где вы выводите что-либо в html без использования htmspeciachars(), убедитесь, что вам действительно нужны эти места и помните, что, несмотря на всю вашу уверенность, эти места являются потенциальными уязвимостями.

Если вы думаете, что это слишком большая осторожность: "почему мне нужно htmlspecialchar() эта переменная, которую я знаю, содержит только целое число и потерять все драгоценные циклы процессора?"

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

также никогда не используйте фильтры HTML черного списка. Youtube сделал эту ошибку, и кто-то вдруг узнал, что только первый <script> удаляется, и если вы введете второй в комментарии, Вы можете ввести любой Javascript в браузер посетителей.

аналогично, чтобы избежать SQL-инъекций, обработайте mysql_real_escape_string () все значения, которые вы клеите к SQL-запросу, или еще лучше используйте подготовленные PDO операторы.


Если вы не передаете ничего, что должно быть сформировано как html, используйте:

strip_tags() <- Eliminates any suspicious html

а затем выполните следующие действия для очистки перед сохранением в db

mysql_real_escape_string() 

Если ваш ajax сохраняет введенный пользователем html через текстовое поле или wysiwyg, посмотрите на использование HTMLPurifier чтобы удалить javascript, но разрешить HTML-теги.


Я не полностью согласен с другими ответами, поэтому я опубликую свои рекомендации.

рекомендуемая литература XSS_ (Cross_Site_Scripting)_Prevention_Cheat_Sheet

Ввод HTML: При отображении любого пользовательского контента он должен быть соответствующим образом очищен с помощью htmlspecialchars или htmlentities при указании ENT_QUOTES, если используется внутри одинарных кавычек. Я бы рекомендуется никогда не инкапсулировать в одинарные кавычки и всегда инкапсулировать атрибуты в двойные кавычки (не опускайте их). Это относится к таким вещам, как:

<input value="<?php echo htmlspecialchars($var); ?>" />
<textarea><?php echo htmlspecialchars($var); ?></textarea>
<p><?php echo htmlspecialchars($var); ?></p>
<img width="<?php echo htmlspecialchars($var); ?>" />

JavaScript Для Инъекций: Лучше всего (но не всегда практично) никогда не повторять пользовательский контент в событиях и javascript. Однако, если вы это сделаете, есть некоторые вещи, которые можно сделать, чтобы уменьшить риск. Только передайте целочисленные идентификаторы. Если вам требуется что-то вроде спецификатора типа, используйте белый список и / или условная проверка перед выводом. Возможно, принудительно перевести пользовательский контент на буквенно-цифровой только при необходимости;preg_replace("/[^A-Za-z0-9]/", '', $string); но будьте очень осторожны, что вы позволяете здесь. Включите контент только тогда, когда он инкапсулирован в кавычки, и обратите внимание, что htmlspecialchars/htmlentities не защищает вас здесь. Он будет интерпретироваться во время выполнения, даже если он был переведен в объекты html. Это относится к таким вещам, как:

<a href="www.stackoverlow.com/?id=<?php echo (int)$id; ?>">Click</a>
href, src, style, onClick, etc.

не Эхо любой пользовательский контент в других областях, таких как тело тегов скриптов и т. д., Если оно не было принудительно к int или другому очень ограниченному набору символов (если вы знаете, что делаете).

SQL-инъекций: Использовать подготовленные заявления, привязать к ним пользовательский контент и никогда напрямую не вставлять пользовательский контент в запрос. Я бы рекомендовал создать класс для подготовленных операторов с вспомогательными функциями для ваших различных основных типов операторов (и в то время как по теме, функционализируйте все ваши операторы баз данных). Если вы решили не использовать подготовленные операторы, используйте использования mysql_real_escape_string() или аналогичный (не addslashes ()). Проверьте содержимое, когда это возможно, перед хранением в базе данных, например, принудительная / проверка типа данных integer, условные проверки типов и т. д. Используйте правильные типы и длины столбцов базы данных. Помните, что основная цель здесь-предотвратить инъекцию sql, но вы также можете сделать защиту от инъекций html/javascript.

Другие Ресурсы Я сделал некоторые исследования в интернете в надежде найти простое решение уже общедоступной. Я нашел OWASP ESAPI, но он кажется довольно устаревшим. Ссылки на версию php разбиты в нескольких местах. Кажется, я нашел его здесь.--36-->ESAPI PHP но опять же это довольно старый и не так просто, как я надеялся. Однако вы можете найти это полезным.

В целом, никогда не предполагайте, что вы защищены, например, с помощью htmlentities в атрибуте onClick. Вы должны использовать правильный инструмент в правильном месте и не делать вещи в неправильном месте.