Quais são as melhores práticas para evitar ataques de xss em um site em PHP

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

  •  09-06-2019
  •  | 
  •  

Pergunta

Eu tenho o PHP configurado de modo que a magia de orçamentos e register globals estão fora.

Eu faço o meu melhor para sempre chamada htmlentities() para tudo o que eu estou outputing que é derivada da entrada do usuário.

Eu também, ocasionalmente, minha pesquisa de banco de dados para coisas comuns, usados em xss anexados como...

<script

O que mais devo fazer e como posso ter certeza de que as coisas que eu estou tentando fazer são sempre feito.

Foi útil?

Solução

Escapando de entrada não é o melhor que você pode fazer para o sucesso de XSS prevenção.De saída também deve ser escapado.Se você usar o Smarty template engine, você pode usar |escape:'htmlall' modificador para converter todos os caracteres sensíveis para entidades HTML (eu uso próprio |e modificador que é alias acima).

A minha abordagem à segurança de entrada/saída é:

  • armazenar a entrada do usuário não modificado (sem HTML escapar na entrada, apenas DB-ciente de escapar feito através DOP instruções preparadas)
  • escape na saída, dependendo do formato de saída que você usa (por exemplo,HTML e JSON precisa escapar regras)

Outras dicas

Eu sou da opinião de que um não deve escapar de alguma coisa durante a entrada, apenas na saída.Uma vez que a maior parte do tempo) você não pode assumir que você sabe onde os dados vão.Exemplo, se você tem forma, que o leva de dados que, mais tarde, aparece em um e-mail que você enviar, você precisa escapar (caso contrário, um usuário mal-intencionado poderia reescrever o seu e-mail-headers).

Em outras palavras, você só pode escapar no último momento os dados é "deixar" o seu aplicativo:

  • Item de lista
  • Escrever para o arquivo XML, de escape para XML
  • Escrever para o banco, escape (para que determinado DBMS)
  • Escrever e-mail, de escape para e-mails
  • etc

Para ir de curto:

  1. Você não sabe onde seus dados estão indo
  2. Os dados podem realmente acabar em mais de um lugar, que necessitam de diferentes sair mecanismo, MAS NÃO AMBOS
  3. Dados de escape para o alvo errado é realmente não é bom.(E. g.receba um e-mail com o assunto "Ir para Tommy\'s bar".)

Controlo electrónico de velocidade #3 vai ocorrer se você escapar de dados na camada de entrada (ou você precisa de escapar de novo, etc.).

PS:Eu vou, segundo o conselho para não usar as aspas mágicas, esses são pura maldade!

Há um monte de maneiras de fazer XSS (Ver http://ha.ckers.org/xss.html e é muito difícil de pegar.

Eu, pessoalmente, delegar no quadro actual, o que eu estou usando (Código de Ignição por exemplo).Embora não seja perfeito, ele pode pegar mais do que a minha mão rotinas de sempre.

Esta é uma grande questão.

Primeiro, não escapam texto de entrada, exceto para torná-lo seguro para o armazenamento (como está sendo colocado em um banco de dados).A razão para isto é que você quer manter o que foi a entrada, então você pode contextualmente apresentar de diferentes formas e lugares.Fazer alterações aqui pode comprometer a sua posterior apresentação.

Quando você vai apresentar os seus dados de filtrar o que não deveria estar lá.Por exemplo, se não há uma razão para que o javascript esteja lá procurá-lo e removê-lo.Uma maneira fácil de fazer isso é usar o strip_tags função e somente as tags de html que você está permitindo.

Em seguida, pegue o que você tem e passe-o pensamento htmlentities ou htmlspecialchars para alterar o que há para caracteres ascii.Fazer isso com base no contexto e do que você quer sair.

Eu, também, sugerem desligar Citações Mágicas.É foi removido do PHP 6 e é considerado má prática para usá-lo.Detalhes http://us3.php.net/magic_quotes

Para mais detalhes confira http://ha.ckers.org/xss.html

Esta não é uma resposta completa, mas, espero que o suficiente para ajudar você a começar.

rikh Escreve:

Eu faço o meu melhor para sempre chamada htmlentities() para tudo o que eu estou outputing que é derivada da entrada do usuário.

Ver Joel ensaio sobre Tornar O Código Olhar Errado para ajudar com isso

Eu confio no PHPTAL para que.

Ao contrário do Smarty e simples do PHP, que escapa a qualquer saída por padrão.Esta é uma grande vitória para a segurança, porque o seu site não fique vurnelable se você esquecer htmlspecialchars() ou |escape em algum lugar.

XSS é HTML-ataque específico, de modo que a saída de HTML é o lugar certo para impedi-lo.Você não deve tentar pré-filtragem de dados no banco de dados, porque você pode precisar de saída de dados para outro meio, que não aceitam HTML, mas tem os seus riscos.

Modelo de biblioteca. Ou pelo menos, que é o que o modelo de bibliotecas deve fazer.Para evitar XSS todos a saída deve ser codificado.Esta não é a tarefa do aplicativo principal / de lógica de controle, ele deve apenas ser tratadas pelos métodos de saída.

Se você polvilhar htmlentities() thorughout seu código, o projeto total está errado.E como você sugere, você pode perder um ou dois pontos.É por isso que a única solução é rigorosa codificação html -> quando saída vars são escritos em html/xml fluxo.

Infelizmente, a maioria dos php modelo de bibliotecas só adicionar a sua própria sintaxe do modelo, mas não preocupam-se com a codificação de saída, ou de localização, ou de validação de html, ou qualquer coisa importante.Talvez alguém conhece um bom modelo de biblioteca para php?

Escapar de todas as entradas do usuário é suficiente para a maioria dos sites.Também certifique-se que as IDs de sessão não acabar na URL para que eles não podem ser roubados do Referer link para outro site.Além disso, se você permitir que os usuários para enviar links, certifique-se de que não javascript: protocolo links são permitidos;estes poderia executar um script assim que o usuário clica no link.

Se você estiver preocupado com ataques de XSS, a codificação de sua seqüências de saída para o HTML é a solução.Se você se lembrar para codificar cada caracteres de saída para o formato HTML, não há nenhuma maneira para executar um bem-sucedido ataque de XSS.

Leia mais:Desinfecção de dados do usuário:Como e onde fazê-lo

Pessoalmente, eu iria desativar as aspas mágicas.Em PHP5+ ele é desabilitado por padrão e é melhor para o código como se ele não está lá como ele não escapa de tudo e ele será removido do PHP6.

A seguir, dependendo de qual o tipo de dados de usuário que você está filtrando vai ditar o que fazer a seguir e.g.se ele é apenas texto e.g.um nome e, em seguida, strip_tags(trim(stripslashes())); ou para verificar os intervalos de usar expressões regulares.

Se você esperar um certo intervalo de valores, criar uma matriz de valores válidos e só permitir que aqueles valores por meio do (in_array($userData, array(...))).

Se você estiver verificando o uso de números de is_numeric para impor números inteiros ou convertido para um tipo específico, que deve impedir que as pessoas tentando enviar cadeias de caracteres no lugar.

Se você tem PHP5.2+, em seguida, considerar a filter() e fazendo uso de uma extensão, que pode filtrar a vários tipos de dados, incluindo endereços de e-mail.A documentação não é particularmente boa, mas está melhorando.

Se você tiver que lidar com HTML, então você deve considerar algo como PHP Filtro de Entrada ou HTML Purificador.HTML Purificador irá igualmente validar o HTML para a conformidade.Eu não tenho certeza se o Filtro de Entrada ainda está sendo desenvolvido.Ambos irão permitir que você defina um conjunto de tags que podem ser usadas e quais atributos são permitidos.

Tudo o que você decidir, lembre-se sempre, nunca, jamais, confiar em nada que vem em seu script PHP a partir de um usuário (incluindo você!).

Todas essas respostas são grandes, mas, fundamentalmente, a solução para XSS vai ser parar de geração de documentos HTML por manipulação de seqüência de caracteres.

Filtragem de entrada é sempre uma boa idéia para qualquer aplicação.

A fuga de saída usando htmlentities() e amigos devem funcionar, desde que seja usado corretamente, mas este é o HTML equivalente de criação de uma consulta SQL concatenando strings com mysql_real_escape_string($var) - ele deve funcionar, mas poucas coisas podem validar o seu trabalho, por assim dizer, em comparação com uma abordagem de como utilizar consultas parametrizadas.

A solução a longo prazo deve ser de aplicativos para construir a página internamente, talvez usando uma interface padrão, como o DOM e, em seguida, usar uma biblioteca (como libxml) para lidar com a serialização de XHTML/HTML/etc.Claro, estamos muito longe de que ser popular e rápido o suficiente, mas enquanto isso, temos que construir os nossos documentos HTML através de operações de cadeia de caracteres, e que é inerentemente mais arriscado.

Eu acho que usar essa função ajuda a eliminar uma série de possíveis ataques de xss:http://www.codebelay.com/killxss.phps

"Citações mágicas" é um remédio paliativo para alguns dos piores falhas de XSS que funciona por fugir de tudo na entrada, algo que está errado é por design.O único caso em que alguém iria querer usar é quando você absolutamente deve utilizar um aplicativo PHP conhecido para ser escrito de forma descuidada com relação a XSS.(Neste caso, você está em um problema sério, mesmo com a "magic quotes".) Ao desenvolver seu próprio aplicativo, você deve desabilitar o "magic quotes" e siga XSS-práticas de segurança em vez disso.

XSS, uma vulnerabilidade de script entre sites, ocorre quando uma aplicação que inclui seqüências de caracteres a partir de fontes externas (entrada do usuário, obtido a partir de outros websites, etc) na sua [X]HTML, CSS, ECMAscript ou outro navegador analisado de saída sem sair adequada, na esperança de que os caracteres especiais como menos do que (em [X]HTML), aspas simples ou duplas (ECMAscript) nunca vai aparecer.A solução adequada é sempre escapar de cordas de acordo com as regras do idioma de saída:usando a entidades [X]HTML, barras invertidas no ECMAscript etc.

Porque pode ser difícil manter o controle do que não é confiável e tem que ser ignorado, é uma boa idéia sempre escapar de tudo o que é uma "seqüência de caracteres de texto", em oposição ao "texto com marcação" em uma linguagem como HTML.Alguns ambientes de programação mais fácil através da introdução de vários incompatível tipos de seqüência de caracteres:"de cadeia" (texto normal), "seqüência de caracteres HTML" (linguagem de marcação HTML) e assim por diante.Dessa forma, directa conversão implícita de "cadeia de caracteres" a "seqüência de caracteres HTML" seria impossível, e a única forma de uma seqüência de caracteres pode tornar-se marcação HTML é passando-a através de um escapando função.

"Register globals", que desabilitá-lo é definitivamente uma boa idéia, lida com um problema totalmente diferente de XSS.

Faz de você cookies de sessão (ou todos os cookies) utilizar HttpOnly.A maioria dos navegadores irá ocultar o valor do cookie de JavaScript no caso.O utilizador pode ainda copiar manualmente os cookies, mas isso ajuda a evitar direta, acesso de script.StackOverflow tive esse problema durning beta.

Esta não é uma solução, apenas mais um tijolo na parede

  • Não confie a entrada do usuário
  • Fuja de todo livre de texto de saída
  • Não usar as aspas mágicas;veja se há um SGBD-specfic variante, ou usar PDO
  • Considere o uso de HTTP-só os cookies sempre que possível para evitar qualquer script mal-intencionado que está sendo capaz de seqüestrar uma sessão

Você deve, no mínimo, validar todos os dados que vão para o banco de dados.E tentar validar todos os dados, deixando o banco de dados também.

mysql_real_escape_string é bom para evitar SQL injection, mas o XSS é mais complicado.Você deve preg_match, stip_tags, ou htmlentities sempre que possível!

O melhor método para evitar XSS em um aplicativo PHP é HTML Purificador (http://htmlpurifier.org/).Uma pequena desvantagem é que é muito grande e a biblioteca é melhor usado com um op cache de código como APC.Você gostaria de usar isso em qualquer lugar onde o conteúdo não confiável está sendo enviado para o ecrã.Ele é muito mais completa que htmlentities, htmlspecialchars, filter_input, filter_var, strip_tags, etc.

Use um usuário existente-entrada de higienização biblioteca para limpar todos entrada do usuário.A menos que você coloque um monte de esforço para isso, a implementação de ele mesmo nunca vai funcionar tão bem.

Eu encontrar a melhor maneira é usando uma classe que permite que você ligar o seu código, então você nunca terá que se preocupar manualmente a fuga de dados.

É difícil implementar uma profunda injeção de sql/xss injeção de prevenção em um site que não causar falsos alarmes.Em um CMS, o usuário final poderá usar <script> ou <object> que links para itens de outro site.

Eu recomendo ter todos os usuários a instalar o FireFox com NoScript ;-)

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