Защита ссылок на php

Защита ссылок от множества одновременных кликов

А теперь проблема: если нажать на ссылку 1 раз а затем еще 100 раз пока загружается страница, то и ссылка сработает 100 раз, не успев удалить себя из БД. Кто что расскажет вообще о способах защиты против этого?

P.S. Был очень удивлен, зайдя на привычный мне хешкод и увидевши перед собой менее привычный стековерфлоу с поддоменом ru. 😀

Предусмотреть эту ситуацию с серверной стороны. — вот ответ. Все щепетильные моменты всегда должны обрабатываться на бэк-энде.

1 ответ 1

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

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

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.7.27.43548

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Источник

Защита от XSS в PHP

XSS — это когда злоумышленник пытается через формы на сайте (обратная связь, оформление заказа и т.п.) добавить свой javascript-код, который затем выполнится в браузере админа/менеджера сайта или других пользователей и натворит дел.

Как это работает

Возьмём простую форму обратной связи. 2 поля для заполнения и кнопка отправки.

 

Заголовок:

Текст:

Добавим к этой форме PHP обработчик, который просто выводит заголовок и текст на экран:

'; echo 'Текст: ', $_POST['content']; > ?> 

Заголовок:

Текст:

Прекрасно. Код работает, введённый текст выводится над формой.

А теперь вместо текста введём какой-нибудь javascript код, например .

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

Чем опасна XSS

Внедрив свой скрипт, злоумышленник получает доступ ко всей html-странице, может её читать и менять как угодно.

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

Таким образом, он может войти на сайт под чужой учётной записью без логина и пароля. Разумеется, только если на сайте нет других проверок: на соответствие браузера, IP-адреса и т.д., хотя при желании их можно подделать.

Как защититься от XSS

К нашему огромному счастью, есть простой универсальный инструмент — функция htmlspecialchars() или её иногда применяемый аналог htmlentities() .

Как это работает. В HTML есть такая штука как сущности или мнемоники. Это когда я пишу прямо в HTML определённую последовательность символов, например © , а браузер отображает соответствующий этой мнемонике символ, в данном случае значок копирайта ©.

 
Абзац ¶
Перевёрнутый знак вопроса ¿
Знак умножения (крестик) ×
Стрелка влево ←
Типографский крестик †

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

Т.е. когда мы введём в нашу форму текст , функция htmlspecialchars() превратит его в <script>alert(‘hello’)</script> . Разумеется, браузер уже не воспримет такой код как javascript и просто выведет на экран как есть.

'; echo 'Текст: ', htmlspecialchars($_POST['content'], ENT_QUOTES, 'UTF-8'); > ?> 

Заголовок:

Текст:

Теперь какой бы javascript код мы не пытались подставить, он будет просто выводиться в браузер как строка.

Когда лучше обрабатывать строку

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

У обработки до записи в базу есть несколько недостатков:

  • Мы не можем узнать реальную длину строки, поскольку ООО «Три кота» — это 14 символов, но ООО "Три кота" — уже 24 символа.
  • Помимо HTML данные из базы иногда нужно подставлять куда-то ещё, например в word/excel/pdf файлы, где может не быть никаких мнемоник. Придётся декодировать все данные в исходный вид.

В общем, неудобно это. Рекомендую всегда сохранять в базу исходный текст, который ввёл пользователь, а обрабатывать уже при выводе на экран.

Как упростить обработку строк

И что, каждый раз теперь писать эту длиннющую функцию?

Ну нет, спасибо. Лучше напишем отдельную функцию под это дело:

Можно заменить return сразу на echo, не принципиально. Теперь обрабатывать строки гораздо проще:

if(isset($_POST['form'])) < echo 'Заголовок: ', e($_POST['title']), '
'; echo 'Текст: ', e($_POST['content']); >

Если ты слышал про шаблонизаторы вроде Twig или Blade, там специально используется свой синтаксис вывода переменных, чтобы они по-умолчанию всегда обрабатывались:

Источник

Лучшие практики и рекомендации по защите php-приложений от XSS-атак

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

Большинство уязвимостей связано с неправильной обработкой данных, получаемых извне, или недостаточно строгой их проверкой. Одной из таких уязвимостей является межсайтовое выполнение сценариев (Сross Site Sсriрting, XSS), которая может привести к дефейсу сайта, перенаправлению пользователя на зараженный ресурс, вставке в веб-ресурс вредоносного кода, краже COOKIE-файлов, сессии и прочей информации. Противостоять XSS своими сила поможет применение лучших практик и рекомендаций по безопасному программированию, о которых и пойдет речь ниже.

Лучшие практики и рекомендации:

1. Используйте экранирование входных\выходных данных. Применяйте встроенные функции для очистки кода от вредоносных скриптов. К ним относятся такие функции как htmlspecialchar(), htmlentities() и strip_tags().
Примеры использования:

$name = strip_tags($_POST['name']); $name = htmlentities($_POST['name'], ENT_QUOTES, "UTF-8"); $name = htmlspecialchars($_POST['name'], ENT_QUOTES);

Встроенные функции PHP, в отличие от самописных, работают гораздо быстрее, а также имеют меньше ошибок безопасности и уязвимостей, т.к. постоянно совершенствуются. Также рекомендуется использовать специальные библиотеки, построенные на основе встроенных функций и фильтров. В качестве примера можно привести OWASP Enterprise Security API (ESAPI), HTML Purifier, Reform, ModSecurity.
Для того чтобы библиотека работала правильно, её нужно предварительно настроить!

2. Используйте подход «белые списки». Подход работает по принципу «что не разрешено, то запрещено». Это стандартный механизм валидации полей для проверки всех входных данных, включая заголовки, куки, строки запросов, скрытые поля, а также длина полей форм, их тип, синтаксис, допустимые символы и другие правила, прежде чем принять данные, которые будут сохраненные и отображены на сайте. Например, если в поле нужно указать фамилию, необходимо разрешить только буквы, дефис и пробелы. Если отклонить все остальное, то фамилия д’Арк будет отклонена — лучше отклонить достоверную информацию, чем принять вредоносные данные.
К сожалению, со своей задачей встроенные фильтры валидации данных PHP не справляются, поэтому рекомендуется писать собственные фильтры и «допиливать» их по мере необходимости. Таким образом, со временем ваши входные методы фильтрации будут усовершенствованы. Стоит также не забывать, что существует слишком много типов активного содержимого и способов кодирования для обхода подобных фильтров. По этой же причине не используйте проверку по «черному списку».

3. Указывайте кодировку на каждой веб-странице. Для каждой веб-страницы необходимо указывать кодировку (например, ISO-8859-1 или UTF-8) до каких-либо пользовательских полей.
Пример использования:

или в файле .htaccess веб-сервера Apache дописать строчку:

Если в http-заголовке или в метатегах кодировка не указана, браузер пытается сам определить кодировку страницы. Стандарт HTML 5 не рекомендует использовать такие кодировки, которые включают JIS_C6226-1983, JIS_X0212-1990, HZ-GB-2312, JOHAB (Windows code page 1361), а также кодировки, основанные на ISO-2022 и EBCDIC. Кроме того, веб-разработчики не должны использовать CESU-8, UTF-7, BOCU-1 и кодировки SCSU. Эти кодировки никогда не предназначались для веб-контента[1]. В случае если тег расположен до тега и заполняется пользовательскими данными, злоумышленник может вставить вредоносный html-код в кодировке UTF-7, обойдя, таким образом, фильтрацию таких символов, как ‘

4. Установить флаг HttpOnly. Этот Флаг делает клиентские куки недоступными через языки сценариев, такие как JavaScript.
Данная настройка активируется
— в php.ini [2]:

— в скрипте через функцию session_set_cookie_params() [3]:

void session_set_cookie_params ( int $lifetime [, string $path [, string $domain [, bool $secure = false [, bool $httponly = true ]]]] )

— в веб-приложении через функцию setcookie() [4]:

bool setcookie ( string $name [, string $value [, int $expire = 0 [, string $path [, string $domain [, bool $secure = false [, bool $httponly = true ]]]]]] )

Эта функция поддерживается последними версиями распространенных браузеров. Однако старые версии некоторых браузеров через XMLHttpRequest и другие мощные браузерные технологии обеспечивают доступ для чтения HTTP-заголовков, в том числе и заголовка Set-Cookie, в котором установлен флаг HttpOnly[5].

5. Использовать Content Security Policy (CSP). Это заголовок, который позволяет в явном виде объявить «белый список» источников, с которых можно подгружать различные данные, например, JS, CSS, изображения и пр. Даже если злоумышленнику удастся внедрить скрипт в веб-страницу, он не выполниться, если не будет соответствовать разрешенному списку источников.
Для того чтобы воспользоваться CSP, веб-приложение должно через HTTP-заголовок «Content-Security-Policy» посылать политику браузеру.
Пример использования:

Content-Security-Policy: default-src 'self'; script-src trustedscripts.example.com style-src 'self' ajax.googleapis.com; connect-src 'self' https://api.myapp.com realtime.myapp.com:8080; media-src 'self' youtube.com; object-src media1.example.com media2.example.com *.cdn.example.com; frame-src 'self' youtube.com embed.ly

‘Content-Security-Policy’ — это официальный http-заголовок, утвержденный W3C, который поддерживается браузерами Chrome 26+, Firefox 24+ и Safari 7+. HTTP-заголовок «X-Content-Security-Policy» используется для Firefox 4-23 и для IE 10-11, заголовок «X-Webkit-CSP» – для Chrome 14-25, Safari 5.1-7[6].

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

6. Регулярно проводите анализ безопасности кода и тестирование на проникновение. Используйте как ручной, так и автоматизированный подходы. Такие инструменты как Nessus, Nikto и OWASP Zed Attack Proxy помогут обнаружить уязвимости XSS в вашем веб-приложении.

7. Пользователям рекомендуется регулярно обновлять браузер до новой версии и использовать для них расширения, например, NoScript.
Как вы могли заметить, у каждой рекомендации есть свои достоинства и недостатки, поэтому эффективность противодействия межсайтовому выполнению сценария достигается путем применения комплексной защиты, т.е. использования описанных рекомендаций в совокупности.

Автор статьи: Внештатный сотрудник PentestIT, Сергей Сторчак

Источник

Читайте также:  Javascript удалить повторяющиеся элементы массива
Оцените статью