Qual é a melhor maneira de lidar com conteúdo gerado pelo usuário html que será visto pelo público?

StackOverflow https://stackoverflow.com/questions/1608758

  •  05-07-2019
  •  | 
  •  

Pergunta

Na minha aplicação web que permitem conteúdo gerado pelo usuário a ser publicado para consumo público semelhante ao Stackoverflow.

O que é a melhor prática para entregar isso?

Os meus passos atuais para lidar com conteúdo gerado pelo usuário são:

  1. Eu uso MarkItUp para permitir que os usuários uma maneira fácil de formatar o seu html.

  2. thier Depois que um usuário tenha apresentado muda eu executá-lo através de uma HTML Sanitizer (rolagem para o bottem) que usa uma lista branca abordagem.

  3. Se o processo de desinfecção tem removido qualquer conteúdo criado pelo usuário I não salvar o conteúdo. Eu então Retornar conteúdo modificado lá com um mensagem de aviso, "Alguns ilegal tags de conteúdo, onde detectados e removido verifique o seu trabalho e tente novamente. "

  4. Se o conteúdo passa pela processo de sanitização limpa, eu salvar o conteúdo HTML para o banco de dados.

  5. Ao renderizar ao cliente Eu só passar o html cru fora do db para a página.

Foi útil?

Solução

Isso é uma abordagem completamente razoável. Para aplicações típicas será perfeitamente suficiente.

A parte mais complicada de HTML puro branco-lista é o atributo style e embed / object. Há razões legítimas para que alguém pode querer colocar os estilos CSS em um bloco de outra forma não confiável de texto formatado, ou dizer, um vídeo do YouTube incorporado. Esta questão surge mais comumente com feeds. Você não pode confiar o bloco arbitrário de texto contido dentro de uma entrada de feed, mas você não quer retirar, por exemplo, destaque de sintaxe CSS ou Flash vídeo, porque isso iria mudar fundamentalmente o conteúdo e qualquer potencialmente confundir lê-lo. Porque CSS pode conter coisas perigosas como comportamentos no IE, você pode ter que analisar o CSS se você decidir permitir que o atributo style para estadia em. E com embed / object você pode precisar de branco-lista nomes de host.

Addenda:

Em cenários de pior caso, escapando HTML tudo à vista pode levar a uma experiência de usuário muito pobre. É muito melhor usar algo como um dos analisadores HTML5 para percorrer o DOM com o seu whitelist. Isso é muito mais flexível em termos de como você apresenta a saída higienizado para seus usuários. Você pode até mesmo fazer coisas como:

<div class="sanitized">
  <div class="notice">
    This was sanitized for security reasons.
  </div>
  <div class="raw"><pre>
    &lt;script&gt;alert("XSS!");&lt;/script&gt;
  </pre></div>
</div>

Em seguida, esconder o material .raw com CSS, e usar jQuery para vincular um manipulador de clique ao .sanitized div que alterna entre .raw e .notice:

CSS:

.raw {
  display: none;
}

jQuery:

$('.sanitized').click(function() {
  $(this).find('.notice').toggle();
  $(this).find('.sanitized').toggle();
});

Outras dicas

A lista branca é uma boa jogada. Qualquer solução lista negra está propenso a deixar passar mais do que deveria, porque você simplesmente não pode pensar em tudo. Eu vi algumas attemts do uso de listas negras (por exemplo, o projeto de código), e se eles conseguem pegar tudo, geralmente eles ainda causa problemas adicionais, como substituição de caracteres em código para que ele não pode ser usado sem restaurá-lo manualmente primeiro .

O método mais seguro seria:

  1. HTML codificar todo o texto.

  2. Jogo um conjunto de tags permitidas e atributos e decodificar os.

Usando uma expressão regular que você pode até mesmo exigir que cada tag de abertura tem uma marca de fechamento, de modo que uma tag não fechada não pode mexer-se a página.

Você deve ser capaz de fazer isso em algo como linhas dez de código, de modo que o código que é ligada ao parece muito complicado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top