nesta seção, descreveremos alguns princípios gerais para prevenir vulnerabilidades de script entre sites e formas de usar várias tecnologias comuns para proteger contra ataques XSS.

Cross-site scripting, a prevenção pode ser geralmente obtida por meio de duas camadas de defesa:

  • Codificar dados de saída
  • Validar a entrada na chegada

Você pode usar Arroto Scanner para digitalizar os seus web sites para diversas vulnerabilidades de segurança, incluindo a XSS. A lógica de varredura de ponta do Burp Replica as ações de um invasor habilidoso e é capaz de obter uma cobertura correspondentemente alta das vulnerabilidades XSS. Você pode usar o Burp Scanner para ter certeza de que suas defesas contra ataques XSS estão funcionando de forma eficaz.

codificar dados na saída

a codificação deve ser aplicada diretamente antes que os dados controláveis pelo USUÁRIO sejam gravados em uma página, porque o contexto em que você está escrevendo determina que tipo de codificação você precisa usar. Por exemplo, valores dentro de uma string JavaScript requerem um tipo diferente de escape para aqueles em um contexto HTML.

No HTML contexto, você deve converter os não-incluídos na lista de permissões valores em entidades HTML:

  • < converte para: &lt;
  • > converte para: &gt;

Em JavaScript contexto de seqüência de caracteres não-alfanuméricos valores devem ser Unicode caracteres de escape:

  • < converte para: \u003c
  • > converte para: \u003e

às Vezes você precisa aplicar várias camadas de codificação, na ordem correta. Por exemplo, para incorporar com segurança a entrada do usuário dentro de um manipulador de Eventos, você precisa lidar com o contexto JavaScript e o contexto HTML. Então, você precisa primeiro Unicode-escape da entrada e, em seguida, HTML codificar:

<a href="#" onclick="x='This string needs two layers of escaping'">test</a>

Validar a entrada na chegada

Codificação é, provavelmente, a mais importante linha de XSS defesa, mas isso não é suficiente para evitar vulnerabilidades de XSS em cada contexto. Você também deve validar a entrada o mais estritamente possível no ponto em que ela é recebida pela primeira vez de um usuário.

exemplos de validação de entrada incluem:

  • se um usuário enviar um URL que será retornado nas respostas, validando que ele começa com um protocolo seguro, como HTTP e HTTPS. Caso contrário, alguém pode explorar seu site com um protocolo prejudicial como javascript ou data.
  • se um usuário fornecer um valor que espera ser numérico, validando que o valor realmente contém um inteiro.
  • validar essa entrada contém apenas um conjunto esperado de caracteres.

a validação de entrada deve funcionar idealmente bloqueando a entrada inválida. Uma abordagem alternativa, de tentar limpar a entrada inválida para torná-la válida, é mais propensa a erros e deve ser evitada sempre que possível.

Lista Branca vs Lista negra

a validação de entrada geralmente deve empregar listas brancas em vez de listas negras. Por exemplo, em vez de tentar fazer uma lista de todos os protocolos prejudiciais (javascript, data, etc.), basta fazer uma lista de protocolos seguros (HTTP, HTTPS) e não permitir nada que não esteja na lista. Isso garantirá que sua defesa não quebre quando novos protocolos prejudiciais aparecerem e o tornará menos suscetível a ataques que buscam ofuscar valores inválidos para evitar uma lista negra.

permitir HTML” seguro ”

permitir que os usuários postem marcação HTML deve ser evitado sempre que possível, mas às vezes é um requisito comercial. Por exemplo, um site de blog pode permitir que Comentários sejam postados contendo alguma marcação HTML limitada.

a abordagem clássica é tentar filtrar tags e JavaScript potencialmente prejudiciais. Você pode tentar implementar isso usando uma lista de permissões de tags e atributos seguros, mas graças a discrepâncias nos mecanismos de análise do navegador e peculiaridades como mutation XSS, essa abordagem é extremamente difícil de implementar com segurança.

a opção menos ruim é usar uma biblioteca JavaScript que executa filtragem e codificação no navegador do usuário, como o DOMPurify. Outras bibliotecas permitem que os usuários forneçam conteúdo no formato markdown e convertam o markdown em HTML. Infelizmente, todas essas bibliotecas têm vulnerabilidades XSS de tempos em tempos, então esta não é uma solução perfeita. Se você usar um, deve monitorar de perto as atualizações de segurança.

Nota

além do JavaScript, outros conteúdos como CSS e até HTML regular podem ser prejudiciais em algumas situações.

ataques usando CSS malicioso

como evitar o XSS usando um mecanismo de modelo

muitos sites modernos usam mecanismos de modelo do lado do servidor, como Twig e Freemarker, para incorporar conteúdo dinâmico em HTML. Eles normalmente definem seu próprio sistema de escape. Por exemplo, em Twig, você pode usar o filtro e() , com um argumento definindo o contexto:

{{ user.firstname | e('html') }}

alguns outros mecanismos de modelo, como Jinja e React, escapam do conteúdo dinâmico por padrão, o que efetivamente impede a maioria das ocorrências de XSS.

recomendamos revisar os recursos de escape de perto quando você avalia se deve usar um determinado mecanismo ou estrutura de modelo.

Nota

se você concatenar diretamente a entrada do usuário em strings de modelo, ficará vulnerável à injeção de modelo do lado do servidor, que geralmente é mais grave que o XSS.

como evitar XSS em PHP

em PHP há uma função embutida para codificar entidades chamadas htmlentities. Você deve chamar essa função para escapar de sua entrada quando estiver dentro de um contexto HTML. A função deve ser chamada com três argumentos:

  • sua string de entrada.
  • ENT_QUOTES, que é um sinalizador que especifica que todas as aspas devem ser codificadas.
  • o conjunto de caracteres, que na maioria dos casos deve ser UTF-8.

por exemplo:

<?php echo htmlentities($input, ENT_QUOTES, 'UTF-8');?>

quando em um contexto de string JavaScript, você precisa Unicode-escape input como já descrito. Infelizmente, o PHP não fornece uma API para Unicode-escape de uma string. Aqui está um código para fazer isso em PHP:

<?php

function jsEscape($str) {
$output = '';
$str = str_split($str);
for($i=0;$i<count($str);$i++) {
$chrNum = ord($str);
$chr = $str;
if($chrNum === 226) {
if(isset($str) && ord($str) === 128) {
if(isset($str) && ord($str) === 168) {
$output .= '\u2028';
$i += 2;
continue;
}
if(isset($str) && ord($str) === 169) {
$output .= '\u2029';
$i += 2;
continue;
}
}
}
switch($chr) {
case "'":
case '"':
case "\n";
case "\r";
case "&";
case "\";
case "<":
case ">":
$output .= sprintf("\u%04x", $chrNum);
break;
default:
$output .= $str;
break;
}
}
return $output;
}
?>

Aqui é como usar o jsEscape função em PHP:

<script>x = '<?php echo jsEscape($_GET)?>';</script>

como Alternativa, você pode usar um modelo de motor.

como evitar o lado do cliente XSS em JavaScript

para escapar da entrada do usuário em um contexto HTML em JavaScript, você precisa do seu próprio codificador HTML porque o JavaScript não fornece uma API para codificar HTML. Aqui está um exemplo de código JavaScript que converte uma string em entidades HTML:

function htmlEncode(str){
return String(str).replace(//gi, function(c){
return '&#'+c.charCodeAt(0)+';';
});
}

você usaria essa função da seguinte maneira:

<script>document.body.innerHTML = htmlEncode(untrustedValue)</script>

se sua entrada estiver dentro de uma string JavaScript, você precisará de um codificador que execute o escape Unicode. Aqui está um exemplo Unicode-encoder:

function jsEscape(str){
return String(str).replace(//gi, function(c){
return '\u'+('0000'+c.charCodeAt(0).toString(16)).slice(-4);
});

}

Você, em seguida, utilize esta função da seguinte maneira:

<script>document.write('<script>x="'+jsEscape(untrustedValue)+'";<\/script>')</script>

Como evitar XSS em jQuery

A forma mais comum de XSS em jQuery quando você passar a entrada do usuário para um seletor do jQuery. Os desenvolvedores da Web costumavam usar location.hash e passá-lo para o seletor, o que causaria XSS, pois o jQuery renderizaria o HTML. o jQuery reconheceu esse problema e corrigiu sua lógica de seletor para verificar se a entrada começa com um hash. Agora, o jQuery só renderizará HTML se o primeiro caractere for <. Se você passar dados não confiáveis para o seletor jQuery, certifique-se de escapar corretamente do valor usando a função jsEscape acima.

mitigar XSS usando a Política de segurança de conteúdo (CSP)

a Política de segurança de conteúdo (CSP) é a última linha de defesa contra scripts entre sites. Se sua prevenção XSS falhar, você pode usar o CSP para mitigar o XSS restringindo o que um invasor pode fazer.

o CSP permite controlar várias coisas, como se scripts externos podem ser carregados e se scripts embutidos serão executados. Para implantar o CSP, você precisa incluir um cabeçalho de resposta HTTP chamado Content-Security-Policy com um valor contendo sua política.

um exemplo CSP é o seguinte:

default-src 'self'; script-src 'self'; object-src 'none'; frame-src 'none'; base-uri 'none';

esta política especifica que recursos como imagens e scripts só podem ser carregados da mesma origem da página principal. Portanto, mesmo que um invasor possa injetar com sucesso uma carga útil XSS, ele só poderá carregar recursos da origem atual. Isso reduz muito a chance de um invasor explorar a vulnerabilidade XSS.

se você precisar carregar recursos externos, certifique-se de permitir apenas scripts que não ajudem um invasor a explorar seu site. Por exemplo, se você colocar certos domínios na lista de permissões, um invasor poderá carregar qualquer script desses domínios. Sempre que possível, tente hospedar recursos em seu próprio domínio.

se isso não for possível, você pode usar a política baseada em hash ou nonce para Permitir scripts em domínios diferentes. Um nonce é uma string aleatória que é adicionada como um atributo de um script ou recurso, que só será executado se a string aleatória corresponder à gerada pelo servidor. Um invasor não consegue adivinhar a string aleatória e, portanto, não pode invocar um script ou recurso com um nonce válido e, portanto, o recurso não será executado.

mitigar ataques XSS usando CSP

Deixe uma resposta

O seu endereço de email não será publicado.