Segurança web

Desserialização insegura

Definição

A desserialização insegura é uma falha que ocorre quando uma aplicação reconstrói objetos a partir de dados controlados por um atacante, por exemplo com unserialize() em PHP. Os métodos disparados automaticamente durante essa reconstrução podem levar à exclusão de arquivos ou à execução de código.

Desserialização insegura, Segurança web

Serializar é transformar um dado estruturado (um array, um objeto) em texto para armazená-lo ou transmiti-lo; desserializar é a operação inversa. O problema surge quando o dado a ser reconstruído vem de fora: um cookie, um campo de formulário, um parâmetro de URL. O MITRE classifica essa fraqueza como CWE-502, “desserialização de dados não confiáveis”; em PHP, também se fala em injeção de objeto (PHP Object Injection).

Como o ataque funciona em PHP

Uma string serializada do PHP descreve ela mesma o tipo do que contém. Por exemplo, O:4:"User":1:{s:4:"name";s:3:"Bob";} designa um objeto da classe User com uma propriedade name. Um atacante que controla essa string pode, portanto, pedir a unserialize() que crie um objeto de qualquer classe carregada pelo site, com os valores que quiser.

Esse objeto se torna perigoso por causa dos métodos mágicos que o PHP chama automaticamente: __wakeup() na reconstrução, __destruct() na destruição, __toString() quando o objeto é usado como texto. Encadeando classes já presentes no código do site, cujos métodos chamam uns aos outros, o atacante monta uma cadeia de gadgets (cadeia POP) que termina em uma ação perigosa: exclusão de arquivo, gravação de um arquivo PHP, execução remota de código.

Etapas de uma injeção de objeto PHP: o atacante envia uma string serializada forjada em um cookie ou campo, a aplicação chama unserialize() e reconstrói um objeto da classe escolhida, o PHP executa automaticamente os métodos mágicos __wakeup, __destruct ou __toString, classes existentes se encadeiam em uma cadeia de gadgets POP e o efeito final é a exclusão de arquivos, a gravação de um arquivo PHP ou a execução de código
Nenhum código é injetado diretamente: o atacante desvia classes que já existem no site.

Um exemplo no WordPress: GiveWP

A falha CVE-2024-5932 do plugin de doações GiveWP, até a versão 3.14.1 inclusive, permitia que um atacante não autenticado injetasse um objeto PHP pelo parâmetro give_title. Uma cadeia de gadgets presente no próprio plugin levava à execução de código e à exclusão de arquivos; a pontuação CVSS 3.1 publicada é 10. Nosso artigo sobre injeção de objetos PHP detalha esse caso e o mecanismo.

A desserialização também serve aos atacantes depois que eles já estão dentro: o backdoor adicionado em 2025 ao portfólio de plugins EssentialPlugin dependia de unserialize, como lembra nosso artigo sobre ataques à cadeia de suprimentos.

Vídeo: “DESSERIALIZAÇÃO INSEGURA - O que é isso?” (Guia Anônima)

No WordPress: unserialize e maybe_unserialize

O WordPress armazena muitos dados serializados, principalmente na tabela de opções e nos metadados. A função maybe_unserialize() serve para lê-los: se o dado parece serializado (is_serialized()), ela chama unserialize(), sem restringir as classes permitidas. Ela não traz, portanto, nenhuma proteção e nunca deve receber um dado vindo de um visitante.

  • Troque dados em JSON: a documentação do PHP recomenda json_encode() e json_decode() para todo dado que passa pelo usuário. O JSON nunca cria objetos de classes arbitrárias.
  • Não espere demais de allowed_classes: essa opção de unserialize() limita as classes instanciadas, mas o manual do PHP avisa que não se deve passar dados não confiáveis para essa função, seja qual for o valor dela.
  • Assine o que precisa ir e voltar: se um dado serializado realmente precisa passar pelo navegador, uma assinatura HMAC verificada antes de qualquer leitura impede que ele seja alterado.
  • Mantenha o PHP atualizado: desde o PHP 8.0, os metadados dos arquivos phar não são mais desserializados automaticamente, o que fechou um caminho de ataque ligado à inclusão de arquivos e aos wrappers.

Do lado do administrador, a principal defesa continua sendo atualizar os plugins afetados, já que a falha está no código deles. Um firewall de aplicação web pode bloquear strings serializadas suspeitas enquanto isso, e os alertas de vulnerabilidades do WP Masquerade Pro avisam quando um plugin instalado está entre as versões afetadas. O WP Masquerade não filtra as requisições por conta própria.

Para saber mais

  • Artigo Desserialização PHP e injeção de objetos explicadas
  • Página Alertas de plugins vulneráveis

Fontes

  1. MITRE CWE-502: Deserialization of Untrusted Data (link externo, abre em uma nova aba)
  2. PHP Manual: unserialize() (link externo, abre em uma nova aba)
  3. WordPress Developer Resources: maybe_unserialize() (link externo, abre em uma nova aba)
  4. CVE Record: CVE-2024-5932 (link externo, abre em uma nova aba)

Todas as definições

Segurança WordPress, sem ruído

Um e-mail quando importa: novos ataques observados, atualizações do plugin e guias práticos. Sem spam, cancelamento com um clique.

Comece de graça e mude para o Pro quando estiver pronto

A versão gratuita já oculta o WordPress e muda o endereço da página de login. O Pro acrescenta aliases, verificação em duas etapas e monitoramento.