Nos dias atuais, infelizmente a segurança não tem sido encarada da forma que deveria por muitos desenvolvedores, e até mesmo pelas empresas de hospedagem.
É muito comum encontrarmos instalações sendo invadidas pelo descuido em questões básicas de segurança, como permissões de arquivos ou hashes não atualizados no wp-config.php.
Com base nisso, resolvi publicar aqui um simples tutorial separado por etapas com algumas boas dicas de segurança focadas em WordPress.
1. PHP
Basicamente, é de suma importância manter as seguintes diretivas no seu php.ini:
display_errors=Off allow_url_fopen=Off disable_functions=popen,exec,system,passthru,proc_open,shell_exec,highlight_file,escapeshellcmd,pcntl_exec
Essas diretivas irão desabilitar algumas funções que podem representar risco para seu servidor.
Mas e se meu tema ou um dos meus plugins usar alguma dessas funções? Considere removê-lo ou substituí-lo!
Por exemplo, é comum ver plugins usando a função exec() para manipular imagens. Manipulação de imagens é um processo que em geral consome muitos recursos do servidor, e certamente vai acarretar na perda de performance em seu site. Assim, além de todas as questões de segurança envolvidas, temos mais um motivo para não utilizar esses plugins.
2. Servidor web
A página Hardening WordPress no Codex recomenda a adição de algumas regras no servidor web para segurança do diretório wp-includes e do arquivo wp-config.php.
2.1. Nginx
Se o seu servidor web for o Apache, ignore essa etapa.
Como as regras estão no formato Apache, efetuei a conversão delas para o formato Nginx manualmente.
Assim, você deverá editar o arquivo de configuração do seu site, geralmente disponível em /etc/nginx/sites-available/, e adicionar as seguintes linhas:
# WordPress Hardening if ($request_uri ~ ^/wp-admin/includes/) { return 403; } if ($request_uri ~ ^/wp-includes/js/tinymce/langs/.+\.php$) { return 403; } if ($request_uri ~ ^/wp-includes/theme-compat/) { return 403; } if ($request_uri ~ ^/wp-config\.php$) { return 403; }
Além disso, a linha abaixo também deverá ser adicionada se você NÃO estiver rodando uma instalação multisite do WordPress:
if ($request_uri ~ ^/wp-includes/[^/]+\.php$) { return 403; }
Após adicionar as linhas, salve o arquivo, dê um reload no Nginx e voilá 🙂
2.2. Apache
Se o seu servidor web for o Nginx, ignore essa etapa.
Você deverá editar o arquivo .htaccess do seu site e adicionar as seguintes instruções:
# WordPress Hardening: wp-config.php <files wp-config.php> order allow,deny deny from all </files>
# Disables the access to htaccess file <files .htaccess> order allow,deny deny from all </files>
# WordPress Hardening: wp-includes <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^wp-admin/includes/ - [F,L] RewriteRule !^wp-includes/ - [S=3] RewriteRule ^wp-includes/[^/]+\.php$ - [F,L] RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L] RewriteRule ^wp-includes/theme-compat/ - [F,L] </IfModule>
Além disso, a linha abaixo também deverá ser adicionada dentro do bloco do wp-includes se você NÃO estiver rodando uma instalação multisite do WordPress:
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
Feito isso, salve o arquivo e voilà, o Apache deverá carregar suas regras automaticamente.
3. MySQL
Primeiramente, recomendaria adicionar a seguinte linha ao seu my.cnf:
bind-address=127.0.0.1
Feito isso, basta salvar o arquivo e reiniciar o MySQL. Com aquela linha, somente acessos vindouros do próprio servidor serão aceitos.
Em relação a base de dados, meu conselho seria criar um usuário dedicado por site rodando WordPress.
Para criar um novo usuário, basta executar os seguintes comandos SQL como root — substituindo database pelo nome da sua base de dados, user pelo nome de usuário e password pela senha desejada:
GRANT ALL PRIVILEGES ON database.* TO user@'localhost' IDENTIFIED BY 'password'; FLUSH PRIVILEGES;
Um bom site para gerar senhas é o Random Keygen.
Depois disso, vá até o seu wp-config.php e edite as credenciais de acordo com o novo usuário que criou.
4. Permissões dos arquivos e diretórios
É muito comum encontrarmos instalações WordPress com permissões atribuídas de maneira inadequada e potencialmente perigosas, principalmente se tratando de hospedagens compartilhadas (shared hosting).
O mais comum dos erros nessa etapa é a definição recursiva da permissão 777 para o diretório wp-content/uploads/. Fazendo uma pequena pesquisa é possível encontrar uma conhecida empresa de hospedagem aqui no Brasil recomendando o uso dessa permissão naquele diretório.
Para evitar dores de cabeça devido a permissões inapropriadas, basta executar três comandos no diretório onde seu site está instalado:
# find . -type d -exec chmod 755 {} \; # find . -type f -exec chmod 644 {} \; # chmod 400 wp-config.php
Assim, todos os diretórios terão permissão 755, e todos os arquivos 644, conforme recomendado pela página Hardening WordPress disponível no Codex. Além disso, adicionalmente seu wp-config.php terá permissões de somente leitura para o usuário root.
Na Synthesis, que oferece hospedagem especializada em WordPress, essas permissões já estão definidas por padrão na sua instalação!
Está usando uma hospedagem compartilhada e não tem acesso ao servidor para executar os comandos? Envie um e-mail para o suporte ténico da empresa solicitando para executarem estes comandos em sua instalação WordPress. Provavelmente eles não irão se opor, se tratando apenas de três simples comandos 🙂
Dica: se a empresa não for capaz de rodar aqueles comandos por você, confie em mim, mude de hospedagem o mais rápido possível.
5. Hashes do wp-config.php
Possivelmente, navegando pelo wp-config.php, você já se deparou com as seguintes constantes:
define('AUTH_KEY', 'put your unique phrase here'); define('SECURE_AUTH_KEY', 'put your unique phrase here'); define('LOGGED_IN_KEY', 'put your unique phrase here'); define('NONCE_KEY', 'put your unique phrase here'); define('AUTH_SALT', 'put your unique phrase here'); define('SECURE_AUTH_SALT', 'put your unique phrase here'); define('LOGGED_IN_SALT', 'put your unique phrase here'); define('NONCE_SALT', 'put your unique phrase here');
Daria para escrever um belo texto explicando essas constantes e como o WordPress lida com elas, mas vou simplificar para não fugirmos do foco do texto.
As constantes AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY e NONCE_KEY são responsáveis por garantir a criptografia dos cookies do usuário gerados pelo WordPress. O sistema de autenticação do WordPress é baseado nesses cookies.
Quer tirar a prova real? Autentique-se no Dashboard, edite o valor da constante AUTH_KEY no seu wp-config.php e dê um refresh na página recém-autenticada do Dashboard. Você será direcionado(a) para página de log in do WordPress.
Repare que para cada KEY há um SALT correspondente. As KEYs adicionam elementos aleatórios para a senha. Já os SALTs são usados para melhorar ainda mais o resultado gerado pelas KEYs.
Deixando a teoria de lado, para nos auxiliar o time do WordPress disponibilizou uma pequena função em sua API para gerar os valores das constantes automaticamente: https://api.wordpress.org/secret-key/1.1/salt/
Assim, basta acessar a página acima, copiar o conteúdo dela e substituir as atuais constantes KEYs e SALTs em seu wp-config.php com as geradas pela API.
6. Atualizações do WordPress
É sempre importante manter seu WordPress atualizado.
As versões pontuais em geral trazem correções de bugs e pequenas modificações. Assim, é sempre uma boa prática configurar o WordPress para recebê-las automaticamente.
Como exemplo, cito a versão 3.8.1 do WordPress, que trouxe a correção de 31 bugs existentes na versão 3.8.
Para ativar as atualizações automáticas das versões pontuais, adicione a seguinte linha ao seu wp-config.php:
define('WP_AUTO_UPDATE_CORE', 'minor');
Depois disso basta salvar o arquivo e fechá-lo 🙂
7. WordPress, plugins e temas
Por padrão, o WordPress permite editar arquivos PHP via Dashboard. Isso pode trazer grandes problemas se alguém que não deveria, de alguma forma, obtiver acesso ao Dashboard.
Assim, recomendo que desabilite o editor padrão do WordPress e edite seus arquivos somente via SFTP ou SSH. Para desabilitá-lo, basta adicionar a seguinte linha ao wp-config.php:
define('DISALLOW_FILE_EDIT', true);
Outro ponto importante: manter seus temas e plugins atualizados. As atualizações trazem correções de segurança e de demais bugs, bem como novas funcionalidades para o tema ou plugin.
Também é importante ter certeza que o plugin ou tema continua sendo suportado pelo(s) desenvolvedor(es), bem como verificar se ele é compatível com sua atual versão do WordPress.
Além disso, temas e plugins que não estão sendo usados devem ser removidos do seu WordPress, pois podem representar problemas de segurança, tendo em vista que continuam acessíveis mesmo quando desativados no Dashboard.
8. Proteção contra ataques DDoS ao xmlrpc.php
Atualmente existe uma onda de ataques DDoS destinados ao arquivo xmlrpc.php das instalações WordPress. E é muito comum ver este tipo de ataque comprometer a performance do site e, muitas vezes, até tirá-lo do ar.
Para resolver o problema, a Sucuri.net – empresa especializada em segurança WordPress – recomenda que o protocolo XMLRPC (pingback) seja desativado.
Com base no código recomendado pela Sucuri, escrevi um pequeno plugin que pode ser adicionado ao WordPress. Basta criar um arquivo chamado disable-xmlrpc.php em seu diretório de plugins (normalmente wp-content/plugins/) com o seguinte conteúdo:
<?php /** * Plugin Name: Disable XMLRPC * Description: This plugin disables the XMLRPC protocol to avoid DDoS attacks. * Version: 0.1 by Sucuri Security */
add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['pingback.ping'] ); return $methods; } );
Depois disso, salve e feche o arquivo, vá até o Dashboard e habilite o plugin 🙂
ATUALIZAÇÃO: seguindo a dica do Diego, o bloqueio sugerido pela Sucuri.net é efetuado por meio de código PHP. Ou seja, vai funcionar porém exigirá vários recursos do servidor para, por exemplo, bloquear um ataque DDoS. Assim, se torna mais eficiente colocar este bloqueio diretamente no servidor web.
Com base nisso, apresento abaixo uma solução mais eficiente, bloqueando as requisições ao XMLRPC diretamente no servidor web.
Nginx
Adicionar a seguinte linha no arquivo de configuração do seu site:
if ($request_uri ~ ^/xmlrpc\.php$) { return 403; }
Após adicionar, será necessário reiniciar o Nginx.
Apache
Basta adicionar a seguinte regra ao seu .htaccess e voilà:
# Disables the access to XMLRPC file <files xmlrpc.php> order allow,deny deny from all </files>
9. Outras medidas de segurança
Além das dicas anteriores, seguem algumas outras medidas de segurança que poderiam ser adotadas:
- Instalar um plugin de segurança para evitar ataques de força bruta e/ou DDoS
- Manter os softwares do servidor atualizados
- Atualizar as senhas dos usuários esporadicamente
- Configurar um firewall
- Habilitar autenticação HTTP básica para acessar o wp-admin
……
O que achou das dicas? Esse tutorial lhe ajudou de alguma forma? Se sim, tudo que peço é que ajude a divulgá-lo. E não esqueça de compartilhar suas experiências e dicas nos comentários, para incrementar ainda mais a troca de conhecimento por aqui 🙂
Quer saber o que é e como funciona o WordPress Cron? Leia aqui!
Mauricio Leonardo says
Montei um wordpress em nuvem no servidor tilaa (muito bom por sinal) só que com lighttp(centOS), muito rápido, mas tive um problema com o meu cartão de crédito e os caras apagaram tudo).
Suas dicas são ótimas, vou colocar em prática…
muito obrigado.
mackilll
Tiago Hillebrandt says
Olá Maurício,
Não tive muito contato com o lighttpd, mas pretendo estudar sobre ele nos próximos meses. Se por acaso tiver aquelas regras em um formato compatível com o lighttpd, ficarei feliz em adicioná-las ao post 🙂
Valeu por compartilhar a experiência.
Espero que as dicas lhe sejam úteis!
Abraços
Marco Damaceno says
Tiago, parabéns! Finalmente encontrei dicas de segurança que realmente valem a pena serem implementadas em WordPress. O que já vi em outros sites sempre me deixaram em dúvida, mas nessas aqui você explicou direitinho o que cada coisa faz. Muito bom!
Vou implementar o mais rápido possível.
Tiago Hillebrandt says
Olá Marco,
Obrigado pelos elogios! Como se trata de um assunto delicado, que envolve a mudança de configurações no servidor, preferi explicar cada item para embasar as recomendações 🙂
Espero que as dicas lhe ajudem!
Abraços
Diego says
Ótimas dicas, simples e objetivo.
Apenas uma sugestão: acredito que o ‘block’ na página de pingback teria uma melhor performance se ocorresse direto no webserver (nginx, apache, etc). A utilização do plugin ou qualquer outro código ainda vai levar o sistema a executar php e fazer todas as verificações basicas do sistema.
No nginx seria algo desse tipo: location ~ ^/xmlrpc.php { deny all; }
Tiago Hillebrandt says
Olá Diego,
Agradeço pelos elogios!
Escrevi algumas observações no item 8 para efetuar o bloqueio diretamente no servidor com base na sua sugestão. Muito obrigado!
Abraços
leonardo says
Tiago meus parabéns e muito obrigado
Sou novo em wordpress e aqui encontrei informações de suma importância e de fácil compreensão.
Agora uma dúvida, tenho lido vários assuntos sobre segurança e como você deve imaginar a cabeça ta quase dando pane, então eis a pergunta:
Após estas configurações que você mencionou seria necessário forçar a área de login e o admin para trabalhar em HTTPS ??? Se sim teria como dar uma ajuda pois com tantos códigos por ai fico com receio de fazer algo errado
Tiago Hillebrandt says
Olá Leonardo,
Sim, o uso de HTTPS é sempre uma boa pedida. E não só na área de login, mas no site como um todo. Ainda mais agora que o Google sinalizou que isso resultará em melhores posições: http://googlewebmastercentral.blogspot.com.br/2014/08/https-as-ranking-signal.html
No entanto, vale ressaltar que o HTTPS por si só costuma afetar a performance do site negativamente. Uma boa sugestão seria habilitar o uso de HTTPS sobre SPDY, que não impacta tanto na performance.
Para habilitar o uso de HTTPS no WordPress, você precisa alterar a URL adicionando o https nas Configurações. Além disso, recomendo habilitar um “rewrite” no servidor web forçando que todo acesso HTTP seja redirecionado para o HTTPS. Já em relação ao SPDY, você pode entrar em contato com sua hospedagem solicitando que habilitem o módulo.
Qualquer dúvida estou a disposição 🙂
Abraços!
Thiago Fuda says
Show de bola Tiago. Tenho um site de conteúdo Nerd (http://vidanerd.com.br). Ontem a noite tive uma tentativa de invasão que acabou me dando um pouco de dor de cabeça. Eles tentaram usar as vulnerabilidade do PHP e brute force. Como medida de contenção acabei bloqueando o IP no iPtables, mais sei que é paliativo. Vou seguir as suas dicas. Vlw
Tiago Hillebrandt says
Olá Thiago,
Fico feliz em saber que as dicas ajudaram.
Caso os ataques DDoS/brute force continuem afetando seu site, tenho uma solução em bash script que detecta e bloqueia os IPs que estão ofendendo um servidor ou mais servidores automaticamente. Se tiver interesse, deixe-me saber e posso oferecer mais detalhes em privado 🙂
Abraços!
Marco Antonio Walter says
Olá Tiago,
Parabéns pelo artigo, e já estou implementando no meu site.
Tive o mesmo problema , como relatado pelo Thiago Fuda, e gostaria desta solução para o meu site (http://www.cpddigital.com.br), como posso obtê-la ??
Att
Marco A Walter
Sergio says
Parabéns pelas dicas muito bem explicadas, vou implementa-las.
Abs
Tiago Hillebrandt says
Olá Sergio,
Espero que a implementação tenha ocorrido tranquilamente!
Qualquer dúvidas estou a disposição 🙂
Abraços
iran says
Ótimas dicas. Procuro sempre uma forma a mais para torná-lo seguro.
Tiago Hillebrandt says
Olá Iran,
Sim, sempre importante ficar por dentro do que pode ajudar a melhorar a segurança do seu servidor e/ou site.
Espero que as dicas tenham lhe ajudado!
Abraços
Alan says
Muito bom Tiago. Valeu.
Tiago Hillebrandt says
Opa, espero que as dicas tenham lhe ajudado 🙂 Abraços
Ricardo Masala says
Tiago, muito obrigado pelas dicas, recentemente tive problemas com invasões, vou colocar as dicas em prática para tentar resolver esses problemas! Abraço e parabéns pelo trabalho!
Tiago Hillebrandt says
Olá Ricardo, fico feliz em ajudar! Qualquer dúvida estou a disposição. Abraços
Julio Saraiva says
Excelentes dicas Tiago, Estou começando meu blog agora e já vou aproveitar para implementar essas dicas de segurança no meu wordpress.
Valeu! 😉
Tiago Hillebrandt says
Valeu Julio, fico feliz em saber que as dicas lhe ajudaram. Um abraço! 🙂
Marcos says
Olá, Thiago! Boas dicas. Está melhor explicado. Parabéns!!!
Mas como eu não sou muito experiencia no assunto fiquei com uma dúvida, os códigos acima devem ser escritos no arquivo .htaccess antes de # BEGIN WordPress para não ser subscrito??? Isso é verdade?!
carlos alberto says
Olá! Thiago, adorei seu blog.. muito bom!
Me tire uma dúvida por favor::
Tenho um site rodando em Nginx… existe algum
plugin que funcione com Nginx para alterar URL
do wp-admin? pois funcionando no Apache tem
vários plugin já testados.
Desde já, muito obrigado.
Forte abraço!
Carlos Alberto
Luis Alves says
Cara, você é demais! Estou sofrendo ataques severos no meu site! Li todo o seu artigo e me ajudou muito. Porém fiquei com algumas dúvidas; 1 – Desabilitar o XMLRPC (pingback) não vou ter problemas com o ranqueamento do site?
2 – Você acertou em cheio no diretório wp-content/uploads/.777 é a hostgator, eu posso acusar, pois estava em risco. Porém, lá dentro da uploads tem uma pasta de arquivos do site com permissão 777. Mais um index.php com permissão 1204. Parece ser idiota, mais devo restringir também? Obrigado.
Abração.
Vagner do Carmo says
Meu wordpress trava (tela branca) depois que altero a permissão do arquivo wp-config para 400, tive que voltar para 644. :/
Vagner do Carmo says
Desabilitar o xmlrpc também bloqueou o acesso ao site pelos aplicativos wordpress (WordPress Sites e WordPress Mobile)
Thiago Antonio says
Estou remontando meu blog e levei em consideração a maioria das suas recomendações. Como não tenho mto acesso a nível de servidor, a maioria das outras recomendações eu apliquei. Valeu mesmo. Parabéns! Abraço.
Anderson Benites says
Olá…gostei muito desse seu artigo. Muito bem explicado. Passarei a seguir seu blog. Coloquei em prática algumas das dicas que você recomenda. Por enquanto está tudo rodando bem. Parabéns pelo trabalho!! Abs.
Felipe says
Belas dicas, Muito bom!
Rodrigo says
Olá Tiago, com relação ao item 8 que seria o bloqueio xml-rpc.php tento inserir no site o codigo e fica retornando erro 500, saberia me dizer o porque?
Samuel says
Dicas preciosas!
Tiago, essas dicas se aplica a versão mais atualizada do WP, no caso a 4.4.2?
Henrique Félix says
Tiago meus parabéns pelo post. Ótimo. é uma pena que o amigo não esteja mais escrevendo sobre WP. Ficaria feliz em receber mais informações sobre WP e Segurança. Forte abraço!
Saulo says
Ótima dicas, muito obrigado Tiago. Já apliquei algumas aqui para o melhor funcionamento do sistema.
Show, nota 10!
Pablo says
Salvou minha vida!