--- name: emcp-site-audit description: Auditoria de segurança, performance, base de dados e filesystem de um site WordPress via qualquer ligação MCP EMCP Tools, e recuperação de uma edição de IA falhada via o ledger de mudanças/rollback. Usar quando "scan-security mcp", "analyze-performance mcp", "rollback-change", "ledger de mudanças elementor", "falso positivo malware uploads", "query base de dados via mcp". layer: wiki --- # /emcp-site-audit — Auditoria e Rede de Segurança via EMCP Tools Aplica-se a qualquer ligação MCP EMCP Tools. Confirma o site alvo com `core/get-site-info`. ## Scan de segurança `scan-security` — só-leitura, autocontido, audita apenas o site ligado. Quatro áreas: heurísticas de malware PHP (uploads + plugins/temas activos; `deep:true` para a árvore completa), integridade de ficheiros do core WordPress (vs checksums oficiais), hardening de configuração (editor de ficheiros activo, output de debug, username admin, XML-RPC, divulgação de versão, HTTPS, security headers), e software desactualizado/abandonado. Devolve `{summary: {score, grade, counts: {critical, warning, pass, info}}, sections: {...}}`. **Tratar um achado `critical` como um reporte imediato e separado ao utilizador — nunca enterrado dentro de uma tarefa não relacionada.** Mas **`malware_uploads_php` (qualquer `.php` sob `wp-content/uploads/`, categoria `critical`) é uma heurística grosseira que assinala só a localização, não o conteúdo — tem um padrão confirmado e comum de falso positivo. Ler sempre o ficheiro assinalado com `read-file` e inspeccionar o conteúdo real antes de reportar como ameaça real.** Confirmado benigno num scan ao vivo (dois hits `critical`, mesmo id de achado, ambos falsos positivos): - `wp-content/uploads/index.php` — stub próprio do **core WordPress**, incluído por omissão em toda a instalação: `header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden'); die('403 Forbidden');`. Existe só para bloquear listagem de directório. **Nunca apagar este** — removê-lo *reduz* a segurança ao remover exactamente a protecção que fornece. - `wp-content/uploads//cache/index.php` (visto: WPForms) — mesmo padrão, incluído pelo plugin, ex. `header(...' 404 Not Found');`. Qualquer plugin que faça cache em `uploads/` tipicamente inclui um destes por directoria de cache. Regra de diagnóstico: um ficheiro `uploads/*.php` genuinamente malicioso contém lógica executável real (`eval`, `base64_decode`, `system`/`exec`/`shell_exec`, payloads ofuscados, marcadores de webshell) — um stub benigno tem 2-4 linhas, só `header()` + `die()`/`exit` opcional, nada mais. Se `read-file` mostrar só um stub de header/die, despromover o achado para informativo no reporte e **não** apagar o ficheiro. Se mostrar outra coisa — ameaça real, reportar de imediato e confirmar com o utilizador antes de apagar (o caminho de remoção confirmado seguro é `delete-file` se montada para a ligação, ou `wp eval`/`rm` via SSH quando não estiver — ver secção Filesystem abaixo). Achados `integrity_modified` (ficheiro do core difere dos checksums oficiais) também podem ser rotina — ex. `wp-includes/version.php` difere por desenho (é o próprio ficheiro de versão instalada do WordPress, espera-se que difira de uma baseline de checksum genérica). Cruzar o que mudou (`read-file` no ficheiro assinalado) antes de tratar um achado de integridade como indicador de comprometimento. ## Análise de performance `analyze-performance` — só-leitura. Analisa configuração do servidor, internals WordPress (tamanho da BD, opções autoloaded, backlog de cron, object cache, OPcache, contagem de plugins), e uma página alvo (por omissão a página inicial; passar `url` ou `post_id` para uma página específica). Devolve a mesma forma `{summary: {score, grade, counts}, sections}` que `scan-security`, com `status` por achado (`pass`/`warning`/`critical`), `message`, e `recommendation` — uma lista de acções priorizada já pronta, não reportar só o score. ## Base de dados (nível só-leitura) `list-tables` (contagens de linhas + tamanhos), `describe-table({ table })` (colunas/tipos/keys), `query({ sql })` — **só SELECT/SHOW/DESCRIBE/EXPLAIN, escritas e DDL são rejeitadas no servidor.** Resultados têm limite — para conjuntos grandes, restringir a query em vez de esperar paginação. O prefixo das tabelas varia por instalação (visto ao vivo: `wpne_` num site) — sempre `list-tables` primeiro em vez de assumir `wp_`. `insert-row`/`update-rows`/`delete-rows` existem no plugin mas estão comummente no deny-list em todos os sites de produção testados até agora — escritas SQL directas contornam a camada de validação do próprio WordPress. Não tentar sem confirmar primeiro que estão realmente montadas para essa ligação. ## Filesystem (nível só-leitura) `list-directory`/`read-file`/`search-files`, confinados à raiz da instalação WordPress. `read-file` recusa ficheiros de segredos no servidor — confirmado ao vivo: pedir `wp-config.php` devolve *"This file holds site secrets ... and cannot be read"* em vez de um erro ou do conteúdo, independentemente da variante de caminho tentada. `search-files({ query, extensions, path })` faz grep file:line numa árvore de directórios, com limite — bom para confirmar versão de plugin/tema ou um padrão de código específico sem SSH. `write-file`/`edit-file`/`delete-file` existem no plugin mas estão quase universalmente no deny-list (escritas directas no filesystem contornam toda a auditoria de shell/SSH) — tratar como indisponível salvo confirmação explícita de que está montada. Quando um ficheiro confirmadamente malicioso precisa de ser removido e `delete-file` não está montada, usar o canal SSH/wp-cli próprio do site em vez de forçar via MCP. ## Ledger de mudanças + rollback — a rede de segurança para toda escrita Elementor/conteúdo Toda a chamada mutante que este plugin expõe (edições Elementor, e nalguns sites também escritas de filesystem/BD) fica registada. Testado ao vivo, ponta-a-ponta, e funciona: 1. `list-changes` (opcional filtrar por `domain`: elementor/filesystem/database, `rolled_back`, `reversible`) — mais recente primeiro, cada entrada tem `id`, `summary`, `reversible`, `rolled_back`. 2. `get-change({ id })` para detalhe completo incluindo a referência de rollback (before-image / ponteiro de backup / `after_hash`). 3. `rollback-change({ id })` — reverte essa mudança. Confirmado ao vivo: reverteu uma página exactamente para a árvore de elementos anterior, removendo precisamente o que aquela mudança tinha adicionado e nada das mudanças à volta. Recusa com erro de conflito se o alvo mudou de novo desde a mudança registada (passar `force:true` para sobrepor e aceitar perda de dados no estado mais recente). Nunca faz double-rollback da mesma entrada; regista uma entrada compensatória no ledger quando corre. **Quando qualquer escrita nesta sessão correr mal ou produzir um resultado inesperado (ver a armadilha de sobrescrita do `apply-template` em `emcp-page-building`), recorrer a `list-changes` → `rollback-change` antes de tentar reconstruir manualmente o estado anterior.** É mais rápido e fiável do que reconstruir a partir do output de `get-page-structure`. ## Espelho de conteúdo (export/restore git-friendly — separado do ledger de mudanças) `export-content`/`list-content-exports`/`restore-content` — exporta conteúdo de página/template Elementor para ficheiros JSON sob `uploads/emcp-content-mirror/` para um VCS externo poder fazer diff/versionar designs, e restaura a partir de um ficheiro de espelho (um undo baseado em ficheiro, distinto do ledger acima). `list-content-exports` mostra o que está actualmente espelhado em disco. Útil antes de um lote grande de trabalho de construção de páginas como checkpoint extra além do ledger automático. ## Referência cruzada - `emcp-page-building` — construção de páginas Elementor, incluindo as tools com maior probabilidade de precisar de rollback (`apply-template`, `create-theme-template`). - `emcp-content-ops` — operações de conteúdo/media/menus/redirects WordPress. - `emcp-tools` (skill genérica) — inventário completo de ~162 abilities e o mecanismo de deny-list que decide quais das tools referidas acima estão realmente montadas numa dada ligação.