Обход защитных мер - Обычные способы обхода CSP
Last updated
Last updated
Ранее мы обсуждали, как разработчики могут настроить Content Security Policy в качестве способа защиты для сайтов, предотвращая выполнение JavaScript злоумышленниками, даже если они умудряются внедрить HTML. Это значительно снижает воздействие атак. Так как CSP охватывает широкий спектр элементов, включая скрипты, стили и изображения, конфигурация CSP каждого сайта может отличаться. Важно настраивать CSP исходя из содержимого вашего собственного сайта.
Однако, если CSP не настроена правильно, это практически то же самое, что и отсутствие настройки. В этом посте я покажу вам некоторые общие способы обхода CSP.
Если ваш сайт использует публичные платформы CDN для загрузки JavaScript, такие как , возможно, что правило CSP установлено как script-src .
В предыдущем обсуждении CSP я спросил, в чем проблема с этой конфигурацией. Теперь позвольте мне раскрыть ответ.
Проблема этого подхода в том, что он позволяет загружать все библиотеки с этого источника. Чтобы исправить эту ситуацию, кто-то уже создал библиотеку под названием и загрузил ее. Вот пример:
При настройке CSP распространенной практикой является использование nonce для указания, какие скрипты могут быть загружены. Даже если злоумышленник внедряет HTML, они не могут выполнить код без знания nonce. Вот пример
После открытия консоли мы видим ошибку:
Решение для предотвращения этого обхода - добавить правило base-uri в CSP. Например, используйте base-uri 'none', чтобы блокировать все базовые теги. Поскольку большинство сайтов не требует использования <base>, вы с уверенностью можете добавить эту директиву.
JSONP - это способ получения данных с разных источников, но я лично считаю его старым обходным путем, который появился до зрелости CORS.
Эта ошибка CORS мешает вам получить ответ.
Однако есть несколько элементов, которые не подчиняются политике того же источника, такие как <img>. В конце концов, изображения можно загружать из различных источников, и мы не можем получить доступ к их содержимому с помощью JavaScript, поэтому проблемы нет.
Элемент <script> также не ограничен. Например, при загрузке Google Analytics или Google Tag Manager, мы напрямую пишем <script src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXXX-X"></script>, и это никогда не было ограничено, верно?
В результате моя веб-страница может получать данные с помощью функции setUsers:
Мы успешно вставили желаемый код в ответ, и эту технику можно использовать для обхода CSP.
Например, допустим, мы разрешаем скрипт из определенной области, и эта область действительно имеет URL, поддерживающий JSONP. Мы можем использовать его для обхода CSP и выполнения кода. Например:
Но случайно этот домен имеет URL, который поддерживает JSONP:
Таким образом, злоумышленник может использовать его для обхода CSP и успешного выполнения кода.
Во-вторых, проверьте, какие домены имеют доступные API JSONP.
Ранее упомянутый CSP Evaluator также любезно напоминает вам:
Хотя ранее JSONP был представлен как мощный инструмент, позволяющий выполнение произвольного кода, некоторые веб-сайты ограничивают параметр обратного вызова JSONP. Например, разрешены только определенные символы, такие как a-zA-Z., поэтому мы можем вызывать только функцию, и мы не можем контролировать параметры.
Что мы можем сделать в этом случае?
Допустим, на странице есть кнопка, при нажатии на которую происходит какое-то действие. Вы можете использовать JavaScript код document.body.firstElementChild.nextElementSibling.click, чтобы щелкнуть ее. Поскольку символы в этом коде разрешены, вы можете поместить его внутри JSONP: ?callback=document.body.firstElementChild.nextElementSibling.click, и использовать JSONP для выполнения кода, как упоминалось ранее.
В статье упоминается длинный фрагмент кода, который можно использовать для нажатия кнопки "Install Plugin":
Хотя у SOME есть много ограничений, если не найдены другие способы эксплуатации, это все равно может быть метод, который стоит попробовать.
Что происходит, когда CSP сталкивается с серверным перенаправлением? Если перенаправление ведет к другому источнику, который не разрешен, оно все равно не сработает.
Вот пример:
С этим перенаправлением, даже если путь указан полностью, он все равно будет обойден.
Поэтому лучшим решением будет убедиться, что на веб-сайте нет уязвимостей для открытого перенаправления и что в правилах CSP нет доменов, которые могут быть эксплуатированы.
Помимо упомянутого ранее перенаправления для обхода ограничений по пути, существует еще одна техника, называемая Relative Path Overwrite (RPO), которая может быть использована на некоторых серверах.
Путем эксплуатации этого несоответствия в интерпретации URL между браузером и сервером можно обойти правила пути.
Решение состоит в том, чтобы не рассматривать %2f как / на стороне сервера, обеспечивая одинаковую интерпретацию между браузером и сервером для избежания этой проблемы.
Ранее упомянутые методики в основном сосредоточены на обходе правил CSP. Теперь давайте обсудим методики обхода, эксплуатирующие ограничения самого CSP.
Например, предположим, что веб-сайт имеет строгий CSP, но разрешает выполнение JavaScript:
Цель - украсть document.cookie. Как это можно достичь?
Проблема не в том, чтобы украсть cookie, проблема заключается в передаче его внешний ресурс. Поскольку CSP блокирует загрузку всех внешних ресурсов, будь то <img>, <iframe>, fetch() или даже navigator.sendBeacon, все они будут заблокированы CSP.
В заключение, хотя default-src кажется блокирует все внешние соединения, это не так. Есть еще некоторые магические способы передачи данных. Однако, возможно, однажды, когда правила CSP станут более совершенными, будет возможно добиться полностью непроникаемого решения (хотя непонятно, когда настанет этот день).
В этой статье мы рассмотрели некоторые общие методы обхода CSP, и их оказалось довольно много.
Более того, с увеличением количества доменов в CSP становится все сложнее исключить проблемные домены, что добавляет дополнительные риски. Кроме того, использование сторонних сервисов также несет определенные риски, такие как вышеупомянутые общедоступные CDNs или обход CSP Google. Это нужно учитывать.
Написание полностью безопасного CSP на самом деле сложно и требует времени для постепенного устранения небезопасных практик. Однако, в эпоху, когда многие веб-сайты даже не имеют CSP, все еще стоит применить старую поговорку: "Давайте добавим CSP сначала, если есть проблемы, мы можем их отрегулировать позже.".
Я хочу загрузить только React, но мне лень писать полную конфигурацию CSP. Поэтому я написал только , что позволило злоумышленникам загрузить библиотеку csp-bypass, специально разработанную для обхода CSP.
Решение состоит в том, чтобы вовсе избегать использования этих общедоступных CDN или записывать полный путь в конфигурации CSP. Вместо простого пишите .
>Refused to load the script ' because it violates the following Content Security Policy directive: "script-src 'nonce-abc123'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
Хотя это кажется безопасным, было забыто одно: директива base-uri. Эта директива не откладывается до умолчания. Тег используется для изменения местоположения ссылки для всех относительных путей. Например:
Поскольку добавлен <base href="">, скрипт, загружающий app.js, становится , что позволяет злоумышленникам загружать скрипты со своего собственного сервера!
Обычно браузеры препятствуют взаимодействию с веб-страницами не того же источника. Например, выполнение fetch('') в приведет к следующей ошибке:
> Access to fetch at ' from origin ' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Поэтому появился способ обмена данными. Предположим, есть API, который предоставляет данные пользователя, и они предлагают путь вроде . Вместо того чтобы возвращать JSON, он возвращает часть кода JavaScript:
Однако, конкретно заданное имя может быть неудобным. Поэтому общим форматом является , и ответ становится:
Если сервер не проверяет корректность и позволяет передавать любые символы, мы можем использовать такой URL . В этом случае, ответ становится:
Поскольку мы используем Google reCAPTCHA, мы включаем соответствующий скрипт и добавляем в CSP. В противном случае, был бы заблокирован.
Чтобы избежать этой ситуации во время конфигурации, существуют некоторые подходы. Во-первых, сделайте пути более строгими. Например, установите его на вместо , чтобы уменьшить некоторые риски (почему я говорю "уменьшить риски", а не "полностью предотвратить риски"? Вы узнаете позже).
Существует репозиторий под названием , который собирает URL-адреса JSONP из известных веб-сайтов. Хотя некоторые из них были удалены, он все равно может служить референсом.
Существует еще одно понятие, называемое . Идея заключается в том, что, хотя мы можем вызывать только функции, мы также можем исполнять методы на веб-сайте с тем же происхождением.
Есть много ограничений, но это все еще потенциальная вектор атаки. В этом блог-посте под названием "" опубликованном Octagon Networks в 2022 году, автор использовал Same Origin Method Execution (SOME), чтобы установить вредоносный плагин в WordPress.
Однако, согласно описанию в , если перенаправление ведет к другому пути, оно может обойти оригинальные ограничения.
Если CSP установлен на , поскольку учитывается путь, оба скрипта /test и /a/test будут заблокированы CSP.
Однако, последний будет перенаправлен на сервере на . Так как это перенаправление, путь не учитывается, и скрипт может быть загружен, обходя таким образом ограничение пути.
Например, если CSP разрешает путь , он может быть обойден следующим образом:
Браузер в конечном итоге загрузит .
Это работает потому что для браузера вы загружаете файл с именем ..%2fangular%2fangular.js расположенный под , что соответствует CSP.
Однако, для определенных серверов, когда они получают запрос, они будут его декодировать, фактически запрашивая , что эквивалентно .
В данном случае существуют несколько способов передачи данных. Один из способов - использовать window.location = '' + document.cookie для выполнения перенаправления страницы. В настоящее время нет правил CSP, которые могут ограничить этот метод, но в будущем может быть введено правило под названием .
Второй метод - использовать WebRTC, и код следующий из :
В настоящее время нет способа ограничить передачу данных, но в будущем может появиться правило под названием .
Третий метод - предварительный DNS: <link rel="dns-prefetch" href="">. Рассматривая данные, которые вы хотите отправить, в качестве части домена, вы можете передать их через DNS-запросы.
Раньше было такое правило, как , но спецификация изменилась, и теперь эти серии предварительной выборки должны следовать default-src. Chrome имеет эту функцию только начиная с версии 112: .