Как предотвратить перенаправление IFRAME на окно верхнего уровня
Некоторые веб-сайты имеют код, чтобы "вырваться" из корпусов IFRAME
, что означает, что если страница A
загружается как IFRAME
внутри родительской страницы P
, некоторый Javascript в A
перенаправляет внешнее окно до A
.
Обычно этот Javascript выглядит примерно так:
<script type="text/javascript">
if (top.location.href != self.location.href)
top.location.href = self.location.href;
</script>
Мой вопрос: как автор родительской страницы P
и не являлся автором внутренней страницы A
, как я могу предотвратить A
от выполнения этого прорыва?
P.S. Мне кажется, что это должно быть нарушение межсайтовой безопасности, но это не так.
Ответы
Ответ 1
Попробуйте использовать свойство onbeforeunload, которое позволит пользователю выбрать, хочет ли он перейти от страницы.
Пример: https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload
В HTML5 вы можете использовать свойство песочницы. См. Ответ Панкрата ниже.
http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
Ответ 2
В HTML5 добавлен атрибут iframe sandbox. На момент написания этой статьи работает в Chrome, Safari, Firefox и последних версиях IE и Opera, но в значительной степени делает то, что вы хотите:
<iframe src="url" sandbox="allow-forms allow-scripts"></iframe>
Если вы хотите разрешить перенаправления верхнего уровня, укажите sandbox="allow-top-navigation"
.
Ответ 3
Я использую sandbox = "..."
- allow-forms позволяет отправить форму
- allow-popups позволяет всплывающие окна
- allow-pointer-lock позволяет блокировать указатель
- allow-same-origin позволяет документу сохранять исходный код
- allow-scripts позволяет выполнять JavaScript, а также позволяет автоматически запускать функции
- allow-top-navigation позволяет документу выйти из кадра, перейдя в окно верхнего уровня
Верхняя навигация - это то, что вы хотите предотвратить, поэтому оставьте это, и оно не будет разрешено. Все, что осталось, будет заблокировано
ех.
<iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="http://www.example.com"</iframe>
Ответ 4
Прочитав w3.org spec. Я нашел свойство песочницы.
Вы можете установить sandbox=""
, что предотвращает перенаправление iframe. При этом он не будет перенаправлять IFrame. Вы потеряете клик по существу.
Пример здесь: http://jsfiddle.net/ppkzS/1/
Пример без песочницы: http://jsfiddle.net/ppkzS/
Ответ 5
Я знаю, что прошло много времени с тех пор, как был сделан вопрос, но вот моя улучшенная версия будет ждать 500 мс для любого последующего вызова только при загрузке iframe.
<script type="text/javasript">
var prevent_bust = false ;
var from_loading_204 = false;
var frame_loading = false;
var prevent_bust_timer = 0;
var primer = true;
window.onbeforeunload = function(event) {
prevent_bust = !from_loading_204 && frame_loading;
if(from_loading_204)from_loading_204 = false;
if(prevent_bust){
prevent_bust_timer=500;
}
}
function frameLoad(){
if(!primer){
from_loading_204 = true;
window.top.location = '/?204';
prevent_bust = false;
frame_loading = true;
prevent_bust_timer=1000;
}else{
primer = false;
}
}
setInterval(function() {
if (prevent_bust_timer>0) {
if(prevent_bust){
from_loading_204 = true;
window.top.location = '/?204';
prevent_bust = false;
}else if(prevent_bust_timer == 1){
frame_loading = false;
prevent_bust = false;
from_loading_204 = false;
prevent_bust_timer == 0;
}
}
prevent_bust_timer--;
if(prevent_bust_timer==-100) {
prevent_bust_timer = 0;
}
}, 1);
</script>
и onload="frameLoad()"
и onreadystatechange="frameLoad();"
должны быть добавлены в фрейм или iframe.
Ответ 6
Я нашел некоторые полезные хаки по этому поводу:
Использование JS, как я могу остановить дочерние iframes от перенаправления или, по крайней мере, приглашать пользователей о перенаправлении
http://www.codinghorror.com/blog/2009/06/we-done-been-framed.html
http://coderrr.wordpress.com/2009/02/13/preventing-frame-busting-and-click-jacking-ui-redressing/
Ответ 7
Так как страница, которую вы загружаете внутри iframe, может выполнять код "break out" с помощью setInterval, onbeforeunload может быть не таким практичным, поскольку он может помешать пользователю "Вы уверены, что хотите покинуть"? Диалоги.
Существует также атрибут безопасности iframe, который работает только в IE и Opera
: (
Ответ 8
В моем случае я хочу, чтобы пользователь посетил внутреннюю страницу, чтобы сервер увидел свой ip в качестве посетителя. Если я использую технологию php proxy, я думаю, что внутренняя страница увидит мой ip-сервер в качестве посетителя, так что это не хорошо. Единственное решение, которое я получил до сих пор, - это быть впереди.
Поместите это на свою страницу:
<script type="text/javascript">
window.onbeforeunload = function () {
return "This will end your session";
}
</script>
Это работает как в firefox, так и в том, что я тестировал.
вы найдете версии, используя что-то вроде evt.return(что угодно) дерьмо... что не работает в firefox.
Ответ 9
Поступая таким образом, вы сможете контролировать любое действие на странице с рамкой, которой вы не можете. применяется политика происхождения одного домена.