Quer gostemos ou não, o HTTP é o protocolo de transporte de aplicativos de fato da era moderna. Nós o usamos em todos os lugares. É tão onipresente quanto IP e TCP e serve praticamente ao mesmo propósito. Seu único objetivo é transportar o ouro digital dos negócios de hoje: dados.
Não importa se esses dados são JSON, XML ou codificados em URL. É o HTTP que aplicativos e dispositivos usam para se comunicar com servidores e serviços na nuvem e no local, no data center.
Ao contrário do IP e do TCP, no entanto, o HTTP é um protocolo baseado em texto. É altamente flexível e pode transportar uma variedade de dados – de binários a texto. Nós o usamos para transmitir dados, recuperar dados e coletar dados.
Os invasores o usam liberalmente porque, como mencionado, é um protocolo baseado em texto com regras bastante flexíveis em relação às extensões dos cabeçalhos que especificam tudo, desde qual ação o cliente espera que o servidor tome (o 'método' HTTP) até o recurso que está sendo solicitado (o URI) e que tipo de conteúdo pode ser aceito (os cabeçalhos 'Accept'). Essas regras são frouxas para permitir extensibilidade.
Por exemplo, o cabeçalho X-Forwarded-For foi introduzido como um meio de garantir que os desenvolvedores pudessem "ver" o endereço IP original do cliente. Em certas arquiteturas – particularmente aquelas em que os intermediários atuam como proxies completos – essas informações podem ser perdidas. Alguns aplicativos precisam desses dados e, portanto, os desenvolvedores (e fornecedores de rede) estenderam o protocolo HTTP introduzindo um cabeçalho personalizado. Isso faz parte da especificação HTTP; permite inovação e a introdução de novos comportamentos e recursos sem exigir alterações no protocolo. É uma coisa boa.
Exceto quando não é.
Não é uma coisa boa quando essa flexibilidade não é levada em consideração pelos desenvolvedores dos servidores que suportam HTTP ou pelos responsáveis por proteger aplicativos que dependem de HTTP.
Aqui está uma pequena amostra de CVEs relacionados ao HTTP que exploram uma vulnerabilidade em cabeçalhos HTTP:
Entrada CVE | Cabeçalho HTTP | Nome assustador | Impacto |
CVE-2017-9798 | Método | “Sangramento de opções” | Vazamento de dados |
CVE-2011-3192 | Faixa | “Assassino do Apache” | DoS |
CVE-2017-9805 | Tipo de conteúdo | Acesso remoto / execução | |
CVE-2017-9788 | [Proxy-]Autorização | Vazamento de dados / DoS | |
CVE-2017-8219 | Biscoito | DoS | |
CVE-2017-7679 | Tipo de conteúdo | Vazamento de dados | |
CVE-2017-6367 | Conteúdo-Comprimento | DoS |
Honestamente, uma busca por CVEs conhecidos por vulnerabilidades HTTP retorna uma lista excessivamente longa (e inclui uma grande variedade de fornecedores e softwares) que não vou duplicar aqui. Uma parcela significativa deles geralmente é acionada pelo abuso de um cabeçalho HTTP.
Uma nota sobre Optionsbleed
Optionsbleed é uma das vulnerabilidades mais recentes. Eu o chamo porque ele existe no próprio Apache HTTP. Dado que a Netcraft estima atualmente que o Apache roda em “mais de 2,8 milhões de computadores com acesso à web que atualmente executam várias versões e derivados do Apache httpd , o que lhe dá uma participação de 42,8% de todos os computadores com acesso à web”, vulnerabilidades nele se tornam um risco significativo. Felizmente, essa vulnerabilidade específica é acionada por meio de um cabeçalho HTTP, mas também requer a existência de uma diretiva Limits mal configurada no arquivo .htaccess . Esta postagem da Sophos fornece uma ótima visão geral dos detalhes técnicos sangrentos, caso você tenha interesse. O TL;DR é que se a configuração incorreta existir, um invasor pode explorar uma vulnerabilidade no Apache por meio do cabeçalho do método HTTP e (ao que parece) forçar o servidor a "sangrar" dados pertencentes a, bem, outra pessoa.
Agora, eu disse tudo isso para poder dizer o seguinte: a segurança do aplicativo é uma pilha. Essa pilha inclui as plataformas (e, portanto, os protocolos) das quais os aplicativos dependem. Como HTTP.
Precisamos fazer um trabalho melhor para proteger o HTTP de abusos que comprometam a segurança. Não importa se é um vazamento de dados, um ataque de negação de serviço ou acesso remoto. Todos eles são impactos ruins. Precisamos reconhecer melhor que o HTTP é uma superfície de ataque cada vez mais popular. O fato de ser baseado em texto significa que toda a interação entre um cliente e o serviço HTTP deve ser classificada como entrada do usuário .
Isso deve, por sua vez, encorajar uma estratégia de segurança que inclua a higienização dessa entrada. Sim, isso significa aplicação de protocolo e limpeza upstream (antes que chegue a um servidor HTTP potencialmente vulnerável).
Isso significa que um firewall de aplicativo da web ou proxy programável deve ficar na frente de qualquer serviço HTTP público e se envolver ativamente na limpeza de solicitações HTTP recebidas.
O motivo para isso se baseia na maneira como as plataformas web processam cabeçalhos HTTP, ou seja, antes mesmo que a solicitação seja vista por um desenvolvedor. Portanto, não podemos necessariamente apontar os desenvolvedores e culpar práticas de codificação inseguras pelas vulnerabilidades no nível da plataforma.
A aplicação de patches é a solução definitiva, é claro. Desde que você (1) ouça sobre a vulnerabilidade no dia zero, (2) um patch seja disponibilizado no dia zero e (3) você se sinta confortável em implantar um patch potencialmente não testado em sistemas de produção.
Você precisa corrigir, não me entenda mal, mas há uma lacuna entre divulgação, descoberta, disponibilidade e aplicação. Nessa lacuna está o risco; o risco de que uma vulnerabilidade muito fácil de explorar seja usada contra você.
A penúltima solução é garantir que haja um sistema (uma plataforma) em funcionamento no qual você possa implementar soluções de correção imediatas , como scripts ou varredura baseada em assinaturas, para evitar exploração enquanto você se prepara para aplicar o patch.
A limpeza de dados de entrada e a aplicação da correção do protocolo devem ser parte integrante de qualquer política de segurança corporativa.
O HTTP é cada vez mais arriscado, mas também é administrável se você lembrar que a segurança do aplicativo é uma pilha e então implementar proteções em cada camada dessa pilha.