É possível dizer aos navegadores para não executarem JavaScript de partes específicas de um documento HTML?
Gostar:
<div script="false"> ...
Pode ser útil como um recurso de segurança adicional. Todos os scripts que desejo são carregados em uma parte específica do documento. Não deve haver scripts em outras partes do documento e, se houver, não devem ser executados.
javascript
html
script-tag
Seppo Erviälä
fonte
fonte
script-src:"self"
você permite que apenas scripts de seu domínio sejam executados na página. Se você estiver interessado, leia este artigo de Mike West sobre CSP .</div>
para fechar este elemento DOM e, em seguida, iniciar um novo<div>
que será irmão daquele em que os scripts não estão sendo executados?Respostas:
SIM, você pode :-) A resposta é: Política de Segurança de Conteúdo (CSP).
A maioria dos navegadores modernos suporta este sinalizador , que diz ao navegador apenas para carregar o código JavaScript de um arquivo externo confiável e desabilitar todo o código JavaScript interno! A única desvantagem é que você não pode usar nenhum JavaScript embutido em sua página inteira (não apenas em uma
<div>
). Embora possa haver uma solução alternativa, incluindo dinamicamente o div de um arquivo externo com uma política de segurança diferente, mas não tenho certeza sobre isso.Mas se você pode alterar seu site para carregar todo o JavaScript de arquivos JavaScript externos, você pode desativar o JavaScript embutido completamente com este cabeçalho!
Aqui está um bom tutorial com exemplo: HTML5Rocks Tutorial
Se você puder configurar o servidor para enviar esta bandeira HTTP-Header, o mundo será um lugar melhor!
fonte
Você pode bloquear o JavaScript carregado por
<script>
, usando obeforescriptexecute
evento:<script> // Run this as early as possible, it isn't retroactive window.addEventListener('beforescriptexecute', function(e) { var el = e.target; while(el = el.parentElement) if(el.hasAttribute('data-no-js')) return e.preventDefault(); // Block script }, true); </script> <script>console.log('Allowed. Console is expected to show this');</script> <div data-no-js> <script>console.log('Blocked. Console is expected to NOT show this');</script> </div>
Observe que
beforescriptexecute
foi definido no HTML 5.0, mas foi removido no HTML 5.1. O Firefox é o único navegador importante que o implementou.Caso você esteja inserindo um monte de HTML não confiável em sua página, esteja ciente de que o bloqueio de scripts dentro desse elemento não fornecerá mais segurança, porque o HTML não confiável pode fechar o elemento em sandbox e, portanto, o script será colocado fora e executado.
E isso não vai bloquear coisas como
<img onerror="javascript:alert('foo')" src="//" />
.fonte
beforescriptexecute
eventos. Funciona no Firefox.beforescriptexecute
parece que não é compatível e não será compatível com a maioria dos navegadores principais. developer.mozilla.org/en-US/docs/Web/Events/beforescriptexecutePergunta interessante, não acho que seja possível. Mas mesmo que seja, parece que seria um hack.
Se o conteúdo desse div não for confiável, você precisará escapar dos dados no lado do servidor antes que eles sejam enviados na resposta HTTP e renderizados no navegador.
Se você deseja apenas remover
<script>
tags e permitir outras tags html, apenas retire-as do conteúdo e deixe o resto.Verifique a prevenção de XSS.
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
fonte
JavaScript é executado "inline", ou seja, na ordem em que aparece no DOM (se não fosse esse o caso, você nunca poderia ter certeza de que alguma variável definida em um script diferente estava visível quando você o usou pela primeira vez )
Isso significa que, em teoria, você poderia ter um script no início da página (ou seja, o primeiro
<script>
elemento) que examina o DOM e remove todos os<script>
elementos e manipuladores de eventos dentro do seu<div>
.Mas a realidade é mais complexa: o carregamento do DOM e do script ocorre de forma assíncrona. Isso significa que o navegador apenas garante que um script possa ver a parte do DOM que está antes dele (ou seja, o cabeçalho até agora em nosso exemplo). Não há garantias para nada além de (isso está relacionado a
document.write()
). Então você pode ver a próxima tag de script ou talvez não.Você poderia travar o
onload
evento do documento - o que garantiria que você obtivesse todo o DOM - mas, naquele momento, o código malicioso já poderia ter sido executado. As coisas pioram quando outros scripts manipulam o DOM, adicionando scripts lá. Portanto, você também teria que verificar todas as alterações do DOM.Portanto, a solução @cowls (filtragem no servidor) é a única solução que pode funcionar em todas as situações.
fonte
Se você deseja exibir o código JavaScript em seu navegador:
Usando JavaScript e HTML, você terá que usar entidades HTML para exibir o código JavaScript e evitar que esse código seja executado. Aqui você pode encontrar a lista de entidades HTML:
Se você estiver usando uma linguagem de script do lado do servidor (PHP, ASP.NET, etc.), muito provavelmente, há uma função que escaparia de uma string e converteria os caracteres especiais em entidades HTML. Em PHP, você usaria "htmlspecialchars ()" ou "htmlentities ()". O último cobre todos os caracteres HTML.
Se você deseja exibir seu código JavaScript de uma maneira agradável, tente um dos marcadores de código:
fonte
Eu tenho uma teoria:
noscript
tag.script
tags dentro danoscript
tag e desembrulhe seu conteúdo.Exemplo de prova de conceito:
window.onload = function() { var noscripts = /* _live_ list */ document.getElementsByTagName("noscript"), memorydiv = document.createElement("div"), scripts = /* _live_ list */ memorydiv.getElementsByTagName("script"), i, j; for (i = noscripts.length - 1; i >= 0; --i) { memorydiv.innerHTML = noscripts[i].textContent || noscripts[i].innerText; for (j = scripts.length - 1; j >= 0; --j) { memorydiv.removeChild(scripts[j]); } while (memorydiv.firstChild) { noscripts[i].parentNode.insertBefore(memorydiv.firstChild, noscripts[i]); } noscripts[i].parentNode.removeChild(noscripts[i]); } };
body { font: medium/1.5 monospace; } p, h1 { margin: 0; }
<h1>Sample Content</h1> <p>1. This paragraph is embedded in HTML</p> <script>document.write('<p style="color: red;">2. This paragraph is generated by JavaScript</p>');</script> <p>3. This paragraph is embedded in HTML</p> <h1>Sample Content in No-JavaScript Zone</h1> <noscript> <p>1. This paragraph is embedded in HTML</p> <script>document.write('<p style="color: red;">2. This paragraph is generated by JavaScript</p>');</script> <p>3. This paragraph is embedded in HTML</p> </noscript> <noscript> <p>1. This paragraph is embedded in HTML</p> <script>document.write('<p style="color: red;">2. This paragraph is generated by JavaScript</p>');</script> <p>3. This paragraph is embedded in HTML</p> </noscript>
fonte
<noscript>
tag e injetar o que quiserem.Se você quiser reativar as tags de script mais tarde, minha solução foi interromper o ambiente do navegador para que qualquer script executado gerasse um erro bem cedo. No entanto, não é totalmente confiável, então você não pode usá-lo como um recurso de segurança.
Se você tentar acessar as propriedades globais, o Chrome lançará uma exceção.
setTimeout("Math.random()") // => VM116:25 Uncaught Error: JavaScript Execution Inhibited
Estou substituindo todas as propriedades substituíveis em
window
, mas você também pode expandi-lo para interromper outra funcionalidade.window.allowJSExecution = inhibitJavaScriptExecution(); function inhibitJavaScriptExecution(){ var windowProperties = {}; var Object = window.Object var console = window.console var Error = window.Error function getPropertyDescriptor(object, propertyName){ var descriptor = Object.getOwnPropertyDescriptor(object, propertyName); if (!descriptor) { return getPropertyDescriptor(Object.getPrototypeOf(object), propertyName); } return descriptor; } for (var propName in window){ try { windowProperties[propName] = getPropertyDescriptor(window, propName) Object.defineProperty(window, propName, { get: function(){ throw Error("JavaScript Execution Inhibited") }, set: function(){ throw Error("JavaScript Execution Inhibited") }, configurable: true }) } catch (err) {} } return function allowJSExecution(){ for (var propName in window){ if (!(propName in windowProperties)) { delete windowProperties[propName] } } for (var propName in windowProperties){ try { Object.defineProperty(window, propName, windowProperties[propName]) } catch (err) {} } } }
fonte