CVE-2019-9978
Patch now. It under exploitation confirmed by CISA and has a working public exploit.
Apply updates per vendor instructions.
Summary
Falha de Cross-Site Scripting (XSS) armazenado no plugin Social Warfare para WordPress (e sua variante Pro), presente em uma função de depuração acessível sem autenticação via wp-admin/admin-post.php. O endpoint aceita um parâmetro swp_url que o plugin busca e grava como configuração do site sem sanitização, permitindo injetar JavaScript persistente que executa no contexto de qualquer visitante — incluindo administradores logados. Foi explorada em massa em março de 2019 antes da divulgação pública, está no catálogo KEV da CISA, e o CVSS 6.1 subestima o risco prático: é pré-autenticação, automatizável e afetou site com dezenas de milhares de instalações ativas.
Technical detail
A causa raiz (CWE-79, XSS armazenado) está numa rotina de depuração do plugin, acionada pelo parâmetro swp_debug=load_options no endpoint wp-admin/admin-post.php. Essa rotina recebe outro parâmetro, swp_url, faz uma requisição para a URL informada e trata o conteúdo retornado como um array de opções de configuração do plugin (campos como 'twitter_id', usados para atribuição de autoria em compartilhamentos), gravando-o diretamente no banco de dados do WordPress sem qualquer sanitização ou escaping.
Como o admin-post.php é registrado no WordPress para aceitar requisições tanto de usuários autenticados quanto não autenticados (dependendo de como a action é gravada), e a função de debug não valida sessão nem nonce, o atacante controla integralmente o conteúdo remoto buscado — ele hospeda um payload (por exemplo, num paste público) contendo um valor como '">...' dentro do campo esperado e o plugin importa esse valor como configuração legítima.
O payload armazenado é depois renderizado sem escaping nas páginas que exibem os botões de compartilhamento social (front-end) e possivelmente em telas administrativas do plugin, disparando execução de JavaScript arbitrário no navegador de qualquer visitante ou administrador que carregue a página afetada. Por ser armazenado (não refletido), um único disparo compromete o site persistentemente até a limpeza manual da opção corrompida.
How it’s exploited
O vetor é uma única requisição HTTP GET não autenticada para /wp-admin/admin-post.php?swp_debug=load_options&swp_url=, sem necessidade de login, CSRF token ou interação prévia com a vítima — o único pré-requisito real é o plugin estar instalado, ativo e em versão anterior à 3.5.3. A campanha observada em março de 2019 usou pastebins públicos hospedando o payload disfarçado de configuração do plugin (campo 'twitter_id' contendo script codificado em fromCharCode), e a Sucuri registrou tentativas de mais de cem IPs distintos em poucos dias, com o script injetado redirecionando visitantes para sites maliciosos.
A exploração é trivial de automatizar (por isso o EPSS alto e a listagem no KEV) e não exige conhecimento de credenciais nem de estrutura interna do site-alvo, só a URL pública do site WordPress com o plugin ativo. Existem PoCs públicas, incluindo uma submissão de 2025 na lista Full Disclosure descrita pelo autor como 'Remote Code Execution' — rotulagem que não corresponde à natureza real da falha (XSS armazenado); a CVE oficial e a análise da Sucuri confirmam XSS, não execução de código no servidor. A confusão provavelmente vem do fato de que XSS armazenado atingindo um administrador logado pode ser encadeado (via ações administrativas do WordPress, como edição de plugin/tema) para chegar a RCE, mas isso é uma etapa adicional, não parte do exploit documentado.
O impacto final documentado é sequestro de sessão/ações no contexto do navegador da vítima e redirecionamento para infraestrutura maliciosa — consistente com campanhas de infecção em massa (padrão associado a famílias como Balada Injector) que visam SEO spam e redirecionamento, não necessariamente controle total do servidor.
Versions
How to protect
A correção do fornecedor é a atualização para a versão 3.5.3 do Social Warfare (e Social Warfare Pro), que remove ou neutraliza a rota de debug vulnerável. Não há indicação nas fontes de backport para ramos anteriores — trata-se de um plugin de terceiros sem versões LTS documentadas, então a única via oficial é subir para 3.5.3 ou posterior.
Se a atualização imediata não for possível, o paliativo real é bloquear no WAF ou no servidor web requisições para /wp-admin/admin-post.php contendo os parâmetros swp_debug=load_options e swp_url — a Sucuri recomendou exatamente essa virtual-patch enquanto o update não era aplicado. Outra opção de custo baixo é desativar o plugin até a atualização, já que a função de debug não é usada em operação normal do site (não há perda funcional relevante em desativar temporariamente). Vale checar e limpar manualmente as opções do plugin no banco de dados (wp_options) caso a exploração já tenha ocorrido antes da correção, pois o payload permanece armazenado até ser sobrescrito.
Não funciona como mitigação apenas restringir acesso ao painel /wp-admin por IP ou senha adicional, porque o endpoint admin-post.php explorado não exige autenticação prévia — a falha está no processamento da requisição em si, não em contornar login.
How to detect
O indicador mais confiável, segundo a Sucuri, é buscar nos logs de acesso requisições a qualquer arquivo PHP dentro de /wp-admin/ contendo os parâmetros swp_debug e swp_url — em particular GET para admin-post.php?swp_debug=load_options&swp_url=, frequentemente apontando para pastebin.com/raw/... ou hosts similares usados para hospedar o payload. Respostas com código 403 nesses padrões (bloqueadas por WAF) ainda indicam tentativa de exploração, não sucesso.
Como sinal secundário, vale inspecionar a tabela wp_options do WordPress por valores de configuração do Social Warfare (campos como 'twitter_id') contendo tags ou JavaScript codificado — presença disso confirma exploração bem-sucedida e persistência do payload, mesmo que o plugin já tenha sido atualizado depois.