Предотвращение автоматической ссылки на ссылку XSS-атака с использованием CSP

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

Политика безопасности содержимого:

default-src 'none'; script-src 'unsafe-inline';

И тело:

<a href="#" onclick="location.href='http://www.google.com'; return false;">test</a>
<script>
  document.querySelector("a").click();
</script>

Очевидно, что в реальной атаке вы сначала включаете информацию о файлах cookie в поле href и, возможно, переносите это в скрытый self-embedding iframe или переадресовываете домен обратно туда, откуда вы пришли (потенциально с дополнительными параметрами URL-адреса таким образом создавая своего рода XMLHttpRequest, минуя connect-src), но этот базовый пример показывает проблему.

Есть ли способ предотвратить это с помощью CSP (который все еще разрешает выполнение Javascript)?


Подобные атаки

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

Непосредственное объяснение стороны

Из-за всей путаницы, как это может быть применимо даже без script-src: 'unsafe-inline'. Представьте следующий файл с именем api.ext

print URLParameters.method
[...]

Затем этот файл можно вызвать как api.ext?method=<script src='api.ext?method=alert("test")//'></script><!-- (за исключением того, что вам потребуется дополнительная кодировка URL и прочее, это просто для того, чтобы получить точку). Найти подобные действия сложно, и они довольно редки, но такие вещи, как connect-src, похоже, существуют, чтобы предотвратить утечку информации даже в этих случаях.

Ответы

Ответ 1

Это вряд ли будет удовлетворительным подходом - и, очевидно, он не основан на CSP, но это может быть ваш единственный вариант, если вам действительно нужно предотвратить такие атаки. Прежде чем использовать что-либо подобное, убедитесь, что нет возможности отключить встроенные скрипты (которые должны охватывать большинство атак). Кроме того, вы должны отправить свои отзывы в рассылку [email protected] с темой [CSP2].

Здесь моя (неполная) идея:

function guardMethods(clazz, methodNames, urlGetter, allowFilter, reportViolation) {
    var prototype = clazz.prototype;
    methodNames.forEach(function (methodName) {
        var originalMethod = prototype[methodName];
        if (originalMethod) {
            Object.defineProperty(prototype, methodName, {
                value: function () {
                    var url = urlGetter.apply(this, arguments) || '';
                    if (allowFilter(url)) {
                        return originalMethod.apply(this, arguments);
                    } else {
                        reportViolation(url);
                    }
                }
            });
        }
    })      
}

function allowFilter(url) {
    // todo: implement
}

function reportViolation(url) {
    console.error('Redirection prevented:', url);
}

guardMethods(HTMLAnchorElement, ['click', 'dispatchEvent', 'fireEvent'], function () {return this.href}, allowFilter, reportViolation);

Вам придется реализовать аналогичные защитные функции для location, location.href, window.open и других функций/свойств/событий, которые позволяют перенаправить на другие страницы. Если вы пропустите только один, вы все еще уязвимы. Формы, XHR и большинство других ресурсов могут быть покрыты CSP. Насколько я знаю, прототип взлома не работает в некоторых старых браузерах.

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

Ответ 2

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

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

Если вам нужно запустить код JavaScript, но вы не можете доверять этому коду, вы можете обслуживать страницу с помощью директивы sandbox без флага allow-same-origin. С помощью этой директивы CSP страница будет запускаться с уникальным источником безопасности, который не имеет общего состояния (то есть файлы cookie, хранилища DOM, базы данных и т.д.) С отображаемым источником. Следовательно, вложенные скрипты не могут утечки информации, потому что они не могут получить информацию в первую очередь.

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

default-src 'none'; script-src 'unsafe-inline'; sandbox allow-scripts

Не утруждайте себя черным списком методов JavaScript, как это предлагается другим ответом, потому что 1) вы всегда будете игнорировать метод и 2) отключение JavaScript API может неожиданно нарушить ваше веб-приложение, а 3) злоумышленнику требуется только одно отверстие нанести ущерб, а ваше (обычное) приложение, вероятно, содержит по крайней мере один метод, который может быть атакован злоумышленником.

Ответ 3

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


default-src 'none';

Это ужесточает политику, позволяющую без каких-либо XHR/Fetch/WebSockets/CSS/Font/JavaScript/Plugin. Все они имеют свои соответствующие свойства, но в их отсутствие используется свойство default. Вы не пытались сделать что-либо из этого в своем javascript.

script-src 'unsafe-inline';

Это смягчает политику, позволяющую использовать любой javascript, который встроен в используемую страницу. Это включает onclick/onhover и все семейство небезопасных атрибутов. Чтобы процитировать спецификацию:

В любом случае авторы НЕ ДОЛЖНЫ включать "небезопасные-встроенные" или данные: как действующие источники в своих политиках. Оба варианта включают атаки XSS, позволяя включать код непосредственно в самом документе; их лучше всего избегать.

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