Pergunta

Quais são as medidas necessárias para evitar ou impedir que injeções de JavaScript aconteçam em um aplicativo Web PHP, para que informações confidenciais não sejam divulgadas (melhores práticas em PHP, HTML/XHTML e JavaScript)?

Foi útil?

Solução

Um bom primeiro passo é aplicar os métodos listados no pergunta Gert G vinculada.Isto cobre detalhadamente a variedade de funções que podem ser usadas em diferentes situações para limpar entradas, incluindo mysql_real_escape_string, htmlentities(), htmlspecialchars(), strip_tags() e addslashes()

A melhor maneira, sempre que possível, é evitar inserir informações do usuário diretamente no seu banco de dados.Empregar validação de entrada da lista branca:em qualquer situação em que você tenha apenas uma gama limitada de opções, escolha entre valores codificados para inserção, em vez de obter a entrada de qualquer formulário voltado para o cliente.Basicamente, isso significa ter apenas determinados valores que você aceita, em vez de tentar eliminar/combater entradas malignas/mal formadas/maliciosas.

Por exemplo:Se você tiver um formulário com um menu suspenso para itens, não use a entrada deste menu suspenso para inserção.Lembre-se que um cliente malicioso pode editar as informações enviadas com o envio do formulário, mesmo que você ache que ele tem opções limitadas.Em vez disso, faça com que o menu suspenso se refira a um índice em uma matriz no código do lado do servidor.Em seguida, use esse array para escolher o que inserir.Dessa forma, mesmo que um invasor tente enviar um código malicioso, ele nunca atingirá seu banco de dados.

Obviamente, isso não funciona para aplicativos de formato livre, como fóruns ou blogs.Para esses, você tem que recorrer às técnicas do “primeiro passo”.Ainda assim, há uma ampla gama de opções que podem ser melhoradas por meio da validação de entrada da lista de permissões.

Você também pode usar consultas parametrizadas (também conhecidas como instruções preparadas com variáveis ​​de ligação) para suas interações SQL sempre que possível.Isso dirá ao seu servidor de banco de dados que todas as entradas são simplesmente um valor, o que atenua muitos dos problemas potenciais de ataques de injeção.Em muitas situações, isso pode abranger até aplicativos de formato livre.

Outras dicas

Trate qualquer valor que você enviar para html com htmlspecialchars() por padrão.

A única desculpa para não usar htmlspecialchars() é quando você precisa gerar uma string html que contém html.Nesse caso, você deve ter certeza de que esta string é de uma fonte totalmente segura.Se você não tiver essa confiança, deverá passá-la pelo filtro HTML da lista de permissões, que permite apenas um conjunto cuidadosamente limitado de tags, atributos e valores de atributos.Você deve ter um cuidado especial com os valores dos atributos.Você nunca deve permitir que tudo passe como valor de atributo, especialmente para atributos como src, hef, style.

Você deve conhecer todos os locais em seu webapp onde você envia algo para html sem usar htmspeciachars(), certifique-se de que realmente precisa desses locais e esteja ciente de que, apesar de toda a sua confiança, esses locais são vulnerabilidades em potencial.

Se você está pensando que isso é muito cuidado:"Por que preciso htmlspecialchar() esta variável que sei que contém apenas números inteiros e perder todos os preciosos ciclos de CPU?"

Lembre-se disso:Você não sabe, você só pensa que sabe, os ciclos de CPU são a coisa mais barata do mundo e quase todos eles serão desperdiçados esperando pelo banco de dados ou sistema de arquivos ou até mesmo pelo acesso à memória.

Além disso, nunca use filtros HTML de lista negra.O Youtube cometeu esse erro e de repente alguém descobriu que só primeiro <script> é removido e se você inserir o segundo no comentário, poderá injetar qualquer Javascript no navegador do visitante.

Da mesma forma, para evitar injeções de SQL, trate com mysql_real_escape_string() todos os valores que você cola na consulta SQL, ou melhor ainda, use instruções preparadas pelo PDO.

Se você não estiver passando nada que precise ser formatado como html, use:

strip_tags() <- Eliminates any suspicious html

e execute o seguinte para limpar antes de salvar no banco de dados

mysql_real_escape_string() 

Se o seu ajax estiver salvando o html inserido pelo usuário por meio de uma caixa de texto ou wysiwyg, tente usar Purificador HTML para remover o javascript, mas permitir tags html.

Não concordo totalmente com as outras respostas fornecidas, por isso postarei minhas recomendações.

Leitura recomendada XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet

Injeção de HTML:Sempre que exibir qualquer conteúdo enviado pelo usuário, ele deverá ser devidamente limpo com htmlspecialchars ou entidades html ao especificar ENT_QUOTES se usado entre aspas simples.Eu recomendaria nunca encapsular entre aspas simples e sempre encapsular seus atributos entre aspas duplas (não os omita).Isso se aplica a coisas como:

<input value="<?php echo htmlspecialchars($var); ?>" />
<textarea><?php echo htmlspecialchars($var); ?></textarea>
<p><?php echo htmlspecialchars($var); ?></p>
<img width="<?php echo htmlspecialchars($var); ?>" />

Injeção Javascript:É uma prática recomendada (mas nem sempre prática) nunca repetir o conteúdo do usuário em eventos e javascript.No entanto, se o fizer, há algumas coisas que podem ser feitas para reduzir o risco.Passe apenas IDs inteiros.Se você precisar de algo como um especificador de tipo, use uma lista de permissões e/ou verificação condicional antes da saída.Possivelmente forçar o conteúdo do usuário a ser alfanumérico apenas quando apropriado; preg_replace("/[^A-Za-z0-9]/", '', $string); mas tenha muito cuidado com o que você permite aqui.Inclua conteúdo apenas quando ele estiver encapsulado entre aspas e observe que htmlspecialchars/htmlentities não protege você aqui.Será interpretado em tempo de execução mesmo que tenha sido traduzido para entidades HTML.Isso se aplica a coisas como:

<a href="www.stackoverlow.com/?id=<?php echo (int)$id; ?>">Click</a>
href, src, style, onClick, etc.

Não faça eco de nenhum conteúdo do usuário em outras áreas, como o corpo das tags de script, etc., a menos que tenha sido forçado a um int ou algum outro conjunto de caracteres muito limitado (se você souber o que está fazendo).

Injeção SQL:Usar Declarações preparadas, vincule o conteúdo do usuário a eles e nunca insira diretamente o conteúdo do usuário na consulta.Eu recomendaria criar uma classe para instruções preparadas com funções auxiliares para seus diferentes tipos de instruções básicas (e, ainda no assunto, funcionalizar todas as instruções do seu banco de dados).Se você optar por não usar declarações preparadas, use mysql_real_escape_string() ou similar (não addlashes()).Valide o conteúdo quando possível antes de armazená-lo no banco de dados, como forçar/verificar tipos de dados inteiros, verificações condicionais de tipos, etc.Use tipos e comprimentos de coluna de banco de dados adequados.Lembre-se de que o objetivo principal aqui é evitar a injeção de sql, mas você também pode opcionalmente fazer proteção de injeção de html/javascript aqui.

Outros recursosFiz algumas pesquisas online na esperança de encontrar uma solução simples já disponível publicamente.Encontrei o OWASP ESAPI, mas parece bastante desatualizado.Os links para a versão php estão quebrados em vários lugares.Acredito que encontrei aqui; ESAPI PHP mas, novamente, é bastante desatualizado e não tão simples quanto eu esperava.Você pode achar útil, no entanto.

Resumindo, nunca presuma que você está protegido, como usar htmlentities em um atributo onClick.Você deve usar a ferramenta certa no local certo e evitar fazer coisas no local errado.

Esta questão já possui algumas respostas aceitas e avaliadas pelos usuários.

Em vez disso, também estou postando uma resposta, espero que funcione bem.

Isso foi testado por mim.

$value = preg_replace("/[\'\")(;|`,<>]/", "", $value); 

A função preg_replace() funciona perfeitamente aqui.

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