Senhas fracas ainda são a porta de entrada mais comum para invasões. Em WordPress, políticas claras e aplicadas no servidor reduzem riscos, simplificam auditorias e elevam a conformidade. A seguir, você verá um guia objetivo com decisões, plugins úteis e snippets prontos para endurecer a autenticação sem perder usabilidade. Nesse artigo você verá:
- Pilares de uma política de senhas
- Boas práticas nativas do WordPress
- 2FA (TOTP/WebAuthn) e gerenciamento de sessões
- Plugins recomendados (prós e contras)
- Snippet: exigir comprimento e complexidade
- Snippet: bloquear senhas “pwned” (Have I Been Pwned)
- Snippet: forçar troca de senha e expiração
- WP‑CLI para governança e respostas rápidas
- Checklist de implantação segura
1) Pilares de uma política de senhas
Defina comprimento mínimo (12+), classes de caracteres (maiúscula, minúscula, número, símbolo), proibição de dados óbvios (nome, usuário, domínio), histórico de senhas (não permitir reutilização recente) e expiração baseada em risco. Combine isso com 2FA para reduzir a dependência da complexidade extrema.
2) Boas práticas nativas do WordPress
- Desative o uso do username no campo público (ex: use e‑mail oculto ou login personalizado).
- Restrinja criação/edição de usuários a perfis específicos; revise capabilities.
- Ative HTTPS e force-o no
wp-config.php(FORCE_SSL_ADMIN). - Rotacione as
AUTH_KEYeSALTperiodicamente. - Limite tentativas de login e bloquie IPs maliciosos (WAF/Firewall + reCAPTCHA/Turnstile no login).
3) 2FA e gerenciamento de sessões
Habilite 2FA via TOTP (Google/Microsoft Authenticator) ou WebAuthn (chaves de segurança). Exija 2FA ao menos para administradores e editores. Configure códigos de backup e política de desconexão forçada ao alterar senha ou elevar privilégios.
4) Plugins recomendados (prós e contras)
- iThemes Security / All‑In‑One Security (AIOS): regras de senha, 2FA, bloqueio de força bruta, logs.
- Wordfence: WAF + rate limit; combine com políticas de senha via snippet ou add‑on.
- WP Password Policy Manager: políticas granulares (comprimento, histórico, expiração).
- miniOrange / Two‑Factor: 2FA com TOTP/WebAuthn e força por função.
Dica: Evite sobreposição de recursos (dois plugins fazendo a mesma coisa). Centralize logs.
5) Snippet: exigir comprimento e complexidade
Adicione em um plugin Must‑Use (recomendado) ou no functions.php do tema filho.
// /wp-content/mu-plugins/politica-senhas.php
<?php
/**
* Política de senhas mínimas e complexidade.
* Server Express - endurece cadastros, reset e perfil do usuário.
*/
if (!defined('ABSPATH')) exit;
function se_validar_politica_senhas($errors, $update, $user) {
// Aplica ao criar/editar usuário no admin
if (!empty($_POST['pass1'])) {
$senha = $_POST['pass1'];
se_verificar_regras($senha, $errors);
}
}
add_action('user_profile_update_errors', 'se_validar_politica_senhas', 10, 3);
function se_validar_reset($errors, $user) {
// Aplica no reset de senha (frontend)
if (isset($_POST['pass1'])) {
se_verificar_regras($_POST['pass1'], $errors);
}
}
add_action('validate_password_reset', 'se_validar_reset', 10, 2);
function se_verificar_regras($senha, $errors) {
$min = 12;
if (strlen($senha) < $min) {
$errors->add('password_too_short', sprintf(__('A senha deve ter ao menos %d caracteres.'), $min));
}
if (!preg_match('/[a-z]/', $senha)) {
$errors->add('password_lower', __('Inclua ao menos uma letra minúscula.'));
}
if (!preg_match('/[A-Z]/', $senha)) {
$errors->add('password_upper', __('Inclua ao menos uma letra maiúscula.'));
}
if (!preg_match('/\d/', $senha)) {
$errors->add('password_digit', __('Inclua ao menos um número.'));
}
if (!preg_match('/[\W_]/', $senha)) {
$errors->add('password_symbol', __('Inclua ao menos um símbolo.'));
}
// Bloqueia dados óbvios (login, e-mail, domínio)
$user_login = isset($_POST['user_login']) ? sanitize_text_field($_POST['user_login']) : '';
$user_email = isset($_POST['email']) ? sanitize_email($_POST['email']) : (isset($_POST['user_email']) ? sanitize_email($_POST['user_email']) : '');
$proibidos = array_filter([$user_login, $user_email, parse_url(home_url(), PHP_URL_HOST)]);
foreach ($proibidos as $p) {
if ($p && stripos($senha, $p) !== false) {
$errors->add('password_personal_data', __('A senha não pode conter seu login, e-mail ou domínio do site.'));
break;
}
}
}
6) Snippet: bloquear senhas vazadas (Have I Been Pwned)
Consulta via k‑Anonymity (hash SHA‑1 parcial). Não envia a senha em texto puro.
// Acrescente no mesmo MU plugin
function se_password_pwned_check($errors, $user) {
if (isset($_POST['pass1']) && $_POST['pass1']) {
$password = $_POST['pass1'];
$sha1 = strtoupper(sha1($password));
$prefix = substr($sha1, 0, 5);
$suffix = substr($sha1, 5);
$response = wp_remote_get('https://api.pwnedpasswords.com/range/' . $prefix, [
'headers' => ['Add-Padding' => 'true'],
'timeout' => 8,
]);
if (!is_wp_error($response) && 200 === wp_remote_retrieve_response_code($response)) {
$body = wp_remote_retrieve_body($response);
// Procura o sufixo; se existir, a senha já vazou
if (preg_match('/' . preg_quote($suffix, '/') . ':\d+/i', $body)) {
$errors->add('password_pwned', __('Esta senha já apareceu em vazamentos. Escolha outra, mais única.'));
}
}
}
}
add_action('user_profile_update_errors', 'se_password_pwned_check', 20, 3);
add_action('validate_password_reset', 'se_password_pwned_check', 20, 2);
7) Snippet: forçar troca e expiração de senha
Marca usuários para trocar senha no próximo login e expira senhas após X dias.
// Força troca ao próximo login
function se_marcar_redefinir($user_id) {
update_user_meta($user_id, 'se_must_change_password', time());
}
add_action('user_register', 'se_marcar_redefinir');
// Expira após 180 dias
define('SE_MAX_AGE_DIAS', 180);
function se_bloquear_se_expirada() {
if (!is_user_logged_in()) return;
$user_id = get_current_user_id();
$ultima = get_user_meta($user_id, 'se_last_password_change', true);
if (!$ultima) {
// Se não há registro, exigir troca
se_exigir_troca();
} else {
$dias = floor( (time() - intval($ultima)) / DAY_IN_SECONDS );
if ($dias >= SE_MAX_AGE_DIAS) {
se_exigir_troca();
}
}
}
add_action('init', 'se_bloquear_se_expirada');
function se_exigir_troca() {
if (is_admin() || is_page('minha-conta')) return;
// redirecione o usuário para uma página segura de redefinição
wp_safe_redirect(wp_lostpassword_url());
exit;
}
// Registra a data após troca bem-sucedida
function se_registrar_troca($user, $new_pass) {
update_user_meta($user->ID, 'se_last_password_change', time());
delete_user_meta($user->ID, 'se_must_change_password');
}
add_action('password_reset', 'se_registrar_troca', 10, 2);
Observação: Expiração agressiva pode reduzir segurança se levar a senhas previsíveis. Prefira expiração baseada em eventos (ex.: vazamento detectado, privilégio elevado, ocioso > 90 dias) e exija 2FA.
8) WP‑CLI para governança e resposta rápida
# Listar admins rapidamente
wp user list --role=administrator --fields=ID,user_login,user_email
# Forçar redefinição de senha para um usuário
wp user update 123 --user_pass=GeradaForte#2025
# Rotacionar salts (logará todo mundo para fora)
wp config shuffle-salts
9) Checklist de implantação segura
- Defina e documente a política (mín. 12, complexidade, 2FA, bloqueios).
- Implemente snippets/plug‑ins e teste em staging.
- Ative 2FA para papéis críticos e entregue guias de onboarding.
- Habilite WAF, reCAPTCHA/Turnstile e limite de tentativas de login.
- Rotacione SALTs, force logoff, revise admins e remova contas antigas.
- Monitore logs: tentativas, resets, ativações de 2FA.
- Plano de resposta a incidentes (reset em massa, bloqueio, auditoria).
Perguntas Frequentes (FAQ)
Qual o mínimo recomendado para senhas?
Use 12 caracteres como base. Em admins, 14–16 com 2FA obrigatório. O ganho real vem da combinação com 2FA. Expirar senhas melhora a segurança?
Depende. Expirar sem critério pode gerar senhas fracas e previsíveis. Prefira expiração por evento ou para contas sensíveis. 2FA substitui senha forte?
Não. 2FA reduz o risco de senha vazada, mas senhas fortes continuam essenciais. Use os dois. Posso bloquear senhas vazadas?
Sim. O snippet com HIBP recusa senhas conhecidas em vazamentos. É leve e preserva a privacidade com k‑Anonymity. Como evitar reutilização de senhas?
Guarde os hashes das últimas N senhas em meta de usuário e compare no reset. Alguns plugins já oferecem isso pronto. Isso funciona no WooCommerce?
Sim. Os hooks de reset/perfil funcionam para usuários do site inteiro. Teste o fluxo “Minha Conta” antes de subir para produção. Como educar a equipe?
Entregue guia de criação de senhas, recomende gerenciador (Bitwarden, KeePass, 1Password) e habilite políticas corporativas. O que fazer após uma suspeita de vazamento?
Rotacione SALTs, force logoff, redefina senhas chave, exija 2FA, revise acessos e audite logs. Aplique IP block e WAF.
Tags
WordPress, Segurança, Políticas de Senhas, 2FA, WebAuthn, TOTP, Have I Been Pwned, WP‑CLI, Hardening, WAF, Limite de Tentativas, SSL, Admin Security, Server Express









