Разрешение манипуляции с историей кросс-сайтов
Мы разработали новое приложение, и перед перемещением изменений мы сделали статическое сканирование кода с использованием checkmarx. Существует уязвимость среднего уровня, обнаруженная в коде под названием "Манипулирование историей перекрестных сайтов".
Это отключено на странице JSP, где я проверяю значения сеанса:
if(request.getSession().getAttribute("sesStrUID")!=null)
Не могли бы вы помочь мне понять эту уязвимость и что нужно сделать, чтобы устранить это?
3 ответа
Это скорее уязвимость браузера, чем уязвимость веб-сайта в Internet Explorer 2010 года:
Исследовательские лаборатории Checkmarx выявили новую критическую уязвимость в Internet Explorer (другие браузеры, вероятно, подвержены такому же воздействию), которая позволит хакерам легко взломать веб-приложения.
Это является нарушением той же Политики происхождения браузером, и вы не должны исправлять это в своем веб-приложении. Обнаруженная уязвимость, вероятно, относится к перенаправлению, которое вы делаете на основе вашего
request.getSession().getAttribute("sesStrUID")!=null
состояние. Это говорит о том, что если вы перенаправляете серверную часть на основе сеанса sesStrUID
значение, то злоумышленник может IFrame вашего сайта, и если он обнаруживает, что вы перенаправляете, он может определить, sesStrUID
является нулевым или нет.
Это только проблема, если ваши пользователи используют неработающий браузер. Если ваши пользователи используют современные браузеры, то исправлять IMO не стоит. Если вы хотите быть более безопасным, а также защищаться от атак с помощью кликбека, вы можете вывести X-Frame-Options: DENY
Заголовок HTTP, чтобы предотвратить кадрирование. Обратите внимание, что это защитит вас только от версии атаки IFrame. Для других векторов атаки, обсуждаемых подробно, посмотрите эту статью XSHM.
Редактировать после ответа @adar:
Ответ Адара очень похож на мой и содержит почти ту же информацию, за исключением того, что на плакате говорится, что это все еще проблема.
Тем не менее, XSHM не является проблемой, если вы перенаправляете серверную часть через location
HTTP заголовок. HTTP 3xx
перенаправления не вызывают значение history.length
в современных браузерах, поэтому его нельзя использовать для определения того, вошел ли пользователь на конкретный сайт.
Если вы выводите код JavaScript для перенаправления после вашего
if(request.getSession().getAttribute("sesStrUID")!=null)
код, то XSHM является проблемой, если вы перенаправляете на стороне сервера
<%
String redirectURL = "http://example.com/myJSPFile.jsp";
response.sendRedirect(redirectURL);
%>
тогда вы не уязвимы.
Редактировать после ответа @ Адара II:
@adar правильно: если вы попробуете следующий сценарий атаки:
- открыто
Login.jsp
в IFrame - история содержитLogin.jsp
, - открыто
ShowSecretInfo.jsp
- если сервер перенаправляет наLogin.jsp
с HTTP 3xx, затемhistory.length
останется прежним, если сервер покажетShowSecretInfo.jsp
-history.length
будет увеличен на 1.
Поэтому если history.length
увеличивается, вы можете определить, что пользователь вошел в систему. Я мог воссоздать вышеупомянутое с IE 11 и Firefox 33.1 на Windows 7. Chrome 39 не уязвим таким образом из моих тестов, но это в другом:
При условии, что /ShowSecretInfo.jsp
перенаправляет на /Login.jsp
(без запроса), если пользователь не вошел в систему.
- открыто
/ShowSecretInfo.jsp
в IFrame - история содержит/ShowSecretInfo.jsp
, - Установите для IFrame src значение
/Login.jsp
- еслиhistory.length
не увеличивается, то вы знаете, что пользователь вошел в систему.
Похоже, что Chrome не пытается перенаправить, если src
уже установлен на текущий URL. Я также мог бы воссоздать это в IE и Firefox.
Вот ответ, который я получил от Алекса Ройчмана, главного архитектора программного обеспечения @ Checkmarx:
Манипулирование историей между сайтами - это нарушение политики одного и того же источника в браузере, когда можно узнать состояние условия из другого источника. Например, многие сайты проверяют, прошел ли пользователь проверку подлинности, прежде чем показывать ему свои личные данные. Это можно сделать с помощью следующего кода:
If (!IsAuthenticated())
Redirect “login.jsp”
Используя XSHM, можно с другого сайта узнать, прошел ли пользователь аутентификацию на этом сайте.
Теперь давайте посмотрим на данную строку:
if(request.getSession().getAttribute("sesStrUID")!=null)
Эта строка, кажется, проверяет, есть ли у пользователя сеанс или даже он уже прошел проверку подлинности. Поскольку внутри оператора "if" есть "redirect", любой другой сайт может знать, что request.getSession().getAttribute("sesStrUID")!=null
или если пользователь уже был аутентифицирован.
Таким образом, этот результат верен и не имеет ничего общего со старыми или современными браузерами: все современные браузеры предоставляют доступ к history.lengh, это свойство может привести к нарушению конфиденциальности через XSHM, и не существует простого исправления из-за проблем обратной совместимости.
Опции X-Frame: DENY может защитить от версии XSHM IFrame, но старые браузеры не поддерживают эту опцию.
Редактировать после ответа SilverlightFox
Я согласен, у нас очень похожие ответы.
Тем не менее, относительно:
"Перенаправления 3xx не приводят к увеличению значения history.length в современных браузерах"
Это правильно, и XSHM основан именно на этом.
Ищите следующий сценарий атаки:
- Откройте "Login.jsp" в IFrame - теперь история содержит "login.jsp" поверх него.
- Откройте "ShowSecretInfo.jsp" - если сервер перенаправит на "Login.jsp" с 3xx, то history.length останется прежним, если сервер покажет "ShowSecretInfo.jsp" - history.length увеличится на 1.
а это значит, что атакованный пользователь аутентифицирован - нарушение конфиденциальности.
Манипуляции с историей нескольких сайтов (XSHM) - это нарушение безопасности SOP (Политика одинакового происхождения). СОП является наиболее важной концепцией безопасности современных браузеров. SOP означает, что веб-страницы из разных источников не могут общаться друг с другом. Нарушение манипуляции с историей нескольких сайтов основано на том факте, что объект истории браузера на стороне клиента не разделен должным образом для каждого сайта. Управление историей браузера может привести к компрометации SOP, разрешить двунаправленную CSRF и другие эксплойты, такие как: нарушение конфиденциальности пользователя, обнаружение статуса входа в систему, сопоставление ресурсов, вывод конфиденциальной информации, отслеживание активности пользователей и кража параметров URL.
С request.getSession().getAttribute("sesStrUID")
, вы не делаете ничего, что идет в историю браузера, так что похоже на его неправильное обнаружение