Skip to content

Tudo para WordPress, desenvolvimento web — e não só

🔐 Que tipo de hash o WordPress utiliza

🔐 Que tipo de hash o WordPress utiliza

A palavra-passe do seu painel de administração é a última barreira entre um hacker e o controlo total do seu site. Uma palavra-passe fraca ou um mecanismo de armazenamento desatualizado transformam um alojamento caro e uma firewall paga em meros enfeites.

Ao longo de vinte anos, o WordPress evoluiu do MD5 para o bcrypt de nível industrial. A partir da versão 6.8, o hashing de palavras-passe tornou-se moderno de raiz, sem plugins ou soluções de contorno. Mas cada proprietário de site deve compreender exatamente o que acontece à sua palavra-passe depois de clicar em «Iniciar sessão».

Abaixo está toda a cadeia: desde a introdução de uma palavra-passe no formulário de início de sessão até à string de hash na base de dados. Com código, filtros e configurações específicas para quem quer mais do que aquilo que o núcleo oferece.

💡 Visão geral rápida:

  • O WordPress 6.8 e versões mais recentes fazem o hash das palavras-passe usando o algoritmo bcrypt, o mesmo padrão utilizado por bancos e sistemas governamentais
  • Os hashes antigos (MD5, phpass) são automaticamente atualizados para bcrypt no próximo início de sessão do utilizador; a migração é transparente e não requer nenhuma ação manual
  • O filtro wp_hash_password_algorithm permite-lhe mudar para Argon2 com uma única linha de código, sem necessidade de plugins
  • O plugin PHP Native Password Hash continua a ser uma opção viável para versões anteriores à 6.8 e fornece uma configuração afinada dos parâmetros do Argon2 através do wp-config.php

O que é o hashing e porque é que o WordPress precisa dele

O hashing é uma transformação criptográfica unidirecional. A partir de uma string de qualquer comprimento, obtém-se uma «impressão digital» de tamanho fixo. Reverter um hash para a palavra-passe original é matematicamente impossível; só se pode experimentar diferentes entradas e comparar os hashes resultantes.

Diagrama de hashing de palavras-passe no WordPress

Ao contrário da encriptação, onde os dados podem ser recuperados com uma chave, um hash é um bilhete só de ida. Quando introduz uma palavra-passe durante o início de sessão, o WordPress passa-a pela mesma função de hash e compara o resultado com o que está armazenado na base de dados. Se coincidirem, o acesso é concedido. Caso contrário, o acesso é negado.

O WordPress armazena os hashes na tabela wp_users, no campo user_pass. Se a base de dados for comprometida (e isto já aconteceu até a gigantes: LinkedIn, Yahoo e Tumblr perderam centenas de milhões de registos), um atacante não obtém palavras-passe legíveis, mas sim longas strings bcrypt. Recuperar a palavra-passe a partir de uma string dessas é impossível. Mas adivinhá-la através de um ataque de dicionário é possível se o algoritmo for fraco ou estiver desatualizado. É exatamente por isso que a evolução do hashing no WordPress é tão importante.

Como o WordPress fazia o hash das palavras-passe: MD5 e phpass

Antes da versão 2.5 (2008), o WordPress usava MD5 simples. O algoritmo transforma qualquer palavra-passe num hash de 128 bits composto por 32 caracteres hexadecimais. Parece seguro, mas o MD5 é vulnerável a rainbow tables (bases de dados pré-calculadas de hashes para milhares de milhões de palavras-passe comuns). Um hacker com acesso à base de dados simplesmente procura o hash numa dessas tabelas e recupera instantaneamente a palavra-passe original.

A partir da versão 2.5, o WordPress passou a usar o phpass, uma biblioteca portátil baseada em bcrypt (Blowfish). Esta adicionava um «sal» aleatório à palavra-passe e executava o resultado através da função de hash várias vezes (por predefinição, 2^8 = 256 iterações). O sal tornava as rainbow tables inúteis: duas palavras-passe idênticas para utilizadores diferentes produziam hashes diferentes. Ao mesmo tempo, o phpass mantinha a compatibilidade retroativa com o MD5; as palavras-passe antigas não se partiam e eram suavemente atualizadas para o novo formato no início de sessão.

Isto foi suficiente durante muitos anos. Mas a indústria avançou: o hardware moderno (fazendas de GPU e ASICs) pode experimentar milhares de milhões de hashes por segundo. O algoritmo bcrypt com um fator de custo configurável tornou-se o padrão da indústria. E a partir do WordPress 6.8, o núcleo utiliza-o nativamente.

WordPress 6.8 e bcrypt: o que mudou

O lançamento do WordPress 6.8 «Cecil» (abril de 2025) trouxe uma transição completa para o bcrypt. Anteriormente, o núcleo usava a sua própria classe PasswordHash da biblioteca phpass; agora chama a função nativa do PHP password_hash() com a constante PASSWORD_BCRYPT.

Segurança do WordPress através de hashing nativo do PHP

Principais alterações na função wp_hash_password():

  • bcrypt por predefinição. Todas as novas palavras-passe sofrem hash via password_hash() usando o algoritmo bcrypt e o fator de custo definido pelo servidor PHP (normalmente 10).
  • Migração automática de palavras-passe antigas. Quando um utilizador inicia sessão, o WordPress verifica através de password_needs_rehash() se o hash precisa de ser atualizado. O formato phpass antigo ($P$...) é substituído de forma transparente por bcrypt.
  • Proteção para palavras-passe longas. O bcrypt trunca palavras-passe com mais de 72 bytes, reduzindo a entropia. O WordPress 6.8 resolve isto fazendo um pré-hash com SHA-384 usando a chave de domínio wp-sha384 e codificando em base64. Uma palavra-passe de 100 caracteres mantém toda a sua força.
  • Filtros para configuração flexível. Surgiram novos hooks: wp_hash_password_algorithm (seleção do algoritmo) e wp_hash_password_options (parâmetros: cost, memory_cost, threads).

A chamada wp_hash_password() no núcleo do WordPress 6.8 tem este aspeto:

1function wp_hash_password( $password ) {
2 global $wp_hasher;
3
4 if ( ! empty( $wp_hasher ) ) {
5 return $wp_hasher->HashPassword( trim( $password ) );
6 }
7
8 if ( strlen( $password ) > 4096 ) {
9 return '*';
10 }
11
12 $algorithm = apply_filters( 'wp_hash_password_algorithm', PASSWORD_BCRYPT );
13 $options = apply_filters( 'wp_hash_password_options', array(), $algorithm );
14
15 if ( PASSWORD_BCRYPT !== $algorithm ) {
16 return password_hash( $password, $algorithm, $options );
17 }
18
19 $password_to_hash = base64_encode(
20 hash_hmac( 'sha384', trim( $password ), 'wp-sha384', true )
21 );
22
23 return '$wp' . password_hash( $password_to_hash, $algorithm, $options );
24}

A função verifica primeiro se a lógica de hashing foi substituída por um plugin externo (a variável global $wp_hasher). Em seguida, rejeita palavras-passe com mais de 4096 caracteres; tais tentativas de início de sessão devolvem *, impossibilitando a autenticação. A seguir vem a parte interessante: o filtro wp_hash_password_algorithm determina o algoritmo. Se a seleção NÃO for bcrypt, a palavra-passe sofre hash diretamente. Se for selecionado bcrypt, a palavra-passe passa primeiro por SHA-384 com a chave wp-sha384, é codificada em base64, e só depois é passada para password_hash(). O resultado é um hash com o prefixo $wp, que distingue o bcrypt «WordPress» do bcrypt simples. Isto é útil para auditorias de base de dados ou integração com sistemas externos.

Como reforçar o hashing com Argon2

O bcrypt é uma excelente base de partida. O passo seguinte é o Argon2, o vencedor da Competição de Hashing de Palavras-passe de 2015. O Argon2 foi especificamente concebido para resistir a ataques de GPU: é intensivo em memória, e as placas gráficas são o ponto de estrangulamento aqui.

Exemplo de código para migrar o WordPress para Argon2

Opção 1: o hook wp_hash_password_algorithm (WordPress 6.8+)

Adicione isto ao functions.php do seu tema filho ou através do plugin Code Snippets:

1add_filter( 'wp_hash_password_algorithm', function() {
2 return PASSWORD_ARGON2ID;
3});

Em poucos segundos, o WordPress muda para Argon2ID. As palavras-passe antigas são automaticamente refeitas quando os utilizadores iniciam sessão. O seu alojamento deve suportar Argon2 em PHP; precisa da versão 7.3 ou mais recente para Argon2ID. Pode verificar a disponibilidade chamando password_algos().

Para afinar os parâmetros, use o hook complementar:

1add_filter( 'wp_hash_password_options', function( $options, $algorithm ) {
2 if ( PASSWORD_ARGON2ID === $algorithm ) {
3 return array(
4 'memory_cost' => 65536, // 64 MB
5 'time_cost' => 4,
6 'threads' => 2,
7 );
8 }
9 return $options;
10}, 10, 2 );

O parâmetro memory_cost determina quanta memória o algoritmo deve usar ao calcular o hash; quanto mais alto o valor, mais difícil se torna a quebra por força bruta baseada em GPU. time_cost define o número de iterações, e threads define o número de threads.

Opção 2: o plugin PHP Native Password Hash

Para versões do WordPress anteriores à 6.8, o plugin PHP Native Password Hash faz o mesmo. Substitui toda a lógica de hashing pelo password_hash() nativo, suporta bcrypt e Argon2, e não tem interface; todas as definições são configuradas através de constantes no wp-config.php:

1define( 'WP_PASSWORD_HASH_ALGO', PASSWORD_ARGON2ID );
2define( 'WP_PASSWORD_HASH_OPTIONS', [
3 'memory_cost' => 65536,
4 'time_cost' => 4,
5 'threads' => 2,
6] );

O plugin não é atualizado há mais de dois anos, mas o seu código é mínimo e estável. Com o WordPress 6.8, a sua funcionalidade está integrada no núcleo, pelo que pode desinstalá-lo e utilizar os filtros nativos.

Geradores de hash: o que funciona hoje

Há situações em que precisa de gerar um hash manualmente: escrever uma palavra-passe diretamente na base de dados através do phpMyAdmin ou migrar utilizadores de um sistema externo.

Gerador de hash de palavras-passe do WordPress via WP-CLI

O gerador online do passwordtool.hu, popular na era das versões mais antigas do WordPress, já não está disponível: o site mudou de proprietário. Alternativas funcionais atualmente:

  • WP-CLI: o comando wp user update <id> --user_pass="newpassword" faz tudo corretamente através do wp_hash_password(). Rápido, seguro e garantidamente correto.
  • Um script PHP na raiz do site: crie temporariamente um ficheiro com uma chamada a echo wp_hash_password('password'); e elimine-o imediatamente após a utilização.
  • Qualquer gerador bcrypt online: por exemplo, bcrypt.online. Mas lembre-se: o WordPress 6.8 adiciona o prefixo $wp e o pré-hashing SHA-384, pelo que um hash bcrypt simples não funcionará para inserção direta na base de dados.

Na prática, o WP-CLI é a opção mais fiável.

Como escolher uma palavra-passe que não será descoberta

Nem o bcrypt o salvará se a palavra-passe for admin123. Os atacantes começam o ataque com força bruta por dicionário.

Interface de verificação da robustez da palavra-passe no WordPress

A ferramenta zxcvbn da Dropbox, integrada no WordPress para avaliação de palavras-passe no painel de administração, rejeita padrões comuns: datas de nascimento, 123456 e qwerty, nomes de animais de estimação. Analisa palavras-passe comparando com dicionários, disposições de teclado e padrões de substituição de caracteres. Uma classificação "fraca" significa que a palavra-passe pode ser adivinhada em segundos.

Três regras práticas:

  • Palavras aleatórias, não sopa de caracteres. Uma palavra-passe composta por quatro ou cinco palavras inglesas não relacionadas com separadores (por exemplo, correct-horse-battery-staple) é mais fácil de memorizar do que Tr0ub4dor&3 e demora muito mais tempo a ser descoberta.
  • O comprimento importa mais do que a complexidade. Dezasseis letras minúsculas aleatórias proporcionam maior entropia do que 8 caracteres com símbolos especiais. E o bcrypt no WordPress 6.8 preserva a entropia de palavras-passe de qualquer comprimento razoável através do pré-hashing SHA-384.
  • Use um gestor de palavras-passe. A memória humana é uma ferramenta fraca para gerir uma dúzia de palavras-passe únicas. O 1Password é o padrão de ouro pago com plano familiar, o KeePass é gratuito e de código aberto com base de dados local, o Bitwarden é o meio-termo feliz: gratuito, baseado na nuvem e de código aberto.
Gestor de palavras-passe para armazenar credenciais do WordPress

Um gestor de palavras-passe gera, armazena e preenche automaticamente as palavras-passe. Só precisa de se lembrar de uma palavra-passe mestra. E se o site suportar autenticação de dois fatores, ative-a sem falta. Uma palavra-passe mais um código único de uma aplicação torna o início de sessão virtualmente invulnerável.

Vídeo: como funciona o hashing de palavras-passe no WordPress

Uma breve explicação do mecanismo de hashing, desde a introdução de uma palavra-passe até ao armazenamento na base de dados do WordPress:

⁉️🤔 Perguntas frequentes

As palavras-passe com hash MD5 antigo ainda funcionam no WordPress 6.8+?

Sim. Quando um utilizador inicia sessão, o WordPress deteta o formato de hash antigo, verifica a palavra-passe usando o algoritmo anterior e, se tudo estiver correto, atualiza o hash para bcrypt de forma transparente. Não é necessário eliminar utilizadores antigos nem forçar a redefinição de palavras-passe.

O plugin PHP Native Password Hash é necessário no WordPress 6.8 e mais recentes?

Não. Tudo o que o plugin fazia (hashing via password_hash() e suporte a Argon2) está agora disponível através dos filtros nativos wp_hash_password_algorithm e wp_hash_password_options. O plugin permanece relevante apenas para versões anteriores à 6.8.

Posso voltar a usar Argon2 em vez de bcrypt?

Tecnicamente sim, alterando o algoritmo no filtro. Mas os hashes Argon2 antigos não serão reconhecidos e os utilizadores terão de redefinir as suas palavras-passe. Se estiver a experimentar algoritmos num site ativo, faça primeiro uma cópia de segurança completa da base de dados.

O bcrypt ajuda se a base de dados for comprometida?

O bcrypt torna a descoberta de palavras-passe a partir de hashes comprometidos centenas de milhares de vezes mais lenta do que o MD5. Com um fator de custo de 10, um hash num CPU moderno demora cerca de 0,1 segundos a calcular; mil milhões de tentativas levariam anos. Mas se a palavra-passe for password, será encontrada na primeira iteração de um ataque de dicionário. O algoritmo protege palavras-passe complexas; nada pode salvar as fracas.

Como verifico se as minhas palavras-passe estão a ser armazenadas com bcrypt?

Verifique a tabela wp_users via phpMyAdmin. O campo user_pass para novos utilizadores (e para aqueles que iniciaram sessão após a atualização para a 6.8) deve começar com o prefixo $wp (o marcador do novo formato bcrypt do WordPress). Os hashes phpass antigos têm o aspeto $P$B.... Para uma verificação em massa, execute esta consulta SQL: SELECT COUNT(*) FROM wp_users WHERE user_pass NOT LIKE '$wp$%' AND user_pass NOT LIKE '$P$%';. Mostrará quantas palavras-passe estão presas num formato desatualizado, se existirem.

O que fazer quanto ao hashing do WordPress agora mesmo

Se o seu site WordPress estiver na versão 6.8 ou mais recente, já está protegido pelo bcrypt; não precisa de fazer nada. O núcleo atualiza automaticamente os hashes antigos quando os utilizadores iniciam sessão e a migração é completamente transparente.

Se quiser Argon2, adicione o filtro wp_hash_password_algorithm com PASSWORD_ARGON2ID ao functions.php. Primeiro, certifique-se de que o seu alojamento suporta Argon2: execute var_dump(password_algos()); através de um script de teste. A maioria dos fornecedores de alojamento modernos tem suporte.

Para versões anteriores à 6.8, instale o plugin PHP Native Password Hash; ele fornecer-lhe-á bcrypt ou Argon2 sem atualizar o núcleo. E agende uma atualização do WordPress já agora: cada atualização principal fecha dezenas de vulnerabilidades, não apenas no hashing.

E, mais importante, mude admin123 para algo decente. Nenhum algoritmo o pode salvar de um ataque de dicionário se a sua palavra-passe estiver nas primeiras cem entradas da lista rockyou.txt.