Permitir trechos de código na entrada de formulário e evitar ataques de injeção XSS e SQL

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

Pergunta

Como permitir que trechos de código sejam inseridos em um editor (como faz o stackoverflow) como o FCKeditor ou qualquer outro editor, evitando XSS, injeção de SQL e ataques relacionados.

Foi útil?

Solução

Parte do problema aqui é que você deseja permitir certos tipos de HTML, certo?Links por exemplo.Mas você precisa limpar apenas as tags HTML que podem conter ataques XSS, como tags de script ou até mesmo atributos do manipulador de eventos ou um href ou outro atributo começando com "javascript:".E assim uma resposta completa à sua pergunta precisa ser algo mais sofisticado do que "substituir caracteres especiais" porque isso não permitirá links.

A prevenção da injeção de SQL pode depender um pouco da sua escolha de plataforma.Minha plataforma web preferida possui uma sintaxe integrada para parametrizar consultas que evitarão principalmente a injeção de SQL (chamada cfqueryparam).Se você estiver usando PHP e MySQL, existe uma função nativa semelhante mysql_escape().(Não tenho certeza se a função PHP cria tecnicamente uma consulta parametrizada, mas funcionou bem para mim na prevenção de tentativas de injeção de sql até agora, já que vi algumas que foram armazenadas com segurança no banco de dados.)

Na proteção XSS, eu costumava usar expressões regulares para limpar entradas por esse tipo de motivo, mas desde então me afastei desse método devido à dificuldade envolvida em permitir coisas como links e ao mesmo tempo remover o código perigoso.O que mudei como alternativa é o XSLT.Novamente, a forma como você executa uma transformação XSL pode variar dependendo da sua plataforma.escrevi um artigo para o ColdFusion Developer's Journal há algum tempo sobre como fazer isso, que inclui tanto um folha XSL padrão você pode usar e mostra como fazê-lo funcionar com CF usando a função nativa XmlTransform().

A razão pela qual escolhi mudar para XSLT para isso é dupla.

Primeiro, validar se a entrada é um XML bem formado elimina a possibilidade de um ataque XSS usando certos truques de concatenação de strings.

Em segundo lugar, é mais fácil manipular o pacote XHTML usando seletores XSL e XPath do que com expressões regulares porque eles são projetados especificamente para funcionar com um documento XML estruturado, em comparação com expressões regulares que foram projetadas para manipulação de strings brutas.Então é muito mais limpo e fácil, tenho menos probabilidade de cometer erros e se eu descobrir que cometi um erro, é mais fácil consertar.

Além disso, quando os testei, descobri que editores WYSIWYG como o CKEditor (ele removeu o F) preservam o XML bem formado, então você não deveria se preocupar com isso como um problema potencial.

Outras dicas

As mesmas regras se aplicam à proteção: Entrada de filtro, saída de escape.

No caso de entrada de código de entrada, a filtragem significa apenas que a string deve conter caracteres imprimíveis e talvez você tenha um limite de comprimento.

Ao armazenar texto no banco de dados, use parâmetros de consulta ou escape da sequência para garantir que você não tenha caracteres que criem vulnerabilidades de injeção SQL. O código pode conter mais símbolos e caracteres não alfa, mas os que você deve observar com relação à injeção de SQL são os mesmos do texto normal.

Não tente duplicar a função de fuga correta. A maioria das bibliotecas de banco de dados já contém uma função que corrige a escape para todos os caracteres que precisam escapar (por exemplo, isso pode ser específico do banco de dados). Também deve lidar com problemas especiais com conjuntos de personagens. Basta usar a função fornecida pela sua biblioteca.

Não entendo por que as pessoas dizem "Use procedimentos armazenados!" Os Procs armazenados não oferecem proteção especial contra a injeção de SQL. Se você interpolar os valores não especificados nas cadeias de SQL e executar o resultado, isso será vulnerável à injeção de SQL. Não importa se você está fazendo isso no código do aplicativo versus em um proc.

Ao produzir para a apresentação da Web, escape de caracteres especiais de HTML, como faria com qualquer texto.

A melhor coisa que você pode fazer para evitar ataques de injeção de SQL é garantir que você use consultas parametrizadas ou procedimentos armazenados ao fazer chamadas de banco de dados. Normalmente, eu também recomendaria a realização de alguma higienização básica de entrada, mas como você precisa aceitar o código do usuário, isso pode não ser uma opção.

Por outro lado (ao renderizar a entrada do usuário para o navegador), a codificação HTML dos dados causará qualquer javascript malicioso ou o que gosta de ser renderizado como texto literal em vez de executado no navegador do cliente. Qualquer estrutura decente do servidor de aplicativos da web deve ter a capacidade.

Eu diria que alguém poderia substituir todos <por <, etc. (usando htmlentities no PHP, por exemplo) e, em seguida, escolher as tags seguras com algum tipo de lista de permissões. O problema é que a lista de permissões pode ser um pouco rigorosa demais.

Aqui está um exemplo php

$code = getTheCodeSnippet();
$code = htmlentities($code);
$code = str_ireplace("&lt;br&gt;", "<br>", $code); //example to whitelist <br> tags
//One could also use Regular expressions for these tags

Para evitar injeções de SQL, você pode substituir todos 'e chars por um equivalente "inútil", como ' e , de modo que a seguinte linha C

#include <stdio.h>//'); Some SQL command--

Não teria nenhum resultado negativo no banco de dados.

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