A “famosa instalação de 5 minutos” é um slogan de marketing, não um padrão profissional. Uma instalação predefinida do WordPress é “faladora”, pouco otimizada e muitas vezes insegura.
Como programadores, não nos limitamos a “instalar” o WordPress. Preparamo-lo para funcionar num ambiente concreto. Este guia cobre as constantes de configuração essenciais e as técnicas de reforço de segurança que devem fazer parte da base de qualquer projeto de cliente em 2026.
Configurar o wp-config.php após instalar o WordPress
Este é o cérebro da sua instalação. Deixe de o manter nas definições predefinidas.
Definir o WP_ENVIRONMENT_TYPE no wp-config.php
Desde o WordPress 5.5, WP_ENVIRONMENT_TYPE é o padrão. Use-o para impedir que erros de desenvolvimento cheguem à produção.
// No wp-config.php
define( 'WP_ENVIRONMENT_TYPE', 'production' ); // 'local', 'development', 'staging', 'production'Depois, no seu código:
if ( wp_get_environment_type() === 'production' ) {
// Ativar cache, desativar erros
}Desativar o editor de ficheiros e forçar SSL no wp-config.php
Impeça que clientes (ou atacantes) estraguem o site através do painel de administração.
// Desativar o editor de ficheiros (editor de temas/plugins)
define( 'DISALLOW_FILE_EDIT', true );
// Bloquear a instalação/atualização de plugins (bom para implementações imutáveis)
define( 'DISALLOW_FILE_MODS', true );
// Forçar SSL na administração
define( 'FORCE_SSL_ADMIN', true );Como limitar as revisões de artigos no WordPress
O assassino da base de dados. Precisa mesmo de 100 versões da página “Sobre nós”?
define( 'WP_POST_REVISIONS', 10 ); // Manter as últimas 10
// OU
define( 'WP_POST_REVISIONS', false ); // Desativar por completo (não recomendado)Como ativar o WP_DEBUG_LOG sem mostrar erros
Nunca mostre erros no frontend. Registe-os.
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/tmp/wp-errors.log' ); // Mova o registo para fora da pasta pública!
define( 'WP_DEBUG_DISPLAY', false );
// Registar consultas SQL para depurar o desempenho (desative em produção!)
define( 'SAVEQUERIES', false );Como desativar os emoji e o XML-RPC no WordPress
O WordPress vem com funções de que 90% dos sites empresariais não precisam: emoji, oEmbeds e XML-RPC.
Não instale um plugin para os desligar. Crie um plugin must-use (wp-content/mu-plugins/lean-core.php).
<?php
/* Plugin Name: Lean Core */
// 1. Desativar os emoji (poupa um pedido HTTP)
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
// 2. Desativar o XML-RPC (segurança)
add_filter( 'xmlrpc_enabled', '__return_false' );
// 3. Remover a versão do WP (security by obscurity)
remove_action( 'wp_head', 'wp_generator' );
// 4. Desativar os feeds RSS (se estiver a criar um site institucional)
// function wppoland_disable_feed() {
// wp_die( 'Não há feed, visite a nossa página inicial!' );
// }
// add_action('do_feed', 'wppoland_disable_feed', 1);Apesar do nome, o filtro xmlrpc_enabled do ponto 2 só desativa os métodos XML-RPC que exigem autenticação, como a publicação. Os pingbacks e outros métodos sem autenticação continuam a responder em xmlrpc.php. Bloquear o ficheiro inteiro cabe ao servidor web, e só se nada o usar: o Jetpack, por exemplo, liga-se por XML-RPC.
Alterar as chaves salt no wp-config.php
Conhece as chaves de autenticação no wp-config.php.
define('AUTH_KEY', 'escreva aqui a sua frase única');
// ...Facto: alterá-las termina de imediato a sessão de todos os utilizadores. É a “opção nuclear” se o site for comprometido. Dica profissional: automatize a rotação com um script CLI ou com o Vault se gere sites enterprise.
O que definir no wp-config.php antes de pôr o site no ar
Antes do lançamento:
- Defina
WP_ENVIRONMENT_TYPEcomo production. - Defina
DISALLOW_FILE_EDITcomo true. - Limite
WP_POST_REVISIONS. - Mova
WP_DEBUG_LOGpara uma pasta privada. - Desative os emoji/XML-RPC por código.
Uma instância de WordPress bem configurada é silenciosa, segura e rápida.
Que ligações permanentes definir no WordPress
A estrutura de ligações permanentes ideal
Definições > Ligações permanentes > Nome do artigoPorquê:
- URLs mais curtos e legíveis
- Melhor para SEO (palavras-chave no URL)
- Mais fáceis de memorizar e partilhar
Uma instalação nova traz muitas vezes ligações permanentes legíveis. Quando o servidor suporta a reescrita de URL, o instalador define /%year%/%monthnum%/%day%/%postname%/ (a função do núcleo wp_install_maybe_enable_pretty_permalinks()). Mude para Nome do artigo antes de publicar o primeiro artigo: alterar a estrutura num site em funcionamento muda o URL de todos os artigos, e os endereços antigos passam a precisar de redirecionamentos.
Estrutura de categorias e etiquetas
- Crie as categorias base (3-7 principais)
- Defina a hierarquia (categorias superiores e subcategorias)
- Defina uma categoria predefinida (não “Sem categoria”)
- Planeie uma estratégia de etiquetas (opcional, 5-10 etiquetas por artigo)
Definições de multimédia e tamanhos de imagem no WordPress
Tamanhos de imagem
Definições > MultimédiaDefinições recomendadas:
- Miniatura: 150x150px (marque “Recortar a miniatura para as dimensões exatas”)
- Média: 300x300px
- Grande: 1024x1024px
- Tamanho completo: sempre disponível
Otimização automática de imagens
<?php
/* Plugin Name: Image Sizes */
add_action( 'init', function () {
remove_image_size( '1536x1536' ); // WordPress 5.3+
remove_image_size( '2048x2048' ); // WordPress 5.3+
} );Duas linhas habituais em cópias deste excerto ficam de fora de propósito. wp_lazy_loading_enabled já devolve true por predefinição (loading="lazy" nativo desde o WordPress 5.5), e o filtro wp_image_editors só define a ordem em que o WordPress experimenta o Imagick e o GD, que já é a ordem predefinida. Nenhum dos dois otimiza nada no carregamento. As imagens com mais de 2560 px de largura ou altura já são reduzidas no carregamento através do filtro big_image_size_threshold.
Como ativar o carregamento em WebP no WordPress
add_filter( 'image_editor_output_format', function ( $formats ) {
$formats['image/jpeg'] = 'image/webp';
$formats['image/png'] = 'image/webp';
return $formats;
} );O excerto não usa wp_upload_image_mime_transforms, um filtro que não existe no núcleo atual do WordPress. image_editor_output_format existe desde o WordPress 5.8 e associa um tipo de origem ao tipo em que o WordPress guarda os tamanhos gerados; desde a 6.7 a predefinição já converte HEIC e HEIF em JPEG, e o excerto mantém essas entradas. O Imagick ou o GD do servidor têm de suportar WebP. Ferramentas > Saúde do site > Informação > Gestão de multimédia mostra o que é suportado.
Como proteger o WordPress após a instalação
Alterar o prefixo predefinido das tabelas
Durante a instalação: Introduza um prefixo personalizado em vez de wp_ (por exemplo x7k9_, mysite_, proj23_)
Após a instalação (avançado):
// wp-config.php
$table_prefix = 'x7k9_';RENAME TABLE wp_posts TO x7k9_posts;
RENAME TABLE wp_options TO x7k9_options;
-- ... repetir para todas as tabelas
UPDATE x7k9_options SET option_name = 'x7k9_user_roles' WHERE option_name = 'wp_user_roles';
UPDATE x7k9_usermeta SET meta_key = CONCAT('x7k9_', SUBSTRING(meta_key, 4)) WHERE meta_key LIKE 'wp\_%';O WordPress não tem uma constante DB_PREFIX: o prefixo está na variável $table_prefix. Renomear só as tabelas deixa os administradores sem acesso, porque as funções e permissões ficam guardadas em chaves com prefixo em options (wp_user_roles) e usermeta (wp_capabilities, wp_user_level). É isso que as duas instruções UPDATE corrigem. O guia Hardening WordPress trata um prefixo próprio como ofuscação: pode travar alguns ataques automatizados de injeção de SQL que assumem wp_, e não substitui a correção do código vulnerável.
Proteger o ficheiro wp-config.php
# .htaccess (raiz, no topo do ficheiro)
<Files "wp-config.php">
Require all denied
</Files>Order allow,deny é sintaxe do Apache 2.2 e no Apache 2.4 só funciona através do módulo de compatibilidade. O guia Hardening WordPress indica a forma Require all denied acima e coloca-a no topo do .htaccess da raiz. O Nginx ignora os ficheiros .htaccess, por isso no Nginx a mesma regra vai para o bloco server.
Bloquear o acesso a pastas
# wp-content/uploads/.htaccess
Options -Indexes
# .htaccess (raiz, fora de # BEGIN WordPress e # END WordPress)
<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>O WordPress reescreve tudo o que está entre os marcadores # BEGIN WordPress e # END WordPress sempre que as ligações permanentes são guardadas, por isso este bloco fica fora deles, no .htaccess da raiz e não em wp-includes/: os caminhos das regras são relativos à raiz do site. Em multisite, a linha ^wp-includes/[^/]+\.php$ impede o ms-files.php de servir imagens, e o guia Hardening WordPress manda retirar essa linha, à custa de alguma proteção.
Limitar as tentativas de início de sessão
<?php
/* Plugin Name: Login Security */
function wppoland_login_key() {
return 'login_attempts_' . md5( $_SERVER['REMOTE_ADDR'] );
}
add_filter( 'authenticate', function ( $user ) {
if ( (int) get_transient( wppoland_login_key() ) >= 5 ) {
return new WP_Error( 'too_many_attempts', 'Demasiadas tentativas de início de sessão. Tente novamente dentro de uma hora.' );
}
return $user;
}, 30 );
add_action( 'wp_login_failed', function () {
$key = wppoland_login_key();
set_transient( $key, (int) get_transient( $key ) + 1, HOUR_IN_SECONDS );
} );
remove_action( 'wp_head', 'wp_generator' );
add_filter( 'the_generator', '__return_empty_string' );Contar as falhas em wp_login_failed e chamar wp_die() aí não funciona. Esse hook corre depois da verificação da palavra-passe, por isso uma palavra-passe correta continuava a entrar depois de cinco falhas. O filtro authenticate com prioridade 30 corre depois de o núcleo verificar o utilizador e a palavra-passe, e um WP_Error devolvido aí trava o início de sessão. Atrás de uma CDN ou de um proxy inverso, REMOTE_ADDR contém o endereço do proxy e todos os visitantes partilhariam um único contador: nesses casos, limite os inícios de sessão no proxy ou com fail2ban no servidor.
Autenticação de dois fatores (2FA)
O núcleo do WordPress não tem segundo fator. O plugin Two Factor, publicado no WordPress.org pela conta WordPress.org, acrescenta aplicações de autenticação (TOTP), códigos por email e códigos de recurso, e cada utilizador ativa-o no próprio perfil. O guia Hardening WordPress recomenda a autenticação em dois passos como camada adicional à palavra-passe. O excerto abaixo faz algo mais modesto: rejeita palavras-passe com menos de 12 caracteres quando um perfil é guardado.
// Exigir palavras-passe fortes
add_action('user_profile_update_errors', function($errors) {
$password = $_POST['pass1'];
if (!empty($password) && strlen($password) < 12) {
$errors->add('password_error', 'A palavra-passe tem de ter pelo menos 12 caracteres.');
}
});Como acelerar o WordPress após a instalação
Otimização básica da base de dados
// No wp-config.php
// Limitar as revisões de artigos
define('WP_POST_REVISIONS', 10);
// Esvaziar o lixo automaticamente após 7 dias
define('EMPTY_TRASH_DAYS', 7);
// Desativar o editor de ficheiros (segurança + desempenho)
define('DISALLOW_FILE_EDIT', true);Limpeza da base de dados
wp transient delete --expired
wp post list --post_type=revision --format=count
wp db optimizeO mu-plugin removido apagava transients comparando option_value com a hora atual, mas a expiração fica em linhas _transient_timeout_ à parte, por isso apagava as linhas erradas. O núcleo já faz este trabalho: wp-admin/admin.php agenda um evento diário delete_expired_transients (ignorado quando uma cache de objetos persistente guarda os transients), e um evento diário wp_scheduled_auto_draft_delete remove os rascunhos automáticos com mais de sete dias. Com WP_POST_REVISIONS definido, as revisões também não precisam de um cron de limpeza. Execute à mão os comandos WP-CLI acima quando uma base de dados parecer inchada.
Otimização da Heartbeat API
add_filter( 'heartbeat_settings', function ( $settings ) {
$settings['interval'] = 120; // predefinição: 60
return $settings;
} );
add_action( 'init', function () {
if ( ! is_admin() ) {
wp_deregister_script( 'heartbeat' );
}
}, 1 );O intervalo predefinido do Heartbeat é de 60 segundos (mainInterval em heartbeat.js), não 15, por isso o valor anterior de 60 não mudava nada. O Heartbeat também abranda sozinho para 120 segundos quando o separador do navegador está oculto. No editor transporta os bloqueios de artigos, por isso um intervalo mais longo atrasa o aviso de que outra pessoa está a editar o mesmo artigo.
Remover as ligações RSD, shortlink e REST API do wp_head
// Num mu-plugin: wp-content/mu-plugins/disable-bloat.php
<?php
/* Plugin Name: Disable Bloat */
// Desativar os emoji
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('wp_print_styles', 'print_emoji_styles');
// Desativar o XML-RPC
add_filter('xmlrpc_enabled', '__return_false');
// Desativar a ligação RSD
remove_action('wp_head', 'rsd_link');
// Desativar a ligação do Windows Live Writer
remove_action('wp_head', 'wlwmanifest_link');
// Desativar a ligação curta
remove_action('wp_head', 'wp_shortlink_wp_head');
// Desativar a ligação da REST API (se não a utilizar)
remove_action('wp_head', 'rest_output_link_wp_head');Definições básicas de SEO no WordPress
Título do site, descrição e visibilidade nos motores de pesquisa
Definições > Geral:
- Título do site: [A sua marca]
- Descrição: uma frase curta, ou vazia
Definições > Leitura:
- Visibilidade nos motores de pesquisa: deixe DESMARCADO "Pedir aos motores de pesquisa para não indexar este site"O núcleo não imprime nenhuma meta description, por isso a descrição do site não o é. Nas instalações atuais o campo começa vazio, e os temas podem mostrá-lo no cabeçalho ou no título. A meta description vem de um plugin de SEO ou do tema. A caixa de visibilidade nos motores de pesquisa está em Leitura, não em Geral, e enquanto estiver marcada o WordPress também desativa o seu próprio mapa do site.
Estrutura de ligações permanentes amiga do SEO
Definições > Ligações permanentes > Nome do artigoMapa do site (XML Sitemap)
add_filter( 'wp_sitemaps_post_types', function ( $post_types ) {
unset( $post_types['portfolio'] ); // retirar um tipo de conteúdo do mapa do site
return $post_types;
} );O mapa do site do núcleo em /wp-sitemap.xml está ativo por predefinição desde o WordPress 5.5, desde que o site esteja visível para os motores de pesquisa. Inclui todos os tipos de conteúdo públicos, também os personalizados, por isso a antiga linha $post_types[] = 'portfolio' era desnecessária e, além disso, errada: o array contém objetos WP_Post_Type indexados pelo nome. O filtro serve para o contrário, para retirar um tipo do mapa do site.
Otimização básica de imagens para SEO
Um excerto habitual preenche os atributos ALT vazios com o título do anexo e gera títulos a partir do nome do ficheiro. O segundo passo já é comportamento do núcleo: media_handle_upload() vai buscar o título do anexo ao nome do ficheiro. O primeiro produz textos ALT como “IMG_2041”, que o leitor de ecrã anuncia e que nada dizem sobre a imagem. Escreva o texto ALT de cada imagem na biblioteca multimédia e deixe-o vazio nas imagens puramente decorativas.
Como fazer cópias de segurança do WordPress
Cópias automáticas da base de dados
# crontab -e (utilizador do site, não root)
15 3 * * * cd /var/www/example/public && wp db export /home/example/backups/db-$(date +\%F).sql --quiet && find /home/example/backups -name 'db-*.sql' -mtime +7 -deleteO mu-plugin anterior gravava as cópias em wp-content/uploads/backups, uma pasta pública de onde qualquer pessoa que adivinhe o nome baseado na data pode descarregar a base de dados. Também passava a palavra-passe da base de dados na linha de comandos do mysqldump, onde outros utilizadores do servidor a veem na lista de processos, e dependia do WP-Cron, que só corre quando alguém visita o site. Uma tarefa cron do sistema com wp db export grava fora da raiz web e corre à hora certa.
Configurar cópias externas
Soluções recomendadas:
- UpdraftPlus: a versão gratuita chega para sites pequenos
- BlogVault: pago, mas muito fiável
- WPvivid: uma boa alternativa gratuita
Configuração:
- Cópia diária (base de dados)
- Cópia semanal (completa)
- Retenção: no mínimo 30 dias
- Localização externa: Google Drive, Dropbox, S3
Configurar o SMTP no WordPress
SMTP em vez de mail()
// No wp-config.php ou num mu-plugin
define('SMTP_USER', '[email protected]');
define('SMTP_PASS', 'your-password');
define('SMTP_HOST', 'smtp.gmail.com');
define('SMTP_PORT', '587');
define('SMTP_SECURE', 'tls');
define('SMTP_FROM', '[email protected]');
define('SMTP_NAME', 'O seu site');
// No mu-plugin
add_action('phpmailer_init', function($phpmailer) {
$phpmailer->isSMTP();
$phpmailer->Host = SMTP_HOST;
$phpmailer->SMTPAuth = true;
$phpmailer->Username = SMTP_USER;
$phpmailer->Password = SMTP_PASS;
$phpmailer->SMTPSecure = SMTP_SECURE;
$phpmailer->Port = SMTP_PORT;
$phpmailer->From = SMTP_FROM;
$phpmailer->FromName = SMTP_NAME;
});Como enviar um email de teste a partir do WordPress
add_action( 'admin_init', function () {
if ( isset( $_GET['test_email'] ) && current_user_can( 'manage_options' ) ) {
$sent = wp_mail( get_option( 'admin_email' ), 'Test email', 'Esta é uma mensagem de teste enviada a partir do WordPress.' );
wp_die( $sent ? 'OK' : 'wp_mail() returned false' );
}
} );admin_init também dispara nos pedidos a admin-ajax.php de visitantes sem sessão iniciada, por isso, sem a verificação de permissões, qualquer pessoa poderia pôr o site a enviar emails. Com WP-CLI o mesmo teste ocupa uma linha: wp eval 'var_dump( wp_mail( get_option( "admin_email" ), "Test", "Test" ) );'.
Monitorização do WordPress e registo de erros
Registo de erros
// No wp-config.php
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', '/var/log/wp-errors.log'); // Fora da pasta pública
define('WP_DEBUG_DISPLAY', false);
// Registo de consultas SQL (apenas em modo de depuração)
// define('SAVEQUERIES', true);Monitorização de uptime
Ferramentas recomendadas:
- UptimeRobot
- Pingdom (pago, mas mais avançado)
- Better Uptime (alternativa moderna)
Registar inícios de sessão e atualizações de artigos
// Num mu-plugin: wp-content/mu-plugins/activity-log.php
<?php
/* Plugin Name: Activity Log */
add_action('wp_login', function($user_login, $user) {
error_log('User logged in: ' . $user_login . ' from IP: ' . $_SERVER['REMOTE_ADDR']);
}, 10, 2);
add_action('save_post', function($post_id, $post, $update) {
if ($update && $post->post_status === 'publish') {
error_log('Post updated: ' . $post->post_title . ' by user: ' . get_current_user_id());
}
}, 10, 3);O que verificar antes de lançar um site WordPress
Lista de verificação antes de pôr o site no ar
- Todas as definições de SEO corretas
- Mapa do site gerado
- Google Search Console configurado
- Google Analytics instalado
- Política de privacidade e termos adicionados
- Formulários de contacto testados
- O email funciona
- O SSL funciona (HTTPS)
- Redirecionamentos entre www e sem www configurados
- Cópia de segurança feita
- Plugins de cache configurados (opcional)
- CDN configurada (opcional)
- Testes de desempenho feitos (PageSpeed Insights)
- Testes de responsividade em dispositivos móveis
- Testes em vários navegadores
- Página 404 configurada
- Favicon adicionado
Testar checksums e acesso a ficheiros com WP-CLI e curl
# Testes WP-CLI
wp core verify-checksums
wp plugin verify-checksums --all
wp db check
# Testes de segurança
curl -I https://o-seu-site.pt/wp-admin/install.php # devolve a página "Já instalado" exceto se o servidor a bloquear
curl -I https://o-seu-site.pt/wp-config.php # 403 com a regra <Files>; sem ela, uma página vaziaQue definições do WordPress alterar depois da instalação
Três ecrãs em Definições guardam predefinições que contam antes de chegar o primeiro visitante. A documentação do ecrã Geral descreve cada campo.
Geral. Escolha o fuso horário como uma cidade e não como um desvio UTC. Uma cidade segue a hora de verão, um desvio fixo não, e os artigos agendados são publicados com uma hora de diferença durante metade do ano. O idioma do site definido aqui é o idioma do painel. Um novo endereço de email de administração não entra em vigor de imediato: o WordPress envia uma ligação de confirmação para o novo endereço e mantém o antigo ativo até a ligação ser clicada, por isso use uma caixa de correio que alguém leia. Deixe a opção Adesão (“Qualquer pessoa se pode registar”) desligada, a menos que o site precise de registo aberto, e se precisar, mantenha Subscritor como função predefinida dos novos utilizadores.
Leitura. Este ecrã tem a caixa de visibilidade nos motores de pesquisa. As cópias de staging devem tê-la marcada e a produção não. A definição fica guardada na base de dados e viaja com cada cópia dela: verifique-a depois de cada passagem de staging para produção.
Discussão. Uma instalação nova tem os comentários e os pingbacks abertos por predefinição, a aprovação manual de comentários desligada e “O autor do comentário deve ter um comentário previamente aprovado” ligado. Num site empresarial sem comentários, feche-os aqui antes de publicar. A definição aplica-se aos artigos novos; os existentes mantêm o seu próprio estado.
Como ler a Saúde do site depois de instalar o WordPress
Ferramentas > Saúde do site executa uma série de verificações e ordena os resultados em problemas críticos e melhorias recomendadas (documentação do ecrã Site Health). Num site novo, as verificações úteis são as que as definições deste artigo tocam:
- Depuração ativada. Com
WP_DEBUG_LOGligado, a verificação passa a crítica quando o registo de erros do PHP está dentro da pasta do WordPress, porque o registo pode então ser descarregado. É por isso que o caminho do registo, mais acima neste artigo, aponta para fora da pasta pública. - Visibilidade nos motores de pesquisa. Assinalada enquanto “Pedir aos motores de pesquisa para não indexar” estiver marcado (verificação acrescentada no WordPress 6.9).
- Registo aberto com uma função predefinida privilegiada. Assinalado quando qualquer pessoa se pode registar com uma função acima de Subscritor (desde o WordPress 7.0).
- Atualizações em segundo plano, atualizações automáticas de plugins e temas, eventos agendados, pedido loopback. Se falharem, nem as atualizações automáticas nem as tarefas do WP-Cron correm.
- Estado do HTTPS, cache de objetos persistente, cache de página. Verificações do alojamento. As duas de cache são recomendações, não erros.
O separador Informação lista os dados do servidor (versão e extensões do PHP, versão da base de dados, suporte do editor de imagens, constantes como WP_DEBUG_LOG e WP_ENVIRONMENT_TYPE) e tem um botão que copia tudo para a área de transferência. Colar isso num pedido de suporte poupa uma ronda de perguntas com o alojamento.
Como funcionam as atualizações automáticas num site WordPress novo
Há três níveis, definidos em sítios diferentes (Configuring automatic background updates):
- Versões menores do núcleo (segurança e manutenção) instalam-se sozinhas desde o WordPress 3.7.
- Versões maiores do núcleo. Nos sites instalados com o WordPress 5.6 ou posterior, a opção
auto_update_core_majorcomeça ativada. Os sites atualizados a partir de uma versão anterior têm-na por definir. A constanteWP_AUTO_UPDATE_COREsobrepõe-se às duas:truepara todas as versões,'minor'só para as menores,falsepara desligar as atualizações do núcleo em segundo plano. - Plugins e temas. As atualizações automáticas estão desligadas por predefinição e ligam-se por plugin ou por tema nos ecrãs Plugins e Temas, uma funcionalidade do WordPress 5.5.
DISALLOW_FILE_MODS (ponto 5 da lista) faz mais do que esconder os botões de instalar e atualizar. O núcleo verifica wp_is_file_mod_allowed( 'automatic_updater' ) antes de qualquer atualização em segundo plano, por isso a constante também trava as versões de segurança automáticas. Não há problema quando cada atualização chega por um deploy. Sem esse processo, o site fica na versão com que foi implementado até alguém voltar a implementar.
Deve desativar as palavras-passe de aplicação no WordPress
As palavras-passe de aplicação, introduzidas no WordPress 5.6, permitem que uma ferramenta externa se autentique na REST API com o nome de utilizador e uma palavra-passe gerada em vez da palavra-passe da conta (documentação de Application Passwords). Cada utilizador cria-as e revoga-as no próprio perfil. Uma palavra-passe nova é mostrada uma única vez, guardada como hash e listada com a data e o IP da última utilização. O núcleo só disponibiliza a funcionalidade em sites com HTTPS ou quando WP_ENVIRONMENT_TYPE é local.
Mantenha-a ligada quando uma aplicação móvel, uma ferramenta de deploy ou uma integração falar com a REST API. Num site sem nada disso, um filtro desliga-a para todos os utilizadores:
add_filter( 'wp_is_application_passwords_available', '__return_false' );Perante a suspeita de uma intrusão, revogue as palavras-passe de aplicação além de trocar as chaves salt. As chaves novas terminam todas as sessões, mas as palavras-passe de aplicação são guardadas com um hash de chave fixa que não depende das salts, por isso continuam a funcionar até alguém as revogar.
Como configurar a página de política de privacidade no WordPress
O instalador cria uma página “Política de privacidade” como rascunho e atribui-a em Definições > Privacidade, um ecrã introduzido no WordPress 4.9.6 (documentação das definições de privacidade). O rascunho tem títulos sugeridos e texto de exemplo, não uma política acabada. O mesmo ecrã permite escolher outra página e liga ao guia da política de privacidade, onde o núcleo e os plugins que registam texto sugerido com wp_add_privacy_policy_content() descrevem o que guardam.
Daqui resultam duas coisas. O rascunho não é público até alguém o editar e publicar. E os temas imprimem a ligação para a política com the_privacy_policy_link(), que não mostra nada enquanto a página atribuída não estiver publicada, por isso uma ligação do rodapé que “falta” costuma indicar uma página por publicar. Ferramentas > Exportar dados pessoais e Ferramentas > Apagar dados pessoais tratam os pedidos de acesso e de apagamento dos dados que o WordPress e os plugins que colaboram com estas ferramentas guardam.
Resumo: a lista de verificação de 50 pontos
Segurança (1-15)
- ✅ Defina um prefixo de tabelas próprio (na instalação, com
$table_prefix) - ✅ Defina palavras-passe fortes (mín. 12 caracteres)
- ✅ Altere o nome de utilizador admin
- ✅ Desative o editor de ficheiros no painel
- ✅ Bloqueie a instalação de plugins (opcional; também trava as atualizações automáticas)
- ✅ Force SSL no painel de administração
- ✅ Proteja o wp-config.php através do .htaccess
- ✅ Bloqueie o acesso a pastas (no indexes)
- ✅ Restrinja o XML-RPC (o filtro só cobre métodos com autenticação; mantenha-o para o Jetpack)
- ✅ Oculte a versão do WordPress
- ✅ Limite as tentativas de início de sessão
- ✅ Configure a autenticação de dois fatores (plugin Two Factor)
- ✅ Faça a rotação regular das chaves de autenticação (salts)
- ✅ Instale um certificado SSL
- ✅ Configure proteções ao nível do servidor (firewall, limite de tentativas de início de sessão)
Desempenho (16-25)
- ✅ Limite as revisões de artigos (5-10)
- ✅ Desative os emoji
- ✅ Desative funções não utilizadas (XML-RPC, RSD)
- ✅ Otimize os tamanhos de imagem
- ✅ Confirme que o carregamento diferido está ativo (predefinição desde a 5.5)
- ✅ Configure a cache (de objetos, de página)
- ✅ Otimize a Heartbeat API
- ✅ Ative a compressão GZIP/Brotli
- ✅ Configure uma CDN (opcional)
- ✅ Otimize a base de dados (limpeza automática)
SEO (26-35)
- ✅ Defina a estrutura de ligações permanentes “Nome do artigo”
- ✅ Defina o título e a descrição do site (a descrição não é uma meta description)
- ✅ Verifique o mapa do site do núcleo em /wp-sitemap.xml
- ✅ Adicione o site ao Google Search Console
- ✅ Configure o Google Analytics / GA4
- ✅ Escreva o texto ALT de cada imagem
- ✅ Crie a estrutura de categorias
- ✅ Configure breadcrumbs
- ✅ Adicione o schema Organization
- ✅ Prepare as meta tags Open Graph
Cópias de segurança (36-42)
- ✅ Configure cópias automáticas da base de dados
- ✅ Configure cópias completas semanais
- ✅ Guarde as cópias numa localização externa
- ✅ Teste a reposição a partir de uma cópia
- ✅ Defina a retenção das cópias (mín. 30 dias)
- ✅ Documente o procedimento de reposição
- ✅ Verifique regularmente a integridade das cópias
Conteúdo e funcionalidades (43-50)
- ✅ Crie as páginas base (Sobre nós, Contacto, Política de privacidade)
- ✅ Configure os menus de navegação
- ✅ Teste todos os formulários
- ✅ Configure o SMTP para o email
- ✅ Crie uma página 404 personalizada
- ✅ Adicione o favicon e os ícones PWA
- ✅ Faça testes de desempenho
- ✅ Documente a configuração
Consulte a nossa auditoria de segurança WordPress se quiser pôr em ordem os riscos e as proteções do site.
Diferenças no wp-config.php entre staging e produção
Este guia define WP_DEBUG duas vezes com valores diferentes: true na secção sobre depuração e false na secção sobre monitorização. Ambas as versões estão corretas, cada uma para um ambiente diferente, por isso a mesma cópia do wp-config.php não deve ir sem alterações para o staging e para a produção. Antes de mover o ficheiro entre servidores, reveja estas constantes:
WP_ENVIRONMENT_TYPE:stagingna cópia de testes,productionno site em produção. Todas as condições baseadas emwp_get_environment_type()dependem deste valor.WP_DEBUG: ativado no staging, desativado na produção.WP_DEBUG_DISPLAYficafalsenos dois sítios, e o registo vai para fora da pasta pública.SAVEQUERIES: apenas enquanto procura consultas lentas, nunca em produção.DISALLOW_FILE_MODS: em produção bloqueia a instalação e a atualização de plugins a partir do painel, pelo que as atualizações passam pela implementação ou pelo WP-CLI. Combine isto com o cliente antes que ele repare que o botão de atualização desapareceu.- Chaves de autenticação: geradas aleatoriamente para cada instalação. Uma cópia da produção no staging recebe o seu próprio conjunto, e as chaves de produção não se tocam, porque alterá-las termina a sessão de todos os utilizadores.
Depois de mover o ficheiro, execute wp core verify-checksums e wp plugin verify-checksums --all da secção sobre testes antes do lançamento.






