Como "O maior ponto cego da Internet" leva a uma vulnerabilidade de segurança de 15 anos

Descobrindo e divulgando httpoxy

Nas últimas duas semanas, tenho coordenado a divulgação de uma vulnerabilidade de segurança muito grande e muito antiga. Se você está procurando os detalhes técnicos, pode dirigir-se a httpoxy.org , e se você estiver procurando por uma explicação não técnica, talvez prefira ler minha outra história de Médio sobre o problema .

Em vez disso, esta é a história de como a descobrimos, e minha experiência com o processo de divulgação.

fundo

Vend é um sistema de carteira de varejo, gerenciamento de inventário, comércio eletrônico e fidelização de clientes que corremos como um serviço. Trabalho na equipe da plataforma, ajudando a garantir que nossos varejistas recebam uma experiência rápida, livre de erros e segura; Eles contam com Vend para mantê-los vendendo coisas sem preocupações e 24/7.

Uma grande parte da missão da equipe da plataforma é manter nossos sistemas de monitoramento e registro. Nosso sistema para logs baseados em texto, em oposição a eventos (Kafka) ou métricas (statsd), é baseado em uma pilha “ELK”; a combinação popular de Elasticsearch, Logstash e Kibana.

Descoberta

Há pouco mais de duas semanas, numa segunda-feira, de outra forma, Scott Geary, meu colega, estava procurando por painéis de Kibana, procurando uma pista relacionada com um ticket de suporte que recebemos.

Em vez disso, Scott encontrou um erro “interessante” e destruiu o resto do time. Aqui está o que viu:

GuzzleHttp Exception ConnectException: erro cURL 7: Falha ao conectar-se ao proxy: Conexão recusada (consulte http://curl.haxx.se/libcurl/c/libcurl-errors.html )

“Hmm, isso é estranho “, pensamos. Nós certamente não temos nenhum microservice chamado ‘proxy’; e esse é um nome de domínio simples? Hã.

Pessoalmente, minha mente correu para o ambiente Docker Compose que eu havia configurado alguns dias antes. Ele usa o excelente contêiner jwilder / nginx-proxy para fornecer um proxy reverso automático. Uma magia muito bonita. “Oh, porcaria “, pensei, “de alguma forma consegui implementar este ambiente de desenvolvimento experimental até a produção!”

Um rápido grep da base de código colocou essa noção na cama. Dado que tínhamos o rastreamento de pilha, conseguimos encontrar rapidamente uma referência a HTTP_PROXY em Guzzle , e parecia assim:

 // Utilize o Linux HTTP_PROXY e HTTPS_PROXY padrão se definido se ($ proxy = getenv ('HTTP_PROXY') ) { 
 $ default ['proxy'] ['http'] = $ proxy; 
 }

Cue head asploding.

Divulgação

Em primeiro lugar, não pensamos que isso seria qualquer coisa menos um erro em Guzzle. Era sério, era remotamente explorável, e Guzzle é popular.

Para desenvolvedores que não estão familiarizados com o PHP (não se regozija por favor), o Guzzle é um cliente HTTP de melhor qualidade para o PHP. Tem uma boa base de código “PHP moderno” e um sólido sistema de middleware funcional. Isso significa que é uma dependência atrativa para usar se você estiver escrevendo um SDK ou wrapper de API. Uma vulnerabilidade remotamente explorável em Guzzle é bastante ruim que achamos que não poderia ser generalizada.

Mas, à medida que continuamos a observar a situação, ficou evidente que esse erro afetaria muito mais do que uma única biblioteca de HTTP; Ninguém parecia mencionar o problema em relação a HTTP_PROXY especificamente em qualquer conselho de segurança do PHP que pudéssemos encontrar. Então, ampliamos nosso pensamento um pouco e contatamos a lista de endereços de segurança do PHP.

Getenv do PHP

Eu vou ter uma breve diversão aqui para discutir o problema em PHP. Obviamente, há uma tentação com uma vulnerabilidade como essa para culpar os autores da biblioteca que confiaram no HTTP_PROXY “variável de ambiente”. Eu não acho que isso seja justo.

Uma grande parte do porquê eu acho que se resume à função getenv, implementada no PHP, e em particular como foi documentada. Há (ou foram) uma série de problemas com a documentação:

  • O resumo da função é apenas “Obtém o valor de uma variável de ambiente”, sem ressalvas.
  • Não há menção de CGI pelo nome, apenas o RFC por número, no corpo de documentação da função (que você deve lembrar não é exibido em visualizações resumidas, como o que seu IDE provavelmente irá mostrar por padrão)
  • Há uma menção da seção 4.1 no RFC, mas não é um link profundo, porque o link do RFC vai para faqs.org em vez de tools.ietf.org (que permite a ligação a seções específicas)
  • A documentação implica (em um comentário de código em um exemplo!) Getenv é aproximadamente o mesmo que $ _SERVER ou outros superglobais, mas nunca explicitamente diz isso . A semântica de $ _SERVER é muito bem compreendida; Os programadores PHP sabem que podem retornar valores fornecidos pelo cliente. Então, por que a documentação não torna o link entre os dois mais nítidos?

O que eu esperaria é que a documentação da função getenv deve fazer uma menção explícita ao “CGI” e mencionar que os valores retornados pelo getenv nem sempre são “variáveis ​​de ambiente” estabelecidas pelo programador, mas geralmente estão sob o controle do usuário final através de seus cabeçalhos de solicitação. Você pode alcançar o último apenas definindo explicitamente a relação entre getenv e superglobals.

As coisas pioram

Tudo bem, então, neste momento, divulgamos a duas partes, e nos sentimos um pouco ruins sobre o estado de segurança em PHP. Foi por esse ponto que começamos a encontrar menções históricas sobre o bug.

Sabíamos que todos os ingredientes da vulnerabilidade estiveram por muito tempo. Tanto quanto podemos dizer, tanto o CGI quanto o cabeçalho HTTP_PROXY chegam até vinte e poucos anos na década de 90. E então, naturalmente, nos dirigimos para a próxima pergunta: “isso é em tudo ?”. A pesquisa de código Github foi inestimável para fornecer a resposta: não, nem tudo.

Especificamente, é quando encontramos a Curl a menção da vulnerabilidade em 2001, a documentação Ruby de find_proxy (que menciona o problema) e, a partir daí, a solução original libwww-perl. Isso trouxe nossa lista de “projetos que consertaram esses anos atrás” para pelo menos três.

Então, era hora de começar a provar o conceito em outros lugares. Primeiro foi Go, principalmente apenas porque é de interesse pessoal para mim, mas também usamos muito um Vend. O método para todos os outros lugares que encontramos o problema foi muito semelhante:

  • Veja se a biblioteca de clientes HTTP mais popular em torno dessa linguagem / plataforma suporta HTTP_PROXY e se não verificar o CGI. (Marque a rede de Go / http)
  • Veja se há uma maneira de implantar o idioma no CGI (Tick for Go’s net / http / cgi)

E foi mesmo assim. Sem implementação do CGI, podemos encontrar o HTTP_PROXY tratado de forma “especial”; se as condições acima fossem verdadeiras, a prova de conceito seria bem-sucedida.

Então, muito rapidamente, eu tinha provas de conceitos baseadas em Docker para os pedidos da net / http e Python da Go, antes de ter ouvido falar da equipe de segurança do PHP. Isso rapidamente se tornou um problema mais complexo para divulgar. Durante as próximas duas horas, mais dois emails de divulgação foram enviados para mais dois grupos de segurança (Python e Go) e, em seguida, outro casal para as equipes de segurança comuns dos servidores CGI (ou FastCGI): Apache e Nginx.

E então as coisas melhoraram

Um dos meus próximos pontos de divulgação foi a equipe Red Hat Product Security. Eles foram extremamente úteis: me acompanhar, escolhendo um período de tempo adequado para o embargo, ajudando a obter CVEs atribuídos e até chegando a uma pontuação CVSS provisória, para que eu pudesse facilmente dizer às pessoas o quão ruim a vulnerabilidade antes de dar-lhes detalhes completos.

Estes são processos vitais que ajudam um processo de divulgação a funcionar sem problemas. Eles também envolvem, por uma boa razão, decisões complicadas que precisam de justificação. E, portanto, há um certo nível de processo envolvido.

No final do período de embargo, enviei cerca de 60 e-mails completos (na lista de endereços de código aberto “tom” que requer uma defesa preventiva cuidadosa contra o pedantismo). Os principais CDNs foram notificados. A Microsoft teve alguns esclarecimentos e algumas informações de mitigação agradáveis ​​para compartilhar. E foi por dias.

Estou no NZST – é +12 para aqueles que não lidam com nós Kiwis regularmente. Isso, por sua vez, significava que conversas começariam muitas vezes no início da manhã; Como eu queria contribuir com a discussão (e tentar afastá-lo das armadilhas), isso significava que começava muito início da manhã.

Quem você vai ligar?

Naturalmente, talvez, como o processo continuou, eu me perguntei se eu estava fazendo um bom trabalho. Ao analisar as recentes divulgações, há muitos exemplos do que não fazer, mas também muitas armadilhas distintas em que você pode entrar.

Onde está o manual de resposta ao incidente para uma vulnerabilidade como esta? A resposta simples é que não existe uma resposta menos satisfatória que provavelmente não poderia ser uma.

A divulgação da vulnerabilidade de segurança é difícil

O httpoxy foi um caso difícil de divulgar por causa da quantidade de software afetado que encontramos. Mas também tivemos uma coisa realmente boa para nós: é fácil mitigar, mesmo sem software corrigido a montante.

Se não fosse esse o caso, as coisas seriam ainda mais complicadas. Em tais situações, você está muito mais à mercê dos desenvolvedores responsáveis ​​pelo problema, antes de poder divulgar de forma responsável outras aplicações afetadas e similares.

Então, há muitas chamadas muito difíceis para fazer. Eu descrevi para mim como um processo de triagem, e essa metáfora faz muito sentido. Primeiro, não faça mal, com certeza. Mas, você precisa descobrir quem você pode ajudar de forma oportuna; você não pode divulgar publicamente e ir para casa.

Por exemplo, devo denunciar isso ao CERT? Quais listas de endereços fechados / privados ainda estão ativas, confiáveis ​​e dignas de divulgação? Quem tem a responsabilidade de obter CVEs atribuídos uma vez que sete equipes de segurança diferentes estão coordenando uma correção? Preciso apresentar o texto dos CVEs sozinho? O que eu faço quando um vendedor me pede uma extensão de duas semanas do período de embargo? As pessoas vão gritar comigo e chamar de arquiteto se eu escolher um nome para minha vulnerabilidade?

Acho que a complexidade dessas questões significa que se estamos procurando por um processo de cortador de cookies a seguir, não o acharemos. Fazer uma divulgação de segurança bem requer uma atenção especial aos detalhes do problema e experiência para saber o que pode dar errado. Nada supera o olho cuidadoso de alguém que já fez isso antes (e especialmente alguém que fez uma dúzia de vezes esta semana.) Então, agradeço novamente especificamente a Kurt Seifried.

Para muitos, não é apenas algo com o qual eles estão familiarizados

Eu já relatei alguns problemas de segurança, e eu tinha uma equipe de especialistas de segurança na Vend me ajudando com as respostas para muitas dessas questões difíceis. Mas os desenvolvedores de código aberto geralmente não são remunerados, contribuindo para uma comunidade em seus tempos livres. Perguntando ou, pior, esperando que um mantenedor voluntário se torne bem versado em normas de divulgação de segurança durante a noite é implorando problemas. Não é só que seja injusto e ligeiramente rude, mas não vai funcionar bem .

Estou bem ciente de frases semelhantes como “segurança é um processo e não uma característica”, e não estou defendendo que os desenvolvedores abdicem da responsabilidade de liberar código seguro e mantê-lo seguro. Mas o processo de divulgação de segurança é outra coisa . O número de acrônimos por si só faz com que o desenvolvimento web seja tão doméstico. E não devemos fingir que um interesse em, digamos, ajudar as pessoas a fazer pedidos HTTP se traduz em algo como um interesse na divulgação de erros de segurança .

A divulgação de segurança também é uma coisa terrível para desencadear um desenvolvedor que pode estar apenas começando. “Não seja um mantenedor se você não sabe como lidar com problemas de segurança” é míope; há uma diferença categórica entre saber como prevenir a injeção de XSS ou SQL e saber o que fazer quando encontrou uma vulnerabilidade de segurança de código aberto. Um é um conjunto básico de habilidades que eu aplico sempre que estou trabalhando em um aplicativo da web. E o outro é algo que eu faço apenas algumas vezes por ano (e que não espero que a maioria das pessoas esteja fazendo).

O problema de financiamento de infra-estrutura de código aberto

Deve ter “apenas” alguém que você possa chamar. Até lá, as divulgações como a de httpoxy permanecerão ad hoc e inconsistentes. Alguns serão bem tratados, e outros não.

É um problema difícil. Estou entusiasmado por ver o problema do “financiamento de infra-estrutura de fonte aberta” que foi discutido recentemente (por exemplo, uma grande discussão iniciada por Nadia Eghbal ). Tais discussões geralmente consideram explicitamente vulnerabilidades amplas de projetos cruzados como a httpoxy como o resultado natural da falta de tal financiamento. Acho que essa é uma ideia interessante. Você pode ver como isso é diretamente aplicável quando você considera o tempo que esta vulnerabilidade estava por perto, e a forma como foi consertada em uma forma de refeição por peça, em duas décadas e em um monte de diferentes softwares de código aberto.

Por que não foi retirado mais cedo? Por que não há alguém apenas observando correções em um idioma que possa afetar outro? É a mesma questão que a “divulgação é difícil” por trás de uma aparência diferente: sem tratar a infra-estrutura de código aberto como um fim em si (e conseguir que alguém funcione bem), continuaremos desapontados.

Esta não é uma tragédia da situação comum. Os comuns em si estão indo bem; mais pessoas que nunca estão usando, e contribuindo para isso. É a falta de instituições que o retiram. É como se devêssemos financiar um serviço de bombeiros até agora, mas estamos muito ocupados pastando nossos rebanhos na alimentação comunitária para lidar com o pincel no próximo campo. E quem quer lidar com isso de qualquer maneira? Isso deve ser deixado aos especialistas. (Embora, se estamos indo com essa metáfora, por favor , podemos ignorar a idade das brigadas privadas de incêndio e das marcas de seguro contra incêndio ?)

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *