Серия "Полное развитие стека"
CORS и CSRF слишком легко спутать, после прочтения этой статьи вам станет ясно.
1. Разница между CORS и CSRF
Взгляните на картинку ниже:
Концепции этих двух совершенно разные.Кроме того, мы часто видим XSS.Давайте представим их вместе:
-
CORS: Распределение ресурсов для обмена ресурсами перекрестного происхождения
-
CSRF: Подделка межсайтовых запросов Подделка межсайтовых запросов
-
XSS: Атака с использованием межсайтовых сценариев Cross Site Scrit (чтобы отличить ее от CSS, поэтому в области безопасности она называется XSS)
2. КОРС
1. Концепция
Cross-Origin Resource Sharing (CORS), также переводится как Cross-Origin Resource Sharing, — это спецификация технологии браузера, которая предоставляет веб-службам метод передачи сценариев песочницы из разных доменов, чтобы избежать политики браузера в отношении одного и того же источника, которая является современной версия схемы JSONP. В отличие от JSONP, CORS также поддерживает другие HTTP-запросы в дополнение к методу запроса GET. Использование CORS позволяет веб-дизайнерам использовать обычный XMLHttpRequest, который лучше обрабатывает ошибки, чем JSONP. С другой стороны, JSONP будет работать в старых браузерах, не поддерживающих CORS. Современные браузеры поддерживают CORS.
Основные знания:CORS — это стандарт W3C, который позволяет браузерам выдаватьXMLHttpRequest
request, тем самым преодолевая ограничение, согласно которому AJAX может использоваться только из одного и того же источника.
Таким образом, ключом к реализации связи CORS является сервер. Пока сервер реализует интерфейс CORS, возможна связь между источниками, то есть для решениямеждоменная проблема.
2. Тип запроса CORS
Браузеры делят запросы CORS на две категории:простой запрос(простой запрос) ине простой запрос(не очень простая просьба).
простой запросКак правило, это следующие две ситуации:
условие | описывать |
---|---|
метод запроса | Метод запроса:HEAD илиGET илиPOST ; |
HTTP-заголовки | Информация заголовка HTTP не превышает следующих полей:Accept Accept-Language Content-Language Last-Event-ID Content-Type : ограничено тремя значениямиapplication/x-www-form-urlencoded ,multipart/form-data ,text/plain
|
Если два вышеперечисленных условия не выполняются одновременно, он принадлежит кне простой запрос.
3. Процесс CORS для простых запросов
Когда браузер обнаружит, что наш запрос AJAX являетсяпростой запрос, это будет автоматическиинформация заголовка, добавить одинOrigin
поле.
Origin
Поле используется для описания источника этого запроса (включаяпротокол + доменное имя + Номер порта), сервер решает, соглашаться ли на запрос в соответствии с этим значением.
когдаOrigin
Указанный источник не разрешен, сервер вернет обычный HTTP-ответ, но браузер найдет в заголовке ответаAccess-Control-Allow-Origin
поле, возникает исключение.
когдаOrigin
Если указанный источник находится в разрешенной области, в заголовке ответа, возвращаемом сервером, будет несколько дополнительных полей заголовка:
В дополнение к информации заголовка на приведенном выше рисунке, как правило, есть следующие три связанных информации заголовка:
Access-Control-Allow-Origin
Это поле обязательно к заполнению. Доменное имя, представляющее область действия лицензии, обычно имеет два значения:Значение поля Origin на момент запросаили*
(звездочка) обозначает любое доменное имя.
Access-Control-Allow-Credentials
Это поле является необязательным. Логическое значение, указывающее, разрешать ли отправку запросов CORS.Cookie
.若不携带Cookie
Вам не нужно устанавливать это поле.
когда установлено наtrue
ноCookie
Включены в запрос и отправлены на сервер вместе. Его также необходимо включить в AJAX-запросе.withCredentials
атрибут, иначе браузер не отправитCookie
.
let xhr = new XMLHttpRequest();
xhr.withCredentials = true;
Уведомление:Если внешний интерфейс установленAccess-Control-Allow-Credentials
дляtrue
для переноса файла cookie для инициирования запроса, серверAccess-Control-Allow-Origin
не может быть установлено на*
.
Access-Control-Expose-Headers
Это поле является необязательным. Вы можете установить поля, которые необходимо получить. Поскольку запрос CORS по умолчанию,XMLHttpRequest
объектgetResponseHeader()
Метод может получить только следующие 6 основных полей:
Cache-Control
,Content-Language
,Content-Type
,Expires
,Last-Modified
,Pragma
.
4. Процесс CORS для непростых запросов
не простой запросНапример: метод запросаPUT / DELETEилиContent-Type:application/json
тип запроса.
Когда запрос CORS делается для непростого запроса, он будет добавлен один раз перед официальным сообщением.Запрос "Preflight" (метод OPTIONS), чтобы узнать у сервера, находится ли запрошенное доменное имя в списке разрешенных и какую информацию заголовка использовать.
когда«Предполетный» запросПосле прохождения AJAX-запрос будет официально инициирован, иначе будет сообщено об ошибке.
4.1 Предполетный запрос
OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
User-Agent: Mozilla/5.0...
...
«Предполетный» запросСообщение содержит два специальных поля:
Access-Control-Request-Method
Это поле является обязательным и используется для перечисления методов HTTP, которые будут использоваться в CORS-запросе браузера.Приведенный выше пример:PUT
.
Access-Control-Request-Headers
Указывает дополнительные поля заголовка, отправляемые запросом CORS браузера, приведенный выше примерX-Custom-Header
.
4.2 Предполетный ответ
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Connection: Keep-Alive
...
При предварительном запросепройти черезПозже, в заголовке предпечатного ответа, он вернетAccess-Control-Allow-
информация в началеAccess-Control-Allow-Origin
Указывает допустимый диапазон, значение также может быть*
.
При предварительном запросеотклонятьПозже, в заголовке ответа перед полетом, не вернетсяAccess-Control-Allow-
информация в начале и сообщение об ошибке выводится на консоль.
3. CSRF
1. Концепция
Подделка межсайтовых запросов (английский язык: Подделка межсайтовых запросов), также известная как атака одним щелчком мыши или сеансовая подмена, часто сокращенно CSRF или XSRF, представляет собой метод принуждения пользователя к выполнению непреднамеренных действий на вошедшем в данный момент способ атаки на работу веб-приложения. По сравнению с межсайтовым скриптингом (XSS), XSS использует доверие пользователя к указанному веб-сайту, а CSRF использует доверие веб-сайта к веб-браузеру пользователя.
Основные знания:Подделка межсайтовых запросов.
Простое понимание:Злоумышленники крадут вашу личность и отправляют вредоносные запросы от вашего имени.
Распространенные сценарии: отправка электронных писем от вашего имени, отправка сообщений, кража вашей учетной записи, даже покупка товаров, перевод виртуальной валюты и т. д.
Воздействие: утечка личной информации и безопасность имущества.
2. Процесс атаки CSRF
Поток атаки CSRF описан выше, где жертва выполняет два шага:
- Войдите на доверенный веб-сайт А и создайте и сохраните файлы cookie локально;
- Посетите вирусный сайт B, не выходя из системы A;
Можно понять, что если два вышеуказанных шага не выполнены, он не будет атакован CSRF.
3. Защита на стороне сервера от CSRF-атак
Способов серверной защиты много, идеи похожи, и все они добавлены на клиентской странице.Псевдослучайное число.
3.1 Хеширование файлов cookie (все формы содержат одно и то же псевдослучайное число)
Самый простой и эффективный способ, потому что злоумышленник теоретически не может получить сторонний файл cookie, поэтому подделка данных формы не удалась. Возьмем в качестве примера php-код:
<?php
//构造加密的Cookie信息
$value = "LeoDefenseSCRF";
setcookie("cookie", $value, time()+3600);
?>
Увеличьте хеш-значение в форме, чтобы убедиться, что это действительно запрос, отправленный пользователем.
<?php
$hash = md5($_COOKIE['cookie']);
?>
<form method="POST" action="transfer.php">
<input type="text" name="toBankId">
<input type="text" name="money">
<input type="hidden" name="hash" value="<?=$hash;?>">
<input type="submit" name="submit" value="Submit">
</form>
Затем выполните проверку значения хэша на стороне сервера.
<?php
if(isset($_POST['check'])) {
$hash = md5($_COOKIE['cookie']);
if($_POST['check'] == $hash) {
doJob();
} else {
//...
}
} else {
//...
}
?>
Я лично думаю, что этот методМожет устранить 99% CSRF-атак, это еще 1%.... Поскольку пользовательский файл cookie легко украсть из-за XSS-уязвимости веб-сайта, это еще 1%.
Среднестатистический злоумышленник видит необходимость вычисления хеш-значения и в основном сдается, за исключением некоторых, поэтому, если требуется 100% устранение, это не лучший метод.
3.2 Код подтверждения
Идея такова: каждый раз, когда пользователь отправляет, пользователь должен заполнить случайную строку на изображении в форме.Это решение может полностью решить CSRF, но простота использования оставляет желать лучшего, а использование изображения капчи связано с ошибками. в MHTML, который может быть в некоторых версиях Microsoft IE.
3.3 Одноразовые токены (разные формы содержат разное псевдослучайное значение)
требует внимания»Совместимость с параллельными сессиями". Если у пользователя одновременно открыты две разные формы на сайте, защита CSRF не должна влиять на его отправку любой из форм. Учтите, генерирует ли сайт псевдослучайное значение каждый раз, когда форма загружается, чтобы перезаписать предыдущий Что происходит с псевдослучайным значением : пользователь может успешно отправить только ту форму, которую он открывал последней, потому что все другие формы содержат недопустимые псевдослучайные значения Необходимо соблюдать осторожность, чтобы защита CSRF не влияла на вкладку Обзор или просмотр сайта с использованием нескольких окна браузера.
Реализация php выглядит следующим образом:
- первый
Token
функция генерации токена (gen_token()
)а такжеSession
функция генерации токена (gen_stoken()
):
<?php
function gen_token() {
$token = md5(uniqid(rand(), true));
return $token;
}
function gen_stoken() {
$pToken = "";
if($_SESSION[STOKEN_NAME] == $pToken){
$_SESSION[STOKEN_NAME] = gen_token();
}
else{ }
}
?>
- WEB-форма генерирует функцию скрытого поля ввода:
<?php
function gen_input() {
gen_stoken();
echo "<input type=\"hidden\" name=\"" . FTOKEN_NAME . "\"
value=\"" . $_SESSION[STOKEN_NAME] . "\"> ";
}
?>
- Структура веб-формы:
<?php
session_start();
include("functions.php");
?>
<form method="POST" action="transfer.php">
<input type="text" name="toBankId">
<input type="text" name="money">
<? gen_input(); ?>
<input type="submit" name="submit" value="Submit">
</FORM>
- Токен проверки сервера
Этот шаг очень прост и подробно описываться не будет.
4. XSS
Уведомление: эта статья кратко знакомит с XSS, вы можете прочитать ее для получения подробной информации.FEWYнаписано«Атака с использованием межсайтовых сценариев — XSS»сегмент fault.com/ah/119000002…
1. Концепция
Межсайтовый скриптинг (англ. Cross-site scripting, обычно сокращенно XSS) — это атака через уязвимость в системе безопасности приложений веб-сайта, представляющая собой разновидность внедрения кода. Это позволяет злоумышленникам вводить код на веб-страницы, и другие пользователи страдают при просмотре страницы. Такие атаки обычно включают HTML и языки сценариев на стороне клиента.
Атака XSS обычно относится к методу атаки, при котором злоумышленник внедряет вредоносный скрипт в веб-страницу, и когда пользователь просматривает веб-страницу, вредоносный скрипт выполняется для управления поведением браузера пользователя.
Общие опасности XSS:
- Украсть пользовательские файлы cookie, обеспечить конфиденциальность пользователей и украсть учетные записи пользователей.
- Взлом сеанса пользователя (браузера) для выполнения произвольных действий, таких как незаконные переводы, форсирование журналов, отправка электронных писем и т. д.
- Насильно открывайте рекламные страницы, очищайте трафик, распространяйте червей межсайтового скриптинга и вешайте лошадей на веб-страницы.
- Комбинируйте с другими уязвимостями, такими как уязвимости CSRF, для дальнейших атак.
2. XSS-классификация
3. XSS-защита
3.1 Метод 1: собственная защита браузера (X-XSS-защита)
Основные современные браузеры (Internet Explorer, Chrome и Safari) поддерживают протокол HTTP.X-XSS-Protection
Заголовок ответа, при обнаружении атаки межсайтового скриптинга (XSS) браузер перестанет загружать страницу.
X-XSS-Protection
Заголовок ответа имеет следующие 4 значения:
X-XSS-Protection: 0
Отключите фильтрацию XSS.
X-XSS-Protection: 1
Включите фильтрацию XSS (обычно браузеры по умолчанию). Если обнаружена атака межсайтового скриптинга, браузер очистит страницу (удалит небезопасные части).
X-XSS-Protection: 1; mode=block
Включите фильтрацию XSS. При обнаружении атаки браузер не очистит страницу, но предотвратит ее загрузку.
X-XSS-Protection: 1; report=<reporting-uri>
Включите фильтрацию XSS. При обнаружении атаки межсайтового скриптинга браузер очистит страницу и отправит отчет о нарушении, используя возможности директивы CSP report-uri.
Уведомление:
Это не полностью предотвращает отражение XSS, и не все браузеры его поддерживают.X-XSS-Protection
, есть проблемы с совместимостью.
У него есть только определенная защита от отраженного XSS, и его принцип заключается только в проверке корреляции между URL-адресом и элементами в DOM.
3.2 Метод 2: побег
Экранируйте обычно используемые специальные символы, чтобы злоумышленники не могли внедрить скрипты, создав специальные символы. Данные, введенные пользователем, должны быть экранированы как на стороне клиента, так и на стороне сервера.
Общие специальные символы, которые необходимо экранировать, например<
,>
,&
,"
,'
.
Метод побега:
function escapeHTML(str) {
if (!str) return '';
str = str.replace(/&/g, "&");
str = str..replace(/</g, "<");
str = str..replace(/>/g, ">");
str = str..replace(/"/g, """);
str = str..replace(/'/g, "'");
return str;
};
3.3 Метод 3: Фильтрация
Распространено в форматированном текстовом содержимом, поскольку ему необходимо сохранить HTML, он не может напрямую использовать методы экранирования, но может использовать белые списки, чтобы разрешить определенные теги и атрибуты HTML для предотвращения атак XSS.
3.4 Метод 4: Политика безопасности контента (CSP)
Политика безопасности контента (CSP), суть в системе белых списков, разработчик четко сообщает клиенту, какие внешние ресурсы можно загружать и выполнять, что значительно повышает безопасность веб-страницы.
Есть два способа включить CSP.
- через HTTP-заголовки
Content-Security-Policy
поля:
Content-Security-Policy: script-src 'self';
object-src 'none';
style-src cdn.example.org third-party.org;
child-src https:
- через Интернет
<meta>
Этикетка
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">
В приведенном выше коде CSP настроен следующим образом:
- Сценарий: доверять только текущему доменному имени
-
<object>
Теги: не доверять ни одному URL, т. е. не загружать никакие ресурсы - таблица стилей: доверять только
cdn.example.org
а такжеthird-party.org
- подконтент страницы, такой как
<frame>
,<iframe>
: должен быть загружен с использованием протокола HTTPS - Дополнительные ресурсы: без ограничений
- Если этот параметр включен, внешние ресурсы, не соответствующие CSP, блокируются от загрузки.