As consequências de uma antiga vulnerabilidade SQLite

Um bug interessante em um dos DBMS embutidos mais populares.

Em outubro de 2022, pesquisadores da Trail of Bits publicaram uma análise detalhada de uma vulnerabilidade do SQLite DBMS. O artigo discute possíveis ataques via CVE-2022-35737, com consequências que vão desde uma simples falha de aplicativo até a execução arbitrária de código. O bug bastante trivial no código SQLite é interessante e potencialmente perigoso por dois motivos. Em primeiro lugar, está no SQLite desde outubro de 2000 – quase desde o início do desenvolvimento deste software de código aberto. Em segundo lugar, os recursos do SQLite tornam teoricamente possível atacar uma ampla gama de programas com SQLite dentro deles.

Recursos SQLite

SQLite é um DBMS compacto, de código aberto e embedado – lançado pela primeira vez há 22 anos (em agosto de 2000). “Embedado” é a definição chave aqui. SQLite não é instalado como software separado. Em vez disso, é usado como uma biblioteca para desenvolvedores de software que precisam trabalhar com bancos de dados. O SQLite está integrado por padrão, por exemplo: nos navegadores Google Chrome, Firefox e Safari; Android; aplicativos de rede; e muitos pacotes de lançamento de sistemas operacionais baseados no kernel Linux. O SQLite ganhou popularidade por sua licença aberta, confiabilidade e… segurança: poucas falhas graves foram encontradas no código do DBMS até agora.

Detalhes da CVE-2022-35737

Especialistas detectaram um bug no código da função sqlite3_snprintf, que é usada para interagir com o banco de dados em programas escritos em C/C++. Se você passar uma entrada de string muito grande (mais de 2 GB) para essa função, isso fará com que o programa trave; ou seja, um ataque de negação de serviço (DoS) torna-se possível. No código sqlite3_snprintf, uma variável inteira foi usada para calcular o tamanho do string. Se o string passado for muito grande, a variável pode ter um valor negativo. Isso faz com que um buffer de memória a ser alocado seja muito pequeno para gravar o string recebido. Ocorre um erro de overflow de buffer.

O erro provavelmente foi inserido no código há 22 anos, já que a passagem de gigabytes de parâmetros de função era improvável devido às limitações de recursos da época. Este não é mais o caso. Um ponto de interesse separado no relatório Trail of Bits é uma suposição sobre porque esse erro foi perdido durante o teste de código padrão. O procedimento de teste visa principalmente verificar o código recém-adicionado ou modificado, enquanto o código aqui não foi alterado em mais de duas décadas. É muito difícil detectar essas vulnerabilidades com fuzzing – que está alimentando parâmetros aleatórios como entradas de função. Os métodos comuns de fuzzing não envolvem a geração de strings de tamanho tão grande. Os autores da pesquisa concluem que o fuzzing não pode substituir totalmente a análise estática de código, incluindo a realizada manualmente.

Implicações nebulosas

O Trail of Bits foi capaz de “modernizar” o ataque DoS original para que pudesse executar código arbitrário manipulando cuidadosamente o conteúdo e o tamanho do parâmetro passado. Embora os autores do artigo tenham mostrado uma prova de conceito funcional demonstrando exemplos de ataques, esses são um exercício puramente teórico de atacar o próprio SQLite. No entanto, como mencionado acima, o SQLite é um DBMS embedado, portanto, para causar danos reais, alguém precisaria atacar um aplicativo com código SQLite incorporado.

Acontece que há muitas suposições na pesquisa, e a possibilidade prática de realmente explorar a vulnerabilidade ainda não foi comprovada. Existem outras limitações. De acordo com dados dos desenvolvedores do SQLite, o bug é relevante apenas para a interface de aplicativos C e somente se o código for compilado com determinados parâmetros. Os próprios pesquisadores do Trail of Bits apontam para a impossibilidade de um ataque se o SQLite foi compilado usando stack canaries. Esse é, essencialmente, um método adicional de proteção contra os ataques de overflow de buffer – impedindo a execução de código arbitrário mesmo quando o overflow em si é possível.

A vulnerabilidade foi resolvida no SQLite 3.39.2, lançado em julho de 2022. No entanto, a patch teve pouco efeito. Os desenvolvedores de software que usam o SQLite como parte de seu próprio código provavelmente terão que atualizar seus códigos e distribuir uma nova versão do software. Até então, a vulnerabilidade permanecerá lá. E não esqueça que muitos programas utilizando o SQLite não são mais suportados.

Ainda não está claro o quanto essa vulnerabilidade é perigosa – ou se pode ser explorada na prática. A julgar pela definição dos desenvolvedores do SQLite, a chance de um ataque real é pequena – mas não zero. Enquanto isso, o bug foi adicionado à coleção de defeitos de longa duração que podem causar dores de cabeça para desenvolvedores de software.

Dicas