sexta-feira, janeiro 23, 2015

Sanitizar HTML por javascript

O significado da palavra sanitizar neste contexto significa limpar o HTML de código potencialmente malicioso, seja ele introduzido propositadamente (na maior parte das vezes) ou seja inadvertidamente por desconhecimento. No caso de utilizar a sanitização por javascript é importante notar que estamos a sanitizar HTML que apenas pode estar errado por desconhecimento de quem o insere, ou então é necessário voltar a revalidar a sanitização do lado do servidor, pois quem quer introduzir especificamente código malicioso facilmente ultrapassará uma limpeza por javascript.

Estando esta salvaguarda feita e querendo eu fazer a sanitização por javascript, andei à procura de algumas bibliotecas de javascript que me pudesse auxiliar, pois de certeza que já mais gente precisou disto. Acabei por fazer uma pré selecção das 3 seguintes:
A primeira é uma biblioteca que inclusivamente é utilizada pelo google, mas ao ler a documentação não  fiquei esclarecido  como se utilizavam as whitelist, e como estava a perder já mais tempo do que eu achava que era razoável acabei por desistir de usar esta biblioteca, inclusivamente ainda andei a olhar o código desta biblioteca e não fiquei convencido que suporte whitelists, mas ao mesmo tempo acho estranho que algo utilizado pelo Google seja tão limitado!

A terceira biblioteca utiliza outras bibliotecas do NPM, e como considerei que era um absurdo a quantidade de bibliotecas que era necessário fazer download para algo tão simples como limpar HTML não gostei muito da solução.

Acabei por escolher a 2ª opção, simples, e em menos de 30 minutos tinha o meu problema resolvido. Gostei da flexibilidade como são definidas as whitelists, não gostei dos nomes das API, não são nada indicativos do que são mas olhando a documentação rapidamente se percebe como se faz. Já existem 3 whitelists disponibilizadas pela biblioteca com diferentes níveis de restrições mas é facílimo definir novas whitelists personalizadas. Deixo aqui um pequeno exemplo de uma possível implementação:

    var sanitizer = new Sanitize({
        elements: ['p','h1','h2','h3','a','b','i','br','ul','ol','li'],
        attributes: {
            a: ['href'],
            '__ALL__': ['width', 'height']
        },
        protocols: {
            a: { href: ['https'] }
        }
    });

    $(".inputToSanitize").each(function (index) {
            
            var sanitized = sanitizer.clean_node($(this).html());
            $(this).html(sanitized);
    }

Sem comentários: