Fortify SCA сообщает, что следующий код уязвим для DOM XSS:
const returnUrl = sessionStorage.getItem('returnUrl') || '/';
window.location.href = returnUrl;
Когда пользователь входит в мое приложение, например, щелкнув ссылку, и пользователь не вошел в систему:
window.location.href
в returnUrl
элемент в хранилище сеансов.window.location.href
на внешнюю страницу входаlogged-in.html
страницу моего приложения.logged-in.html
содержит приведенный выше код, устанавливающий window.location.href
значение, хранящееся в returnUrl
элементе хранилища сеанса.Почему это уязвимо? Как я могу смягчить это?
Обновлено: Я не выполнял Fortify, это сделала внешняя компания и сообщила следующее:
КВЕ-80. Проверка ввода и Представление: Межсайтовый скриптинг: ДОМ
Итак, что произойдет, если скрипт на странице сделает sessionStorage.setItem("returnUrl", "theattackerdomain.com")
?
@VLAZ, чтобы это было возможно, мое приложение должно быть успешно атаковано, чтобы внедрить этот код. Верно?
Я не знаю, как работает ваше приложение. Возможно, вы используете внешние скрипты, которые уже уязвимы, поэтому для проявления атаки не требуется много времени. Или, кто знает, у вас может быть какая-то другая XSS-уязвимость. Или у вас его нет сейчас, но он может появиться в будущем — через 15 месяцев, когда вы бы забыли об этом отчете Fortify. В конце концов, так ли это важно? Ясно, что процесс уязвим для довольно простого вмешательства в приложение.
@Т.Дж.Краудер. Я не запускал Fortify, это сделала внешняя компания и сообщила следующее: CWE-80. Проверка входных данных и представление: Межсайтовый скриптинг: DOM
Вы не должны доверять никаким внешним данным, даже SessionStorage, данные могут быть подделаны перед их сохранением (также они могут быть подделаны при хранении на зараженном устройстве). Вот почему вы всегда должны проверять внешние данные перед использованием.
@ВЛАЗ. Это приложение Angular, оно загружает все скрипты с сервера веб-приложений, кроме logedd-in.html, который загружает alcdn.msauth.net/browser/2.22.1/js/msal-browser.min.js. Если кто-то может вводить sessionStorage.setItem("returnUrl", "theattackerdomain.com")
, он может вводить и window.location.href = "theattackerdomain.com"
, так какой в этом смысл?
@Тему. Спасибо. Итак, вы предлагаете проверить значение returnUrl
?. Я могу легко проверить домен и протокол, но проверить путь и строку запроса очень сложно, так как их много.
@JesúsLópez ¯\_(ツ)_/¯ Ну, я думаю, просто не делайте никаких проверок, не принимайте никаких мер предосторожности, основанных на здравом смысле, и просто заново изобретите, как выполняется перенаправление после входа в систему. Возможно, вы нашли схему перенаправления, возможности которой не смогли реализовать все другие веб-приложения. Они, да и сама Fortify, наверное, ошибаются.
Проверка протокола и домена уже будет большим подспорьем, так как посетитель не сможет перейти на сайт злоумышленника.
@ВЛАЗ. Я не изобретаю ничего нового. Получение returnUrl из хранилища сеансов — это именно то, что делает библиотека @azure/msal-browser от Microsoft. Мне просто нужно знать, почему это уязвимо и как его смягчить. не могу убрать эту функцию
@Тему. Не могли бы вы сделать свои комментарии в качестве ответа? Что-то вроде: «Он уязвим, потому что sessionStorage не заслуживает доверия. Устройство может быть заражено, а sessionStorage может быть подделан».
@JesúsLópez Это только часть истории. Было сложно найти объяснение этому в Fortify, мне удалось найти только этот исходник на Github. Как необработанный XML, его немного трудно читать, но есть полное объяснение этой конкретной ошибки аудита безопасности.
Как я могу смягчить это?
Не сохраняйте полный URL-адрес, просто сохраните необходимую информацию (например, имя страницы или даже значение, подобное перечислению, которое идентифицирует страницу, на которую нужно перейти). Затем, вернувшись на страницу, проверьте данные из хранилища сеансов, прежде чем создавать URL-адрес только из известных значений и проверенных значений:
const returnInfo = JSON.parse(sessionStorage.getItem("returnUrl"));
if (returnInfo && validatePageName(returnInfo.pageName) && /*...*/) {
window.location.href = "/" + returnInfo.pageName; // Or similar
}
... где validatePageName
гарантирует, что переданная ему строка является просто именем страницы в вашем приложении, а не (например) полным URL-адресом.
Или, если это слишком большое изменение, по крайней мере, проверьте URL-адрес перед его использованием:
const returnUrl = new URL(
sessionStorage.getItem("returnUrl") || "/"),
location
);
if (
returnUrl.protocol === location.protocol &&
returnUrl.port === location.port &&
returnUrl.hostname === location.hostname &&
/*...other checks as necessary ...*/
) {
window.location.href = returnUrl;
}
О какой конкретной ошибке сообщает Fortify SCA? Пожалуйста, используйте копирование и вставку, чтобы добавить его к вопросу (с
>
впереди, поэтому отметьте его как цитируемый).