Site Doctor em WordPress: quatro problemas que ninguém tinha visto

12 min de leitura devteam
Site Doctor em WordPress

Quatro casos reais de sites que administramos com Site Doctor. Todos passaram meses parecendo saudáveis.


Quem administra sites WordPress de clientes conhece a sensação: o painel está verde, o site abre, ninguém reclamou. E mesmo assim você tem a impressão incômoda de que existe alguma coisa acontecendo que você não está vendo.

Você tem razão. Quase sempre tem.

O problema não são as falhas que gritam. Um erro 500 você descobre em minutos — o cliente liga. O problema são as que ficam caladas: o post agendado que não saiu, o formulário que parou de enviar, a proteção que você acha que está ligada e não está, os dados de clientes que continuam guardados anos depois de deixarem de ser úteis.

Nenhuma dessas dispara alerta nenhum. Você descobre quando o cliente pergunta.

Foi por isso que a gente construiu o Site Doctor — primeiro para os nossos próprios sites, porque a nossa agência tinha exatamente esse problema. Este texto não é sobre a ferramenta. É sobre quatro coisas que ela encontrou, e sobre por que cada uma delas seria muito difícil de encontrar de outro jeito.

Nenhum site, cliente ou domínio é identificado.

Antes: como isso funciona, em três peças

Vale explicar rápido, porque muda o que dá para perguntar.

O painel — orquestra as verificações, guarda o histórico e decide o veredito.

O conector — um plugin WordPress que você instala no site. Ele responde 21 operações de leitura, cada uma com assinatura verificada. Ele não tem nenhuma operação de escrita. Isso não é uma política que a gente promete cumprir: é código que não existe. Instalar não muda, não quebra e não apaga nada.

A interface de IA — um servidor MCP. Você conecta a sua IA (Claude, ChatGPT) e passa a perguntar em português. Ela lê o estado dos sites e responde. Nunca vê uma credencial.

Essa última parte é a que muda o jogo, e é por isso que os casos abaixo estão escritos como perguntas. Não existe painel com um gráfico para cada uma delas. O que existe é a possibilidade de perguntar qualquer coisa e ter alguém — algo — capaz de ir buscar a resposta em vinte lugares diferentes e cruzar tudo.


Site Doctor cron travado

Caso 1 — O site que passou 17 dias sem publicar nada, e não deu um único erro

A pergunta: “Este site está conectado há três dias e não mandou um único evento. Os scans funcionam normalmente. O que está acontecendo?”

A gente não foi procurar um problema de cron. Foi investigar um detalhe chato de encanamento: o site respondia às nossas consultas, mas não estava nos enviando nada de volta.

O que voltou:

O WP-Cron estava morto. Não a nossa tarefa — todas.

Tarefas agendadas299
Vencidas298 (99,7%)
A mais antiga, parada havia17,2 dias

Dezessete dias sem publicar post agendado, sem rodar atualização automática, sem manutenção de plugin, sem nada. E duas causas empilhadas:

A primeira, DISABLE_WP_CRON = true. É o padrão em hospedagem gerenciada e está correto — em vez de o WordPress disparar o cron a cada visita, o cron de sistema do host chama o wp-cron.php. Mais eficiente. Só que o gatilho deixa de ser seu.

A segunda, a fila entupida: uma única tarefa estava enfileirada 216 vezes. Uma array de cron inchada faz o executor estourar o tempo antes de chegar no resto.

E no mesmo banco, de brinde: 26 tabelas órfãs ocupando 115,8 MB, deixadas por um plugin de segurança que não está instalado. A maior sozinha tinha 64,6 MB. Nenhum desinstalador remove isso — o plugin já não está lá para rodar um.

Depois da limpeza: cron de 299 para 67 tarefas, tabelas dropadas, 115,8 MB de volta. O push rodou em 1,4 segundo e entregou 50 eventos represados, com zero erro. As tarefas estavam saudáveis o tempo todo. Quebrado era só o gatilho.

Por que seria difícil achar de outro jeito: porque não havia nada para achar. Sem erro, sem alerta, sem tela branca, sem entrada no log. O WordPress não sabe que o cron dele não está sendo chamado — não tem como saber. A única pista era um silêncio, e silêncio não aparece em dashboard nenhum. A pergunta que destravou tudo nem era sobre cron.


Caso 2 — O 2FA que estava ligado e não protegia absolutamente nada

A pergunta: “Todos os administradores deste site estão com 2FA ativo?”

Pergunta de rotina, dessas de checklist. A resposta foi bem pior do que “não”.

O que voltou:

A tabela de segredos TOTP estava vazia. Nenhum dos 4 administradores tinha gerado um segredo. Zero de quatro.

O detalhe cruel: a obrigatoriedade de 2FA para o papel de administrador estava ligada. Alguém entrou no painel, ativou a exigência, viu a chavinha verde e foi embora tranquilo. Só que forçar o papel sem ninguém enrolado não bloqueia nada. A proteção efetiva era zero — com a aparência exata de estar tudo certo.

E ao investigar por que um dos admins tinha sessão ativa sem nenhum registro de login, apareceu a segunda camada, que é a que interessa de verdade:

O SSO da hospedagem contorna o 2FA do plugin — por design.

Lendo o código do mu-plugin de sign-on do host:

public function login_user( $user, $start_time, $request_id ) {    wp_clear_auth_cookie();    wp_set_auth_cookie( $user->ID, true );   // cookie direta, remember-me 14d    wp_set_current_user( $user->ID );    do_action( 'wp_login', $user->user_login, $user );

Ele grava o cookie de autenticação direto, sem passar por wp_signon() nem pelo filtro authenticate — que é exatamente onde o plugin de segurança injeta o desafio de 2FA. O hook wp_login só roda depois, quando o cookie já existe.

Isso não é vulnerabilidade nem sinal de invasão: é como SSO de hospedagem gerenciada funciona em todo lugar. Mas define o perímetro real de autenticação do site:

O limite de autenticação efetivo não é o WordPress. É a conta do portal da hospedagem. Quem tem acesso ao portal é administrador de fato do site, com ou sem 2FA no WordPress.

O 2FA do plugin continua necessário — é ele que cobre o wp-login.php, que naquele site tinha levado 34.961 tentativas de login falhas. Só que ele cobre uma porta, e existem duas.

Por que seria difícil achar de outro jeito: a interface diz “2FA obrigatório para administradores: ativo”. Para saber que aquilo era decorativo, era preciso consultar a tabela de segredos e descobrir que estava vazia. E para entender a segunda porta, era preciso ler o código-fonte de um mu-plugin que o host instala sozinho e que ninguém abre nunca. Nenhuma dessas duas coisas está a um clique de distância.


Caso 3 — A assinante nova que nunca recebeu a newsletter

A pergunta: “Uma assinante nova não está recebendo a newsletter. O acesso pago dela funciona normalmente. Onde quebrou?”

Um caso de suporte comum. Podia ser mil coisas: chave de API vencida, lista errada, e-mail na caixa de spam.

O que voltou: nenhuma das mil coisas. Era um defeito no código do plugin.

Primeiro o que foi descartado com evidência, porque isso importa tanto quanto o achado: a chave da ferramenta de e-mail era válida (teste de conexão OK), a lista de destino era a certa (3.296 assinantes ativos, segmentos corretos), e a inclusão manual de um contato funcionava — retornava HTTP 201. Não era integração quebrada.

A causa estava duas camadas abaixo. O complemento que faz a sincronização escuta um evento que o plugin de paywall dispara apenas no caminho de “usuário WordPress novo”. Quando quem assina é um usuário que já tinha conta no site, o fluxo passa por outra função — que não dispara aquele evento. O complemento nunca fica sabendo.

A assinante em questão tinha conta desde 2021. Foi pelo caminho de usuário existente. Nunca sincronizou.

E aqui a parte que transforma um chamado em um problema de negócio: a maioria da base tinha conta antiga, porque o site havia migrado de outra plataforma. Não era uma assinante sem newsletter. Era uma categoria inteira de assinantes, silenciosamente, havia meses.

Por que seria difícil achar de outro jeito: para chegar nisso foi preciso ler o código de dois plugins de terceiros e seguir a bifurcação “usuário novo / usuário existente” por cinco arquivos diferentes, até achar os dois pontos onde os caminhos divergem. Nenhum log registra isso, porque do ponto de vista do plugin não aconteceu erro nenhum: ele simplesmente nunca foi chamado. Testar com um e-mail novo — que é o que qualquer um faria — passa pelo caminho que funciona, e o problema não reproduz.


Caso 4 — Os 317 formulários com dados de pacientes guardados desde 2024

A pergunta: “Que dados pessoais este site está guardando, e desde quando?”

Ninguém tinha reclamado. Não havia incidente. Essa é uma pergunta de higiene, dessas que só se faz quando alguém lembra.

O que voltou:

O site guardava 317 envios do formulário de contato, o mais antigo de setembro de 2024. Cada um com nome, e-mail, mensagem, mais oito campos adicionais, o IP, o user agent e a página de origem. Sendo um site da área de saúde, boa parte desse conteúdo é informação de paciente.

311 tinham mais de 90 dias.

Não estavam expostos — isso foi verificado antes de qualquer conclusão: diretório de uploads retornando 403, endpoint de usuários da API retornando 401, nenhum dump de banco acessível. Não era incidente. Era superfície de exposição acumulada, esperando o primeiro backup que vazasse.

Antes de apagar qualquer coisa, tudo foi exportado para um diretório fora do alcance da web, com hash SHA-256 e contagem conferida linha a linha contra o banco. O export foi gerado duas vezes e deu o mesmo hash — se alguém precisar daqueles dados amanhã, eles existem e é possível provar que não foram alterados.

Depois: 317 envios para 6.

Por que seria difícil achar de outro jeito: porque não é um defeito. Nada estava quebrado, ninguém ia reclamar, e nenhum monitoramento do mundo dispara alerta por “este formulário vem funcionando bem há dois anos”. É exatamente o tipo de coisa que só aparece quando alguém faz a pergunta — e a pergunta só é feita se for barato fazer.


O que a ferramenta não faz

Vale ser explícito, porque isso costuma ser o que as pessoas perguntam primeiro:

Ela não faz backupnão atualiza pluginnão constrói página e não bloqueia ataque como um firewall. Ela diagnostica e avisa. Quando encontra algo para corrigir, ela te entrega os passos exatos — e quem aplica é você ou o seu time.

Isso é decisão de projeto, não limitação. É o que permite instalar em site de cliente sem medo: o conector não tem nenhuma operação de escrita. Ele não pode quebrar o que veio observar. Nos quatro casos acima, toda mudança foi aplicada por uma pessoa, depois de ler o diagnóstico.

O padrão dos quatro

Reparou que nenhum dos quatro problemas era o problema que a gente foi procurar?

O cron morto apareceu investigando encanamento. O 2FA vazio apareceu numa pergunta de checklist. O defeito da newsletter apareceu num chamado de suporte comum. E os dados de paciente apareceram porque alguém teve a curiosidade de perguntar.

É esse o ponto. Ferramenta de monitoramento tradicional responde as perguntas que alguém previu na hora de construir o painel — o site está no ar, a página carrega rápido, o certificado vence quando. As perguntas que encontram esse tipo de coisa não são previsíveis. São específicas, sujas e diferentes a cada vez.

O que mudou para a gente não foi passar a ter mais gráficos. Foi passar a poder perguntar qualquer coisa e ter como ir buscar a resposta em vinte sites ao mesmo tempo, sem distribuir senha para ninguém e sem risco de encostar em nada.

Quer testar em um site seu?

Está em beta e a gente está abrindo aos poucos.

Se você administra 5 sites WordPress ou mais, escreva para a gente. Ligamos o Site Doctor em um deles — plugin somente leitura, 2 minutos de instalação — e mandamos por escrito, em 24 horas, o que ele encontrou. Ou você pode instalá-lo e conectar sua própria IA; dessa forma, você poderá fazer as mesmas perguntas e criar seus próprios relatórios para seus clientes.

Se não encontrar nada, mandamos isso também. É o resultado mais chato possível e ainda assim é informação: você passa a saber.

Gostou? Coloque em prática.

Teste o SYSWP grátis por 5 dias e veja como nossa plataforma resolve isso na prática.

Começar grátis →
Verified by Auditto
Protected by SysWP Shield