Blog de Blank: http://www.planabc.net/
O uso de atributos InnerHTML é muito popular porque fornece uma maneira simples de substituir completamente o conteúdo de um elemento HTML. Outro método é usar a API DOM Nível 2 (RemoveChild, CreateElement, AppendChild). Mas é óbvio que o uso do InnerHTML para modificar a árvore dom é uma maneira muito fácil e eficaz. No entanto, você precisa saber que o InnerHTML tem alguns problemas com seus próprios:
Existem várias outras desvantagens menores, que valem a pena mencionar:
Estou mais preocupado com questões de segurança e memória relacionadas ao uso de propriedades no InnerHTML. Obviamente, esse não é um problema novo, e já existem pessoas que inventaram maneiras de contornar alguns desses problemas.
Douglas Crockford escreve uma função de limpeza que aborta algumas referências de loop causadas pelas funções de manuseio de eventos de registro de elementos HTML e permite que o coletor de lixo livre de memória associado a esses elementos HTML.
A remoção de tags de script de strings HTML não é tão fácil quanto parece. Uma expressão regular pode alcançar o efeito desejado, embora seja difícil saber se todas as possibilidades são cobertas. Aqui está minha solução:
/<script [^>]*> [/s/s]*? <// script [^>]*>/ig
Agora, vamos combinar as duas técnicas em uma função SetinnerHTML separada e ligar a função setInnerHtml ao yahoo.util.dom em yui:
Yahoo.util.dom.setinnerhtml = função (el, html) {
el = yahoo.util.dom.get (el);
if (! el || typeof html! == 'string') {
retornar nulo;
}
// abortar referência circular
(função (o) {
var a = o.attributes, i, l, n, c;
se (a) {
L = A.Length;
for (i = 0; i <l; i = 1) {
n = a [i] .Nome;
if (typeof o [n] === 'function') {
o [n] = nulo;
}
}
}
a = O.ChildNodes;
se (a) {
L = A.Length;
for (i = 0; i <l; i = 1) {
c = O.ChildNodes [i];
// Limpe nós da criança
argumentos.Callee (C);
// Remova todos os ouvintes registrados com elementos através do addlistener de Yui
Yahoo.util.event.purgeElement (c);
}
}
}) (el);
// Remova o script da string html e defina a propriedade InnerHTML
el.innerhtml = html.replace (/<script [^>]*> [/s/s]*? <// script [^>]*>/ig,);
// retorna a referência ao primeiro nó filho
retornar El.Firstchild;
};
Se essa função deve ter mais alguma coisa ou algo faltando no regex, por favor me avise.
Obviamente, existem muitas outras maneiras de injetar código malicioso na página da web. A função setInnerHTML só pode normalizar o comportamento de execução das tags <Script> em todos os navegadores de grau A. Se você estiver pronto para injetar código HTML em que não pode confiar, não se esqueça de filtrar primeiro o servidor e já existem muitas bibliotecas que podem fazer isso.
Texto original: "O problema de Julien Lecomte com Innerhtml"