Regras de segurança no .htaccess do WordPress que realmente ajudam
A maior parte do que é vendido como segurança de .htaccess no WordPress é enchimento. As regras que de fato mudam sua superfície de ataque são curtas — veja aqui quais são quais
Publicado
A maior parte do que é vendido como “segurança de .htaccess no WordPress” é enchimento. As regras que de fato mudam sua superfície de ataque são curtas: bloquear a execução de PHP dentro de wp-content/uploads, negar o acesso direto ao wp-config.php e desativar a listagem de diretórios. As mais populares — bloquear o xmlrpc.php “para impedir força bruta”, esconder a versão do WordPress, colar uma lista de 200 linhas de user-agents de bots ruins — variam de marginais a puro teatro. Abaixo estão quais são quais, e por quê.
Uma coisa para deixar clara primeiro: o .htaccess só faz alguma coisa no Apache (e no LiteSpeed, que também o lê). No nginx ele é totalmente ignorado — o arquivo fica lá parado enquanto você acredita estar protegido. Se sua hospedagem roda nginx, nada disso se aplica e você precisa de blocos server/location no lugar. Verifique com curl -I https://seusite.com e olhe o cabeçalho Server: antes de gastar uma hora editando um arquivo que o servidor nunca lê.
A regra que realmente importa: nada de PHP em /uploads
Essa é a que vale a pena fazer. O wp-content/uploads tem permissão de escrita para todos por design — cada upload de mídia, cada plugin que salva um arquivo, escreve ali. Se um atacante conseguir colocar um arquivo .php nesse diretório (por meio de um manipulador de upload vulnerável, um campo de imagem que não valida o tipo MIME, um plugin comprometido), a diferença entre um aborrecimento e um comprometimento total com execução remota de código é se o servidor vai executar aquele arquivo quando ele for requisitado. Negue a execução e o payload enviado fica sendo apenas um arquivo inerte parado no disco.
Coloque isto no wp-content/uploads/.htaccess (crie o arquivo se ele não existir):
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
Essa é a sintaxe do Apache 2.4. Na versão mais antiga 2.2, o equivalente é Order Deny,Allow / Deny from all. Misturar os dois dialetos em um mesmo arquivo é a causa mais comum de um súbito 500 Internal Server Error depois de “reforçar a segurança” — se o site inteiro cai no momento em que você salva, esse é quase sempre o motivo. Verifique sua versão com apachectl -v.
Proteja o wp-config.php
O wp-config.php guarda as credenciais do banco de dados e as chaves de autenticação. Enquanto o PHP está rodando, uma requisição direta a ele retorna uma página em branco — o PHP executa o arquivo em vez de imprimi-lo. O risco é o caso de falha: se o PHP travar, for mal configurado durante uma migração, ou o manipulador for desativado, o Apache serve o arquivo como texto puro e despeja a senha do seu banco para qualquer um que pedir. Negar o acesso é um seguro barato contra cinco minutos ruins:
<Files wp-config.php>
Require all denied
</Files>
Desative a listagem de diretórios
Se alguém visita uma pasta sem index.php e o Apache está com Options +Indexes ativado, ele lista o conteúdo — cada arquivo de backup, cada dump SQL perdido que você esqueceu. Desative isso no site inteiro:
Options -Indexes
Baixa severidade, mas real, e não custa nada.
Essa é a lista central e honesta. Você pode montar essas regras — mais a sintaxe correta de 2.4 vs 2.2 para não derrubar seu site com um 500 — com a ferramenta para editar o .htaccess do WordPress em vez de copiar e colar de um post de fórum escrito para a versão errada do Apache.
O que NÃO fazer
Bloquear o xmlrpc.php “para proteção contra força bruta”. Essa é a grande que todo mundo repete e está errada da forma como é dita. Sim, o método system.multicall do XML-RPC historicamente permitia que um atacante juntasse muitas tentativas de login em uma única requisição — amplificação real. Mas o vetor de força bruta esmagadoramente mais comum são requisições POST simples ao wp-login.php, e bloquear o xmlrpc.php não faz nada contra isso. Força bruta é vencida com limitação de taxa (rate limiting), senhas fortes e 2FA — não matando um endpoint. Existe um motivo legítimo para desativar o XML-RPC: seu recurso de pingback pode ser abusado para reflexão de DDoS, então se você não usa Jetpack, o app móvel ou pingbacks, fechá-lo reduz sua superfície de ataque. Só não se convença de que essa é sua defesa contra força bruta, porque não é.
Esconder a versão do WordPress / remover a meta tag do gerador. Retirar o readme.html e a tag <meta name="generator"> dá uma sensação de segurança. Um atacante identifica sua versão pelas query strings dos assets enfileirados, pela marcação do editor de blocos e por uma dúzia de outros indícios em segundos. Você não está escondendo nada; está só se sentindo ocupado.
Listas gigantes de bloqueio de user-agents e referrers de bots ruins. User agents são um único cabeçalho HTTP falsificável. Essas listas já estão desatualizadas no dia em que você as cola, não bloqueiam nada competente, e o Apache avalia cada regex em toda requisição — você está pagando um imposto real de desempenho por zero de segurança. Pule isso.
Travar o wp-login.php por IP. Ótimo até seu provedor rotacionar seu endereço e você se trancar para fora do seu próprio painel. Só é viável com um IP genuinamente estático.
Redirecionamentos contra enumeração de autores (?author=1). A regra de rewrite no .htaccess que as pessoas colam para isso é incompleta por si só — o endpoint REST /wp-json/wp/v2/users continua listando os nomes de usuário. Bloquear um caminho enquanto o outro permanece aberto é teatro.
Ainda travado?
Se uma regra derruba o site com 500, é sintaxe — remova o último bloco que você adicionou e recarregue; isso o isola na hora. Se uma regra parece não fazer nada, confirme que você está mesmo no Apache e que o AllowOverride está habilitado para o diretório (muitas hospedagens gerenciadas o restringem). Monte o arquivo a partir de um template comprovadamente correto com a ferramenta para editar o .htaccess, mantenha as três regras que importam e descarte o resto.