Spam japonês no WordPress: diagnóstico e limpeza no banco

Spam japonês no WordPress: diagnóstico e limpeza no banco

Resposta rápida

O spam japonês no WordPress usa cloaking: mostra páginas em japonês só para o Google e o site normal para você. A limpeza depende de uma pergunta: as URLs de spam estão em wp_posts ou são geradas por um arquivo PHP? Depois de limpar banco e disco, as URLs precisam responder erro 4xx, e o intruso precisa sair do Search Console.

  • Compare a URL pedida como navegador e como Googlebot para confirmar o cloaking.
  • Se a URL de spam não existe em wp_posts, apagar post não resolve: o gerador está no disco.
  • wp core verify-checksums com include-root acha arquivos estranhos na raiz.
  • Para o Google, 404 e 410 têm o mesmo efeito; o 410 como regra de servidor evita que algo volte a servir página.
  • A ferramenta de Remoções é temporária, cerca de seis meses.
  • Spam que volta indica porta aberta: cron, mu-plugins, backdoor ou credencial.
Nome técnicoJapanese keyword hack, com cloaking por user agent e referer
Tratamento de 404 e 410 pelo Googleiguais: todos os 4xx, exceto 429, indicam conteúdo inexistente
Duração de uma remoção no Search Consolecerca de seis meses
Verificação de plugins por checksumsó para plugins hospedados no WordPress.org
Sinal de invasão no Search Consoleproprietário desconhecido verificado no site

O sintoma chega quase sempre do mesmo jeito: alguém pesquisa o nome da empresa, e o Google devolve o seu domínio com títulos em japonês, anúncios de bolsa de grife, relógio e remédio. Você abre o site e ele está normal. O painel está normal. Os posts estão normais. É o spam japonês no WordPress — o que o Google chama de Japanese keyword hack —, e a parte que confunde é justamente essa: o site foi feito para parecer limpo para você e sujo só para o buscador.

Este guia é o roteiro que usamos para diagnosticar e limpar o spam japonês no WordPress. Ele parte de uma pergunta que a maioria dos tutoriais pula e que decide todo o resto: as páginas de spam estão gravadas no banco ou são geradas por um arquivo? A resposta muda onde você procura, o que você apaga e por que o spam volta na semana seguinte quando a limpeza é feita pela metade.

Por que você não vê as páginas em japonês

O truque se chama cloaking: o código malicioso olha quem está pedindo a página e decide o que entregar. Se a requisição vem do robô do Google, ou de um visitante que clicou num resultado de busca, ele serve a página de spam. Se vem de você, digitando o endereço, ele serve o site normal — ou um erro 404. O guia do próprio Google sobre o Japanese keyword hack descreve exatamente esse comportamento: as páginas hackeadas podem até responder 404 para você e, mesmo assim, continuar com conteúdo para o robô.

O segundo traço característico é mais grave. O invasor costuma se cadastrar como proprietário do seu site no Google Search Console, subindo um arquivo de verificação na raiz. Com isso ele envia sitemap, pede indexação e acompanha o desempenho do spam usando a sua reputação de domínio. Se você recebeu um e-mail do Google dizendo que um novo proprietário foi adicionado e não reconhece o nome, trate como invasão confirmada.

Diagnóstico em 15 minutos

1. Busca com o operador site:. Pesquise site:seudominio.com.br no Google. Ele lista o que está indexado, inclusive as páginas hackeadas. Para isolar o spam, combine o operador com um caractere japonês muito comum, como site:seudominio.com.br の. Anote o formato das URLs: é isso que vai virar regra de bloqueio mais adiante. Elas costumam seguir um padrão — um diretório inventado, uma sequência numérica terminada em .html, um parâmetro de consulta estranho.

2. Veja o que o robô vê. Compare a mesma URL pedida como navegador e como Googlebot:

# como visitante comum
curl -s -o /dev/null -w "%{http_code}n" https://seudominio.com.br/url-suspeita/

# como o robô do Google
curl -s -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 
  https://seudominio.com.br/url-suspeita/ | head -40

# como quem chegou pela busca
curl -s -e "https://www.google.com/" https://seudominio.com.br/url-suspeita/ | head -40

Se a segunda ou a terceira chamada devolvem texto em japonês e a primeira não, o cloaking está confirmado. Alguns scripts checam também o IP de origem, e aí o curl não basta: use a Inspeção de URL do Search Console com o teste da URL publicada, que busca a página a partir da infraestrutura do Google e mostra o HTML que o robô recebeu.

3. Search Console, em três telas. Em Problemas de segurança, veja se o Google já sinalizou o site. Em Configurações → Usuários e permissões, confira a lista de proprietários. Em Sitemaps, procure qualquer sitemap que você não enviou. E no relatório de Desempenho, filtre por consultas: se aparecem termos em japonês com impressão, você tem a dimensão real do estrago.

4. A pergunta que decide a limpeza. Pegue três URLs de spam da busca e procure-as no banco:

wp db prefix     # confirme o prefixo real das tabelas antes de qualquer SQL

wp db query "SELECT ID, post_type, post_status, post_date, post_name
  FROM wp_posts WHERE post_name LIKE '%trecho-da-url-de-spam%'"

Se as páginas existem em wp_posts, você está no caso do spam gravado: alguém ganhou acesso com permissão de publicar e criou conteúdo em massa. Se não existem, você está no caso mais comum e mais trabalhoso: um arquivo PHP intercepta a requisição e fabrica a página na hora. Nesse caso, apagar post não resolve nada — o gerador está no disco.

A tabela de sintomas: onde está o spam e o que fazer

SintomaOnde provavelmente estáCorreção
URL de spam existe em wp_postsConteúdo gravado por conta com permissão de publicarApagar os posts, auditar usuários, trocar senhas e chaves
URL de spam não existe no banco, mas responde para o GooglebotArquivo PHP gerador (raiz, tema, mu-plugins, uploads)Verificar checksums, reinstalar core, remover arquivos estranhos
Spam só aparece com referer do GoogleRegra no .htaccess ou código no index.phpSubstituir o .htaccess por um limpo e conferir o index.php
Sitemap que você não enviou no Search ConsoleArquivo .xml físico na raiz ou gerado por scriptRemover o arquivo e o sitemap do Search Console
Proprietário desconhecido no Search ConsoleArquivo google*.html ou meta tag de verificaçãoRemover o usuário e o token de verificação
Spam some e volta dias depoisBackdoor, tarefa agendada ou credencial ainda válidaVarredura de cron, mu-plugins e usuários; troca de chaves

Antes de apagar qualquer coisa: cópia do estado invadido

Parece contraintuitivo guardar o site sujo, mas é o que permite responder depois à pergunta por onde entraram. Exporte o banco e compacte os arquivos antes de mexer:

wp db export ~/incidente-$(date +%F)-banco.sql
tar -czf ~/incidente-$(date +%F)-arquivos.tar.gz --exclude=wp-content/cache .

Guarde as duas cópias fora da pasta pública. Elas são evidência, não backup para restaurar — não restaure a partir delas.

Limpeza no banco: wp_posts

No caso do spam gravado, o volume costuma ser grande e concentrado em poucas datas. Liste o que foi criado recentemente, de qualquer tipo e qualquer status:

wp post list --post_type=any --post_status=any 
  --fields=ID,post_type,post_status,post_date,post_title 
  --orderby=post_date --order=DESC | head -60

E procure o texto japonês diretamente. O caractere の aparece em praticamente todo texto em japonês, o que o torna um filtro simples e eficiente:

wp db query "SELECT ID, post_type, post_status, post_date, LEFT(post_title, 60)
  FROM wp_posts
  WHERE post_title LIKE '%の%' OR post_content LIKE '%の%'
  ORDER BY post_date DESC LIMIT 100"

Confira se o resultado não pega conteúdo legítimo — um site com versão em japonês, por exemplo — e então apague com --force, que pula a lixeira:

wp post delete $(wp db query "SELECT ID FROM wp_posts
  WHERE post_title LIKE '%の%'" --skip-column-names) --force

Repare também em post_type que você não reconhece. Spam gravado por plugin comprometido às vezes usa um tipo de post próprio, que nem aparece no menu do painel.

Limpeza no banco: wp_options

A tabela wp_options é o esconderijo preferido para o que precisa sobreviver a uma reinstalação de arquivos: código em base64 guardado numa opção e executado por um trecho curto plantado em outro lugar. Três consultas cobrem o essencial.

As maiores opções do site, que é onde carga útil costuma aparecer:

wp db query "SELECT option_id, option_name, LENGTH(option_value) AS tamanho, autoload
  FROM wp_options ORDER BY tamanho DESC LIMIT 25"

Opções com os padrões de ofuscação que o guia do Google manda procurar em arquivos — base64_decode, eval, gzinflate, str_rot13, strrev — valem também para o banco:

wp db query "SELECT option_id, option_name FROM wp_options
  WHERE option_value LIKE '%base64_decode%'
     OR option_value LIKE '%eval(%'
     OR option_value LIKE '%gzinflate%'
     OR option_value LIKE '%str_rot13%'"

E as opções que mudam o comportamento do site inteiro, para conferir à mão:

wp option get siteurl
wp option get home
wp option get active_plugins --format=json
wp option get template
wp option get stylesheet

Um plugin em active_plugins que não aparece na tela de plugins é sinal forte de código escondido. Antes de apagar uma opção suspeita, pesquise o nome dela: vários plugins legítimos guardam dados em base64, e apagar a opção errada quebra o plugin, não o invasor.

Limpeza nos arquivos: onde o gerador mora

Se as URLs de spam não estão no banco, o trabalho é no disco. O WP-CLI compara o core com as somas oficiais do WordPress.org, e com --include-root avisa também sobre qualquer arquivo estranho na raiz — que é exatamente onde geradores de spam gostam de ficar:

wp core verify-checksums --include-root
wp plugin verify-checksums --all

A documentação do verify-checksums detalha as opções. Uma limitação importa: a verificação de plugins só funciona para plugins hospedados no WordPress.org. Plugin premium e tema precisam ser comparados com um pacote baixado de novo do fornecedor.

Depois, procure PHP modificado recentemente fora do core e os arquivos de verificação do Google que você não criou:

find . -name "*.php" -mtime -30 -not -path "./wp-content/cache/*" -ls
find wp-content/uploads -name "*.php" -ls
ls -la google*.html *.xml 2>/dev/null
grep -rlE "base64_decode|gzinflate|str_rot13|eval(" wp-content --include=*.php | head -50

O grep vai trazer falso positivo — bibliotecas legítimas usam base64_decode. O que procura é a combinação: arquivo com nome aleatório, data recente, uma linha só de código ofuscado. Por fim, o .htaccess: se você não tem regra personalizada, troque o arquivo inteiro por uma cópia nova com as regras padrão do WordPress, como o próprio guia do Google recomenda. Reinstale o core com wp core download --force
--skip-content
para sobrescrever qualquer arquivo alterado.

O sitemap falso

O spam japonês costuma vir com um sitemap próprio, feito para acelerar a indexação das páginas falsas. Ele aparece de duas formas: um arquivo .xml físico na raiz do site, ou um endereço que o gerador responde dinamicamente. Plugins de SEO como Rank Math e Yoast geram o sitemap de forma dinâmica, sem arquivo no disco — então um sitemap.xml físico na raiz que você não criou é suspeito por definição, e ainda por cima atropela o sitemap do plugin.

Remova o arquivo, abra o relatório de Sitemaps no Search Console, remova qualquer sitemap que não seja o seu e reenvie o legítimo. Se o seu sitemap passou a servir cópia antiga depois da limpeza, o problema é de cache, e resolvemos isso em sitemap do Rank Math que não atualiza.

410 para as URLs de spam (e o que ele não faz)

Depois de limpo, cada URL de spam precisa devolver erro — não a página inicial, não um redirecionamento. É comum ver site limpo que redireciona tudo que não existe para a home, e isso mantém as URLs respondendo com sucesso no fim da cadeia.

Um ponto honesto sobre o 410: a documentação do Google sobre códigos HTTP diz que todos os erros 4xx, exceto o 429, são tratados da mesma forma — o conteúdo é considerado inexistente e a URL sai do índice. Ou seja, 404 e 410 têm o mesmo efeito para o Google. A vantagem do 410 é outra: ele é uma regra explícita no servidor, que responde antes do WordPress carregar. Nenhum plugin de redirecionamento, nenhuma sugestão de URL parecida e nenhum gerador que tenha sobrado consegue transformar aquela resposta em página.

Use o padrão de URL que você anotou no diagnóstico. No Apache ou LiteSpeed, antes do bloco do WordPress no .htaccess:

# URLs do spam japonês: 410 antes do WordPress carregar
RewriteEngine On
RewriteRule ^diretorio-inventado/ - [G,L]
RewriteRule ^[0-9]{6,}.html$ - [G,L]

No Nginx:

location ~ ^/diretorio-inventado/ { return 410; }
location ~ ^/[0-9]{6,}.html$    { return 410; }

Troque os padrões de exemplo pelos do seu caso e teste com curl -sI https://seudominio.com.br/url-de-spam — a primeira linha precisa trazer 410. Teste também duas URLs legítimas, para garantir que a regra não pegou conteúdo seu.

Search Console depois da limpeza

A ordem importa:

  1. Remova o proprietário desconhecido e apague o token de verificação dele (o arquivo google*.html ou a meta tag). Sem apagar o token, ele se verifica de novo.
  2. Remova os sitemaps que não são seus e reenvie o legítimo.
  3. Use a ferramenta de Remoções nas URLs de spam mais visíveis. Ela é temporária: o próprio Google informa que uma remoção dura cerca de seis meses. Serve para tirar o spam da vista enquanto o 410 faz o trabalho permanente.
  4. Se houver alerta em Problemas de segurança, peça a revisão só depois de tudo acima.
  5. Acompanhe o site: com o caractere japonês toda semana. A queda é gradual.

Por que o spam volta

Quando o spam japonês reaparece dias depois da limpeza, quase nunca é um ataque novo. É o mesmo invasor usando uma porta que ficou aberta. As três mais comuns:

Tarefa agendada. Um evento no cron do WordPress recria o arquivo gerador. Liste com wp cron event list --fields=hook,next_run_relative,recurrence e investigue qualquer gancho que não pertença a um plugin instalado.

Must-use plugin. Arquivos em wp-content/mu-plugins carregam sempre, não podem ser desativados pelo painel e ficam numa aba separada da tela de plugins. Confira com wp plugin list --status=must-use e abra cada arquivo.

Credencial ainda válida. Se o invasor tem uma conta ou um cookie de sessão, ele volta pela porta da frente. Audite os administradores, troque as senhas e rotacione as chaves do wp-config.php com wp config shuffle-salts, que derruba todas as sessões abertas.

Para o roteiro geral de pós-invasão, com a parte de hospedagem e comunicação, veja como limpar um site WordPress invadido. E se o diagnóstico mostrou plugin adulterado, vale ler sobre a ferramenta que achou dezenas de milhares de plugins maliciosos em instalações WordPress.

Como não passar por isso de novo

O spam japonês é consequência, não causa. Ele entra por plugin vulnerável, senha vazada ou upload que executa PHP, e depois de limpo o que evita a reinfecção é fechar essas portas. As travas de maior retorno são negar execução de PHP em wp-content/uploads, desligar o editor de arquivos do painel, exigir segundo fator de quem publica e manter os plugins que recebem arquivo sempre na frente da fila de atualização. Organizamos todas elas por ordem de retorno em hardening WordPress: 21 travas.

E deixe um alerta simples de pé: uma busca semanal por site:seudominio.com.br の e a notificação de novo proprietário do Search Console chegando num e-mail que alguém lê. As duas juntas avisam em dias o que, sem elas, você descobre quando um cliente manda o print.

Perguntas frequentes

Por que vejo meu site normal, mas o Google mostra páginas em japonês?

Por causa do cloaking: o código malicioso entrega o spam só para o robô do Google ou para quem chega pela busca, e mostra o site normal, ou um 404, para quem digita o endereço. Compare a URL pedida como navegador e como Googlebot, ou use a Inspeção de URL do Search Console.

Apagar os posts em japonês resolve o spam?

Só se as páginas estiverem gravadas em wp_posts. No caso mais comum elas não estão no banco: um arquivo PHP gera o conteúdo na hora. Procure o trecho de uma URL de spam em wp_posts antes de decidir. Se não achar, o trabalho é no disco.

Devo usar 404 ou 410 nas URLs de spam?

Para o Google o efeito é o mesmo: a documentação oficial trata todos os 4xx, exceto o 429, como conteúdo inexistente. A vantagem do 410 como regra de servidor é responder antes do WordPress carregar, sem chance de redirecionamento ou de um gerador remanescente servir página.

A ferramenta de Remoções do Search Console tira o spam para sempre?

Não. A remoção é temporária e dura cerca de seis meses, segundo o próprio Google. Ela esconde as URLs mais visíveis enquanto a correção permanente, as URLs respondendo 4xx, faz efeito.

Por que o spam japonês volta depois da limpeza?

Porque ficou uma porta aberta: tarefa agendada que recria o arquivo gerador, arquivo em mu-plugins, backdoor em uploads ou credencial ainda válida. Revise o cron, os must-use plugins, os administradores e rotacione as chaves do wp-config.php.

Como saber se alguém se cadastrou no Search Console do meu site?

Abra Configurações e depois Usuários e permissões e confira os proprietários. O Google também envia e-mail quando um novo proprietário é verificado. Ao remover o intruso, apague o token de verificação dele, arquivo google*.html ou meta tag, senão ele se verifica de novo.