Como evitar scripts entre sites usando HTML, JavaScript e DOM
Vulnerabilidades de script cruzado deixam seu site aberto à manipulação por invasores. Então, como você pode impedir ataques XSS?
Cross-Site Scripting, amplamente conhecido como XSS, é um dos métodos de ataque mais perigosos empregados por cibercriminosos, por isso é vital que todo desenvolvedor e pesquisador de segurança saiba o que é e como prevenir ataques. Então, como você pode agir contra a vulnerabilidade XSS? Você usa HTML, JavaScript ou DOM para mostrar os dados que um site recebe do usuário. Uma ou mais destas três áreas diferentes podem trabalhar juntas.
Como prevenir XSS usando HTML
O XSS permite que invasores injetem códigos ou scripts maliciosos em páginas da Web, visando usuários desavisados que visitam o site. Isso poderia roubar dados pessoais, redirecionar visitantes para outro site configurado pelo cibercriminoso ou, de outra forma, alterar a aparência da página da web. Mas você pode evitar que isso aconteça; por exemplo, impedindo-os de inserir HTML.
Imagine que você tem um site com um livro de visitas. Digamos que seus visitantes que usam este livro de visitas possam escrever seus nomes e mensagens aqui, e suas mensagens possam ser visualizadas publicamente. Um invasor que queira fazer um teste XSS em seu livro de visitas usará a área que você alocou para que uma mensagem seja escrita. Esse cibercriminoso executará um código JavaScript aqui. Por exemplo, um invasor pode usar código JavaScript como:
<script>alert("The XSS!")</script>
O invasor deve usar uma tag de script para que isso seja bem-sucedido. Caso contrário, o código JavaScript não funcionará. Você deve codificar a instrução < para que os usuários nunca possam usar tags HTML. Isso dificultará o trabalho do invasor com tags HTML.
Como prevenir XSS usando JavaScript
A lógica em HTML também é válida em JavaScript. Em algumas aplicações é possível imprimir os dados recebidos pelo site do usuário com um código JavaScript.
Considere esta codificação:
<p id="print"></p>
<script>
document.getElementById("test").innerHTML = "<!--?php echo $_GET["search"]?-->";
</script>
Imagine que um site usa um bloco de código como o acima. O desenvolvedor usou uma tag “p” chamada “print” aqui. Como você pode ver no código, um valor virá do parâmetro “search”, e o desenvolvedor deseja mostrar esse valor recebido na tag “p”. O desenvolvedor que fez esta operação queria usar o recurso innerHTML do JavaScript.
Agora vamos analisar a situação do ponto de vista do ciberataque. Nesse caso, o invasor realizará um teste XSS dentro da tag “script”. Para isso, o invasor não precisa reiniciar a tag, pois uma tag “script” que já está sendo utilizada. O invasor poderia então escrever um teste como este:
filename.php?search=a" alert("The XSS!"); f= "
Este código aparecerá no site como:
document.getElementById("test").innerHTML = " a" alert("The XSS!"); f=" ";
Esse ataque seria bem-sucedido. Para entender melhor o problema, vamos examinar mais um exemplo de técnica que um invasor pode usar. O hacker pode ter aplicado um teste XSS como:
filename.php?search=";</script><em>Fatih</em>
Esta é a aparência quando visualizada no site:
document.getElementById("test").innerHTML = " ";</script><em>Fatih</em> ";
Isto pode parecer um pouco estranho porque o invasor fechou a primeira tag "script" usando uma estrutura como "/script" aqui. E assim, o invasor pode reiniciar qualquer código JavaScript e HTML que desejar.
Se você pensar nesses dois exemplos diferentes, proteger contra XSS parece bastante simples. A precaução necessária seria codificar os caracteres " e ' que você vê no primeiro exemplo. No segundo exemplo, codifique os caracteres < e >.
Como prevenir XSS usando DOM
Nesta variante do XSS, os dados que o site recebe do usuário podem interferir na propriedade de um elemento DOM. Por exemplo, as informações de cores que o site recebe do usuário podem afetar a cor de fundo de uma tabela ou todo o plano de fundo da página. Assim, o usuário interfere involuntariamente nos layouts de estilo do corpo e da tabela. O código a seguir é um bom exemplo disso:
<body bgcolor="<?php echo $_GET['color']; ?>"/>
Com isso, o site utiliza o parâmetro “color” recebido do usuário diretamente na propriedade “bgcolor” do elemento “body”. Então, o que um invasor poderia fazer neste momento? Eles poderiam executar este código malicioso:
filename.php?color=red" onload="alert('The XSS!')
Fica assim quando visualizado no site:
<body bgcolor=" red" onload="alert('The XSS!') "/>
Para evitar que isso aconteça, o desenvolvedor teria que codificar o caractere ".
No entanto, há mais um elemento importante em JavaScript a ser observado. O trecho de código a seguir é um exemplo disso:
<a href="javascript:alert('The XSS!')">
Isso significa que é possível executar algum código JavaScript diretamente. Uma das melhores medidas preventivas é garantir que o site verifique se os dados que recebe dos usuários são URLs reais. O método mais simples é garantir que haja expressões como “HTTP” e “HTTPS” (a versão segura do HTTP) na conexão.
Um exemplo de função para evitar XSS com PHP
Você viu alguns exemplos de como proteger um aplicativo ou site contra ataques XSS. Você pode usar os trechos de código desta tabela com PHP:
Encode in HTML
htmlspecialchars($str, ENT_COMPAT)
-
Encode in JavaScript and DOM attribute
htmlspecialchars($str, ENT_NOQUOTES)
URL Checking
'/^(((https?)|(\/\/))).*/';
Observe que estes são apenas exemplos e variam dependendo da linguagem de software que você está usando.
Você pode criar um aplicativo da web com PHP e experimentar os códigos que você vê acima para enviá-los por texto. Se você está se perguntando como usar todos esses métodos, você pode obter algumas idéias no bloco de código PHP abaixo, que deve ser útil mesmo se você estiver usando uma linguagem diferente:
<?php
$data = $_GET['data'];
function in_attribute($str){
return htmlspecialchars($str, ENT_COMPAT);
// ENT_COMPAT will encode the double quote (") character.
}
function in_html($str){
$link = '/^(((https?)|(\/\/))).*/';
if(!preg_match($link, $str))
{
return "/";
}
return $str;
}
$data = in_attribute($data);
$data = in_html($data);
$data = real_url(data);
?>
Proteja seu site contra XSS e muito mais
XSS é um vetor de ataque popular usado por hackers. Normalmente, um valor de caminho na URL, qualquer campo do seu site onde os dados possam ser inseridos (como formulários e campos de comentários), pode ser usado para testar uma vulnerabilidade XSS. Mas é claro que existem muitos métodos diferentes que os cibercriminosos podem usar para atacar um site, especialmente se você tiver um site que tenha muitos usuários e oculte suas informações.