Введение в политику безопасности контента (CSP)

внешний интерфейс Безопасность Twitter
Введение в политику безопасности контента (CSP)

Политика безопасности контента (CSP) — это дополнительный уровень безопасности, используемый для обнаружения и смягчения определенных типов атак, включая межсайтовые сценарии (XSS) и атаки с внедрением данных. Будь то кража данных, загрязнение содержимого веб-сайта или распространение вредоносных программ, эти атаки являются основными средствами.

причина

когда я случайно твиттер страницыview sourceПозже обнаружил сюрприз.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>Twitter</title>
  <style>
  body {
    background-color: #ffffff;
    font-family: sans-serif;
  }
  a {
    color: #1da1f2;
  }
  svg {
    color: #1da1f2;
    display: block;
    fill: currentcolor;
    height: 21px;
    margin: 13px auto;
    width: 24px;
  }
  </style>
</head>
<body>
    <noscript>

      <center>If you’re not redirected soon, please <a href="/">use this link</a>.</center>
    </noscript>
    <script nonce="SG0bV9rOanQfzG0ccU8WQw==">

      document.cookie = "app_shell_visited=1;path=/;max-age=5";

      location.replace(location.href.split("#")[0]);
    </script>
</body>
</html>

Можно сказать, что это очень освежает по сравнению с исходным кодом других сайтов, которые обычно видят. Там нет грязной этикетки, функции как много. Особенно смущается, думая, что это весь исходный код страницы, но легко понять, что это не настоящий HTML-код, после просмотра панели Source DevTools. Но что такое исходный код страницы, учитывая такую ​​освежающую версию, это не исследование в первую очередь.

nonceАтрибуты.它以及它后面的神秘字符串成功引起了我的好奇。再去看 Google 首页的源码,也有好些nonceОно использует.是时候去了解一下这里的nonceчто это такое.

! <script nonce="SG0bV9rOanQfzG0ccU8WQw==">

    document.cookie = "app_shell_visited=1;path=/;max-age=5";

    location.replace(location.href.split("#")[0]);
</script>

Content Security Policy (CSP)

чтобы понятьnonce, сначала поймиContent-Security-Policy(CSP).

Мы все знаем, что браузеры имеют политику одного и того же происхождения (same-origin policy) ограничения безопасности, то есть каждому сайту разрешено загружать данные только из того же источника, что и он сам,https://a.comневозможно изhttps://b.comзагружается в ресурс. Каждый сайт строго ограничен своим островом, и это песочница, поэтому очень безопасно, и вся сеть не будет захламлена. В основном, это решает большинство проблем безопасности. При отсутствии политики одинакового происхождения вредоносный код может легко выполниться на стороне браузера и получить различную личную информацию: номера банковских счетов, социальные данные и т. д.

Конечно, есть способ обмена данными между веб-сайтами.Подробнее.CORS.

На самом деле проблема в том, что политика одного и того же источника не является надежной, а междоменные атакиCross-site scripting (XSS)Он включает в себя различные средства для обхода ограничений, в виде внедрения вредоносного кода на страницу для завершения кражи или атаки информации. Например, сайты типа UGC, поскольку контент зависит от создания пользователем, это открывает большую дыру, позволяя контенту, введенному пользователем, работать на странице. Конечно, поскольку мы все знаем, что будут атаки путем внедрения, анти-XSS-фильтрация пользовательского ввода также стала стандартной.

Content-Security-Policy, с другой стороны, добавляет уровень защиты в браузер, что может значительно снизить вероятность таких атак.

принцип

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

Есть два способа его реализации:

  • добавить серверContent-Security-PolicyРеспондент для обозначения правил
  • Добавьте теги в HTML, чтобы указатьContent-Security-Policyправило

Правила CSP в шапке mobile.twitter.com

Для удобства тестирования использованы следующие примеры<meta>тег, чтобы включить правила CSP. но<meta>Некоторые из команд нельзя использовать, которые будут изучены позже. Все директивы ограничения можно использовать только в заголовках ответа.

Простой пример

Создайте HTML-файл со следующим содержимым:

csp_test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Security-Policy" content="script-src 'self' https://unpkg.com">
    <title>CSP Test</title>
</head>
<body>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
</body>
</html>

Откройте локальный сервер в каталоге, где тестовый файл для доступа, здесь приходит использование Python Server:

python -m SimpleHTTPServer 8000

Затем посетите localhost:8000, чтобы увидеть результат:

Обычный доступ в соответствии с правилами CSP

Тогда мы будемContent-Security-PolicyИзмените его, чтобы запретить использование каких-либо ресурсов, и повторите попытку:

csp_test.html

<!DOCTYPE html>
<html lang="en">
<head>
-     <meta http-equiv="Content-Security-Policy" content="script-src 'self' https://unpkg.com">
+     <meta http-equiv="Content-Security-Policy" content="script-src ‘none’">
    <title>CSP Test</title>
</head>
<body>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
</body>
</html>

Инициировать блокировку ресурсов правила CSP

Давайте объясним установленные здесь правила CSP и поймем, почему загрузка ресурсов не удалась.

Правила CSP
либо в шапке, либо<meta>Формат значения, указанного в теге, является единым, который состоит из ряда директив CSP (директив).

Пример:

Content-Security-Policy: <policy-directive>; <policy-directive>…

Здесь директива, то есть директива, — это указанный в спецификации CSP источник для детализации определенного ресурса, такого как тот, что использовался в предыдущем примере.script-src, указав, какие легитимные источники могут быть у скрипта,img-srcЗатем укажите изображение, обычно используются следующие команды:

  • base-uriНа странице могут появиться ограничения<base>ссылка в этикетке.
  • child-srcСписок ссылок, доступных для работника и встроенных в виде фрейма. Например:child-src https://youtube.comУказывает, что видеоресурсы могут быть встроены только с Youtube.
  • connect-srcАдрес, с которого может быть инициировано соединение (через XHR, WebSockets или EventSource).
  • font-srcИсточник шрифта. Например, чтобы использовать Google Web-шрифты, которые вам нужно добавитьfont-src https://themes.googleusercontent.com
  • form-action <form>
  • frame-ancestorschild-srcровно наоборот). Действующий на<frame>, <iframe>, <embed>а также<applet>.该指令不能通过<meta>Назначен и работает только с документами, отличными от HTML.
  • frame-srcЭта директива устарела на уровне 2, но будет восстановлена ​​на уровне 3. резервный вариант, если не указаноtochild-srcинструкция.
  • img-srcУкажите источник изображения.
  • media-srcОграничьте источники аудио- и видеоресурсов.
  • object-srcИсточник для Flash и других плагинов.
  • plugin-typesОграничьте типы плагинов, которые могут быть загружены на странице.
  • report-uri指定一个可接收 CSP 报告的地址,浏览器会在相应指令不通过时发送报告。 не могу пройти<meta>Теги указаны.
  • style-srcОграничьте источник файлов стилей.
  • upgrade-insecure-requestsПоручите клиенту переписать адрес страницы с HTTP на HTTPS. Полезно, когда на сайте много старых адресов, которые нужно перенаправить.
  • worker-srcДиректива в CSP уровня 3, указывающая адреса, которые можно использовать в рабочем, совместно используемом или сервисном работнике.

child-srcа такжеframe-ancestorsПохоже. Первый указывает, какие фреймы могут быть загружены на страницу, а второй указывает, кто может загружать страницу в фреймах. Например, две веб-страницы A и B с разных сайтов, B и B имеют фреймы iframe, которые загружают A. Так

  • Необходимость включения фреймов-предков B
  • Child-src B должен содержать A

По умолчанию эти инструкции открыты до максимального состояния, что можно понимать как их значение по умолчанию.*. Напримерimg-src, если не указано явно, ресурс изображения может быть загружен отовсюду.

default-srcimg-srcЕсли не указано, значение по умолчанию равно*, может загружать изображения из всех источников, но установитьdefault-srcПосле этого по умолчаниюdefault-srcуказанное значение.

Обычная практика установитdefault-src ‘self’, чтобы все ресурсы были ограничены тем же доменом, что и страница. Если вы хотите загружать изображения из CDN в это время, вы можете добавить источник изображения отдельно.

Content-Security-Policy: default-src ‘self’; img-src https://cdn.example.com

Теперь посмотрите на пример в начале, может быть, вы видите его сейчас. Поскольку странице необходимо загрузить библиотеку React из CDN, мы<meta>Тег определяет следующие правила CSP:

script-src 'self' https://unpkg.com

здесьselfа позже изменился наnoneЭто значение по умолчанию и должно быть заключено в кавычки, иначе оно будет проанализировано как URI. Правило CSP здесь означает, что доступ к сценарию на странице возможен только из того же домена иhttps://unpkg.comнагрузка. Если мы удалим последний, библиотека React также не сможет загрузиться, как показано на снимке экрана выше, и в консоли появится журнал неудачной загрузки и сработавшие правила.

изменить наnoneПосле этого это означает, что страница не загружает никаких скриптов, даже скрипты на вашем собственном сайте не могут быть загружены и выполнены. Попробуйте здесьcsp_test.htmlсоздать файл сценария вместеtest.js:

test.js

alert(‘来自 test.js 的问候!’)

В то же время обратитесь к нему на странице:

csp_test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Security-Policy" content="script-src 'none'">
    <title>CSP Test</title>
</head>
<body>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
+    <script src="./test.js"></script>
</body>
</html>

Результат выполнения страницы:

Страница не будет загружать никаких скриптов, если script-src не указан

Да, даже ваши собственные скрипты не могут быть загружены и выполнены. CSP настолько строг и ясен, что в нем нет двусмысленности. Поэтому при указании источника нам нужно подтвердить правильность URI.

допустимые значения для инструкции

Есть два способа записать исходный код, за которым следует команда

  • значение по умолчанию
  • подстановочный знак URI

значение по умолчанию

Значения по умолчанию следующие:

  • никто ничему не соответствует.
  • unsafe-inline позволяет использовать встроенные скрипты и стили. Да, вы правильно прочитали, существуют соответствующие ограничения на встроенный в страницу контент.
  • unsafe-eval позволяет выполнять скрипты, динамически созданные из строк, такие как eval, setTimeout и т. д.

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

Рассмотрим следующий код:

csp_test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <title>CSP Test</title>
    <style>
        body{
            color:red;
        }
    </style>
</head>
<body>
    <h1>Hello, World!</h1>
    <script>
        window.onload=function(){
            alert('hi jack!')
        }
    </script>
</body>
</html>

CSP неуказанные обстоятельства

По описанию на MDN, если на сайте не указан CSP, браузер по умолчанию не откроет соответствующую проверку, так что все вышеперечисленное работает нормально, только ограничивается нормальным тем же доменом.

Если сайт не предлагает заголовок CSP, браузеры также используют стандартную политику того же источника.
— через MDN оОписание политики безопасности контента (CSP)

Добавляем лимит CSP:

csp_test.html

<!DOCTYPE html>
<html lang="en">
<head>
+    <meta http-equiv="Content-Security-Policy" content="default-src 'self'">
    <title>CSP Test</title>
    <style>
        body{
            color:red;
        }
    </style>
</head>
<body>
    <h1>Hello, World!</h1>
    <script>
        window.onload=function(){
            alert('hi jack!')
        }
    </script>
</body>
</html>

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

Встроенный код запрещен

Как это исправить. Если мы хотим разрешить встроенные скрипты или стили на странице, нам нужно явно указать это через script-src и style-src.

csp_test.html

<!DOCTYPE html>
<html lang="en">
<head>
!    <meta http-equiv="Content-Security-Policy" content="default-src 'self' ‘unsave-inline’">
    <title>CSP Test</title>
    <style>
        body{
            color:red;
        }
    </style>
</head>
<body>
    <h1>Hello, World!</h1>
    <script>
        window.onload=function(){
            alert('hi jack!')
        }
    </script>
</body>
</html>

здесьdefault-src 'self' ‘unsave-inline’В конфигурации по умолчанию заслуживают доверия эти источники: те же страницы и домены, а также встроенные.

unsafe-inlineunsafe-eval), потому что встроенные сценарии и стили неудобно поддерживать и они не используют преимущества хорошо организованного кода. Лучше всего извлекать стили в файлы стилей, а скрипты загружать в отдельные файлы js. Рекомендуется сохранять HTML-файлы чистыми. даже еслиonclick=“myHandler”илиhref=“javascript:;”Этот распространенный метод записи также является встроенным сценарием и нуждается в модификации.

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

<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa>
  // 这里放置内联在 HTML 中的代码
</script>

заголовки ответа HTTP страницыContent-Security-PolicyЭта же зашифрованная строка включена в конфигурацию:

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

Обратите внимание здесьnonce-приставка.

Это то, что мы видели в начале статьи, и я понимаю это здесь.

<style>Метки обрабатываются аналогично.

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

Помимо использованияnoceУкажите зашифрованную строку, чего также можно добиться путем запутывания хеш-значения. Эту практику не нужно добавлять на этикеткуnonceВместо этого код, который необходимо внедрить, использует алгоритм шифрования для генерации хэша и помещения его в инструкцию CSP в качестве значения.Алгоритм шифрования здесь поддерживает sha256, sha384 и sha512. В настоящее время префикс, используемый в CSP, является соответствующим именем алгоритма.

Пример хеш-метода:

<script>alert('Hello, world.');</script>
Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='

eval

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

  • setTimeout/setInterval может получить строку для выполнения в виде кода. setTimout('предупреждение(1)', 1000).
  • оценить . eval('предупреждение(1)').
  • Конструктор функций. новая функция («предупреждение (1)»).

И встроенный такой же, есть специальные инструкцииunsafe-evalevalа такжеFunctionКонструктор, исключите использование иsetTimeout/setIntervalМожет быть преобразован в нестроковую форму.

setTimout(function(){
    alert(1);
}, 1000)

URI

В дополнение к указанным выше предустановкам можно указать полный URI или с подстановочными знаками.*адрес, чтобы соответствовать уточнению законного происхождения ресурса. Правила URI здесь такие же, как заголовки отклика в перекрестных доменах сервера конфигурации, см.Same-origin policy.

  • *://*.example.com:*будет соответствовать всемexample.comподдомены , но не включаяexample.com.
  • http://example.comа такжеhttp://www.example.comдва разных URI.
  • http://example.com:80а такжеhttp://example.comЭто также два разных URI, хотя порт веб-сайта по умолчанию — 80.

Согласно ВикипедииUniform Resource IdentifierКак поясняется на странице, полный URI состоит из следующих частей:
URI = scheme:[//authority]path[?query][#fragment]

вauthorityТакже включает:
authority = [userinfo@]host[:port]

Таким образом, вы можете подумать, что один из них отличается, это оба URI. Это важно понимать, как и в первом примере, указанном выше.*.example.com, легко предположить, что раз разрешены все поддомены домена, то должно бытьexample.comтакже является законным.

Поскольку URI сопоставляются динамически, это объясняет, почему вышеупомянутые пресеты взяты в кавычки. Потому что без кавычекselfсказал быhostдаselfАдрес ресурса и не выражает первоначальный смысл.


Content-Security-Policy

Производительность CSP в этих условиях мы посмотрим.

  • Для случаев, когда задано несколько заголовков ответа, применяется самое строгое правило. Например, в следующих двух заголовках ответа, хотя второй установленconnect-srcразрешатьhttp://example.com/, но первый установленconnect-srcдляnone, тем строжеnoneвступит в силу. видетьMultiple content security policies.
Content-Security-Policy: default-src 'self' http://example.com;
                         connect-src 'none';
Content-Security-Policy: connect-src http://example.com/;
                         script-src http://example.com/
  • Если одна и та же инструкция указана несколько раз, приоритет будет иметь первая, а последующие будут игнорироваться.

csp_test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Security-Policy" content="default-src 'self';default-src 'unsafe-inline';">
    <title>CSP Test</title>
    <style>
        body{
            color:red;
        }
    </style>
</head>
<body>
    <h1>Hello, World!</h1>
    <script>
        window.onload=function(){
            alert('hi jack!')
        }
    </script>
</body>
</html>

Эффект отображается, когда одна и та же команда настроена повторно

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

  • уточнитьdefault-srcFetch类指令 的默认值。 которыйdefault-srcНедействительно для всех команд, значение по умолчанию для других команд по-прежнему*.

Отправить жалобу

Content-Security-Policyreport-uri

Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;

JSON основан на сервере для получения данных из формы.

{
  "csp-report": {
    "document-uri": "http://example.org/page.html",
    "referrer": "http://evil.example.com/",
    "blocked-uri": "http://evil.example.com/evil.js",
    "violated-directive": "script-src 'self' https://apis.google.com",
    "original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
  }
}

режим отчета

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

УказавContent-Security-Policy-Report-OnlyвместоContent-Security-Policy, режим отчета включен.

Content-Security-Policy-Report-Only: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;

Конечно, вы также можете указать два заголовка ответа одновременно, и правила в каждом будут выполняться нормально и не будут влиять друг на друга. Например:

Content-Security-Policy: img-src *;
Content-Security-Policy-Report-Only: img-src ‘none’; report-uri http://reportcollector.example.com/collector.cgi

Изображение здесь по-прежнему загружается нормально, ноimg-src ‘none’также обнаружит и отправит отчет.

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

Рекомендуемая практика

Такие меры безопасности, конечно, включаются как можно скорее. Ниже приведены рекомендуемые практики:

  • Во-первых, откройте только режим отчета, посмотрите масштаб влияния и измените проблему.
  • При добавлении инструкций изdefault-src ‘none’Запускайте, проверяйте на ошибки и постепенно добавляйте правила, пока требования не будут выполнены.
  • Наблюдайте в течение определенного периода времени после подключения к сети, а затем после стабилизации переключитесь из режима отчетности в режим обязательного выполнения.

Совместимость с браузером

Текущий выпускLevel 3Can I UseImplementation Report for Content Security Policy Level 2.

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

Ссылаться на

оригинал:блог woo woo woo.cn на.com/WA have/afraid/int…
Автор: Лю Вэйонг