Как запретить meta - http-equiv="refresh"?
HTML-код типа
<meta http-equiv="refresh" content="10;URL=http://site.net">заставляет перегрузиться страницу (в данном примере) через 10 секунд. Можно ли с помощью javascript пресечь эту перезагрузку? Как известно, в теге meta content устанавливает значение атрибута, заданного с помощью name или http-equiv, а http-equiv предназначен для конвертирования метатега в заголовок HTTP. Но я не пойму, чей это атрибут "refresh"? То есть, можно ли его очистить, убить напрочь, чтобы перезагрузка не произошла? Решение с обработкой события onbeforeunload мне видится бестолковым. |
Цитата:
|
Маэстро,
Решали подобную задачу путём заворачивания в noscript <noscript> <meta http-equiv="refresh" content="10;URL=http://site.net"> </noscript> Насчёт JS решения не в курсе |
Цитата:
К сожалению, как только сделано DIV.innerHTML = '<meta http-equiv="refresh" content="10;URL=http://site.net">';, так браузер запускает таймер до взрыва... |
Цитата:
Да это работает. Проверил только что в IE 11 и FireFox. К моему удивлению это не работает в Gooogle Chrome. :( |
Маэстро,
Noscript - это не запрет выполнения сценария. Содержимое тега отобразится / сработает, если браузер не поддерживает скрипты или они отключены. Значит, если подключены, то содержимое игнорируется. MDN Насчёт Chrome пишут, что это известный баг. Иногда это "лечат" путём перезагрузки, но в Вашем случае, получается, это не выход совсем. |
Цитата:
|
Цитата:
Цитата:
Цитата:
Кстати, в одном из продуктов Гугла есть именно эта уязвимость. Но в Гугл я писать не буду. |
Цитата:
|
как вариант
<meta http-equiv="refresh" content="10;URL=http://site.net"> <script>window.stop();</script>:D |
Цитата:
я написал свой вопрос на форум, чтобы услышать от специалистов ответ. Но разговор поворачивается таким образом, что я всё больше отвечаю на Ваши вопросы, а не получаю ответ. Вы мыслите совершенно правильными классическими категориями, но... уже устаревшими. Известное правило "не доверять клиенту ни в чём" породило правило: "вся защита на сервере". А пробовали построить всю защиту на клиенте? имеется ввиду не при отправке данных на сервер, а при приёме. Я разработал такой механизм. Он перекрывает все известные мне уязвимости (их много). Но с "meta-refresh" есть проблемы (и то в частных случаях). Не старайтесь понять зачем мне это надо. Старайтесь помочь, если можете. |
Madzal,
это интересно. В частности, что window.stop() останавливает загрузку окна, а не последующий выполняемый скрипт. Простой тест показал положительный результат! Поисследую способ подробнее. Если будут какие-то неприятности - сообщу. Спасибо! |
Вы мыслите совершенно правильными классическими категориями, но... уже устаревшими.
Даже так, ну-ну, решайте вопросы безопасности исключительно на клиенте, оставляя сервер пассивным участником. Кошмар да и только. я всё больше отвечаю на Ваши вопросы, а не получаю ответ. Я вам уже ответил во втором посте в вопросе, но вы же пионер-первопроходец, а я консервант, вот вы и маетесь дурью. :) |
Цитата:
Вы предложили использовать htmlspecialchars . Это преобразует специальные символы в HTML-сущности. А мне не надо обезвредить ВСЕ html-теги, сделав их тупо видимыми. К тому же в тексте, отправляемом с сервера есть полезные html-теги, которые должны как положено отработать на клиенте. Я ещё мог бы согласиться с Вами, если бы предложили использовать strip_tags (удаляет HTML и PHP-теги из строки). Однако, из-за того, что strip_tags() не проверяет валидность HTML, то частичные или сломанные теги могут послужить удалением большего количества текста или данных, чем ожидалось! Просто говоря в некоторых случаях клиент увидит чистую страницу. И это плохо. Сам браузер лучше распарсит такой html, т.к. нет лучше "серверного парсера", чем сам браузер! Предположим, что скоро разработчики PHP напишут более умный серверный парсер, но... дело в том, что этого мало. На самом деле задача не просто обеспечить защиту на стороне клиента, а еще и сделать умный разбор html-тегов: распарсить все их атрибуты и все их свойства, проверить валидность и прочее. Назовите мне хотя бы 1 серверный парсер для этого? И если Вы "консервант", то попробуйте решить такую задачку (на стороне сервера): в html-коде найти все теги IMG, проверить их width и если ширина указана в px, то заменить width на "100%". 111111<img width="2000px" style="width:2000px" src=http://site.net/pic.jpg>222222Получится? - Сниму шляпу! Цитата:
|
Цитата:
Ну а то что "устаревшие понятия", то решить вопросы безопасности сервера без сервера, а веб приложение это сервер как не крути, нельзя, это объективность. А в случае описанном в данном посте, чему-то разрешить работать, то клиент вынужден постоянно парсить, анализировать, запрещать при каждой загрузке документа огромной армией пользователей, а делать это надо один раз при сохранении документа, но только более разумным, чем strip_tags, и средств для этого предостаточно. Уже с точки зрения нагрузки на клиента не разумно клиенту этим заниматься. Цитата:
|
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
|
Цитата:
Хорошая новость в том, что это работает и в Google Chrome и пресекает загрузку страницы, но не останавливает работу JS-скриптов (это хорошо). Плохая новость: IE11 при window.stop() останавливает ВСЁЁЁ! Подумываю об объединении варианта от Alexander Belov и Вашего вместе.. Вот только не хочется привязываться к конкретным браузерам. Это сейчас плохой тон. А то потом придется ещё рассматривать и разные версии этих браузеров.. |
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
|
мы с вами на разных полюсах. и от вас всё больше эмоций, а не конкретных строк js. поэтому дальше не вижу смысла спорить.
ладно, жизнь покажет кто прав. p.s. а задачка про IMG в моем сообщении 12:15. |
Цитата:
Про IMG, ага есть такое, и не говорите - задача для REGEXP коим обладает сервер, и который намного богаче REGEXP JS, просто неразрешимая. :) |
Господа, я нашел решение данной проблемы. Для тех, кто интересуется обработкой данных на клиенте (а не на сервере) рассказываю.
Постановка задачи: в веб-приложении есть контейнер (DIV), в который с помощью AJAX поступает строка HTML-кода "s". Источники содержимого "s" могут быть разные. Нет 100-й гарантии, что в полученном тексте отсутствует зловредный HTML-код. Такой код надо обезвредить. При этом "нормальные" теги должны отработать как положено.В примере топика к зловредному коду отношу тег meta с атрибутом refresh, что приводит к перезагрузке страницы и перенаправлению на другой сайт. Как решить? Казалось бы просто: найти в DOM соответствующий тег и стереть его атрибут. Для других (известных мне тегов) это работает. Но почему-то не работало для <meta>. <html><body> <script> var o=document.createElement('DIV'); document.body.appendChild(o); function mytest() { // присваиваем контейнеру html-строку, которая содержит что-то... o.innerHTML = s; }; // строка текста, которая может содержать тег meta... var s = '<div>111<meta http-equiv="refresh" content="3;URL=http://javascript.ru"></div><div>222</div><br>333<meta http-equiv="refresh" content="3;URL=http://javascript.ru"><meta name="refresh" content="3;URL=http://vk.com">444'; </script> <input type="button" value="Нажмите - произойдёт перезагрузка." onclick= mytest()> </body></html> Попробуем обезвредить: <html><body> <script> var o=document.createElement('DIV'); document.body.appendChild(o); function find_remove_META(o) { var metatags = o.getElementsByTagName('META'); for (var i = 0; i < metatags.length; i++) { // удаляем атрибут http-equiv="refresh"; // этого уже достаточно, но лучше удалить все атрибуты тега metatags[i].removeAttribute('http-equiv'); } }; function mytest() { // присваиваем контейнеру html-строку, которая содержит что-то... o.innerHTML = s; find_remove_META(o); }; // строка текста, которая может содержать тег meta... var s = '<div>111<meta http-equiv="refresh" content="3;URL=http://javascript.ru"></div><div>222</div><br>333<meta http-equiv="refresh" content="3;URL=http://javascript.ru"><meta name="refresh" content="3;URL=http://vk.com">444'; </script> <input type="button" value="Нажмите - опять перезагрузка??" onclick= mytest()> </body></html> К сожалению, несмотря на удаление зловредного свойства перезагрузка произойдёт. Так вот, фишка в том, что если перед присвоением html-кода контейнеру предварительно извлечь его из дерева DOM (лишить парента) и только потом произвести чистку тега meta, то всё будет хорошо. По окончании процедуры вставим контейнер на своё место. В упрощенном виде это выглядит так: <html><body> <script> var o=document.createElement('DIV'); document.body.appendChild(o); function find_remove_META(o) { var metatags = o.getElementsByTagName('META'); for (var i = 0; i < metatags.length; i++) { // удаляем атрибут http-equiv="refresh"; // этого уже достаточно, но лучше удалить все атрибуты тега metatags[i].removeAttribute('http-equiv'); } }; function mytest() { o.parentNode.removeChild(o) // присваиваем контейнеру html-строку, которая содержит что-то... o.innerHTML = s; find_remove_META(o); document.body.appendChild(o); }; // строка текста, которая может содержать тег meta... var s = '<div>111<meta http-equiv="refresh" content="3;URL=http://javascript.ru"></div><div>222</div><br>333<meta http-equiv="refresh" content="3;URL=http://javascript.ru"><meta name="refresh" content="3;URL=http://vk.com">444'; </script> <input type="button" value="Нажмите - перезагрузки не должно произойти." onclick= mytest()> </body></html> Чтобы не манипулировать контейнером (removeChild/appendChild) можно создать "теневой" контейнер (который создан, но никуда не вставлен) и работать с ним. А после чистки html-кода брать его innerHTML и вставлять в другой, видимый на экране контейнер. |
Часовой пояс GMT +3, время: 12:52. |