Glossário

O que são Nonces no WordPress? Tokens de segurança explicados

5 de agosto de 2026

Um nonce no WordPress é um token de segurança anexado a formulários, links e requisições AJAX para que o WordPress possa verificar se a requisição foi disparada intencionalmente por um usuário logado específico. O nome vem da criptografia e significa number used once, mas aqui isso é um pouco enganoso: um nonce do WordPress não é um número, não é usado só uma vez e tecnicamente é um hash amarrado ao usuário, à sessão e a uma ação específica. Ele permanece válido por até 24 horas. A ameaça principal contra a qual os nonces defendem é o cross-site request forgery (CSRF), um ataque em que uma página maliciosa envia silenciosamente uma requisição usando a sua sessão logada, por exemplo para excluir um post ou alterar uma configuração. Nonces funcionam, e é exatamente por isso que o erro de segurança mais comum em torno deles está do outro lado: um nonce comprova intenção, não permissão. Código de plugin que verifica um nonce mas esquece a checagem de capacidade com current_user_can() é uma das fontes mais frequentes de vulnerabilidades publicadas no WordPress.

O que é um nonce? O nome engana um pouco

Na criptografia, um nonce é um valor usado exatamente uma vez e nunca mais, e é isso que o torna útil contra ataques de repetição. O WordPress pegou emprestado o nome, mas não a definição estrita. Um nonce do WordPress é um hash curto gerado a partir de quatro ingredientes: a ação à qual ele pertence, o ID e o token de sessão do usuário atual, a janela de tempo corrente e as chaves secretas do seu wp-config.php. Essa construção tem três consequências práticas:

  • Um nonce é pessoal. Um token gerado para um usuário falha na validação para qualquer outro usuário, então ele não pode ser compartilhado nem roubado de uma página pública.
  • Um nonce é específico de uma ação. Um token criado para a ação delete-post_42 não vale nada para delete-post_43 nem para qualquer outra operação. É por isso que fixar um nome de ação genérico enfraquece todo o mecanismo.
  • Um nonce é reutilizável dentro do seu tempo de vida. O mesmo token valida quantas vezes você quiser, por até 24 horas. O WordPress documenta isso explicitamente, então um nonce sozinho não protege contra a repetição de uma requisição que o atacante já capturou.

A documentação oficial para desenvolvedores do WordPress é refrescantemente honesta sobre tudo isso e descreve nonces como uma camada de defesa, não como um sistema de segurança completo.

Quais ataques os nonces do WordPress evitam? CSRF explicado

O ataque para o qual os nonces existem é o cross-site request forgery. O cenário: você está logado no painel do WordPress em uma aba do navegador. Em outra aba, você abre uma página completamente sem relação, controlada por um atacante. Essa página contém um formulário oculto ou uma tag de imagem apontando para o seu site, algo como uma requisição para desativar um plugin ou criar um usuário. Como o navegador envia automaticamente os seus cookies do WordPress em toda requisição para o seu domínio, a requisição chega totalmente autenticada, e o WordPress a executaria sem hesitar. Você não clicou em nada, não viu nada, e o seu site acabou de ganhar um novo administrador.

Os nonces quebram esse ataque no último passo. A página maliciosa consegue forjar a requisição, mas não tem como saber o nonce atual do seu usuário para aquela ação, porque o token só aparece dentro de páginas que o WordPress renderiza para você. A requisição forjada chega sem um nonce válido, a verificação falha e o WordPress para com aquela tela branca famosa que pergunta: tem certeza de que deseja fazer isso?

Por quanto tempo um nonce do WordPress é válido? O sistema de ticks

O WordPress divide o tempo em ticks de doze horas. Quando um nonce é verificado, o WordPress aceita tokens do tick atual e do anterior, e é daí que vem o tempo de vida máximo de 24 horas. As funções de verificação até informam em qual metade você está: elas retornam 1 se o nonce foi gerado nas últimas doze horas e 2 se ele tem entre doze e 24 horas, e false se for inválido ou expirado.

O tempo de vida pode ser alterado com o filtro nonce_life, que algumas configurações focadas em segurança usam para encurtar a janela:

// Reduz o tempo de vida do nonce para 4 horas
add_filter( 'nonce_life', function () {
	return 4 * HOUR_IN_SECONDS;
} );

Tempos de vida mais curtos encolhem a janela de repetição, mas também fazem páginas em cache com nonces embutidos expirarem mais rápido, o que é um problema real em sites com cache de página agressivo. Se uma página em cache entrega um nonce com mais de 24 horas, todo visitante recebe um token que nunca vai validar. Essa é a razão clássica pela qual recursos AJAX em sites WordPress com cache pesado falham misteriosamente para alguns visitantes.

Como criar um nonce no WordPress

O WordPress traz três funções auxiliares para gerar nonces, uma para cada lugar onde um token costuma viver:

// 1. Em um formulário: adiciona um campo oculto mais um campo de referer
wp_nonce_field( 'save_settings_action', 'my_plugin_nonce' );

// 2. Em uma URL: acrescenta ?_wpnonce=... a um link
$url = wp_nonce_url( admin_url( 'admin.php?page=my-plugin&delete=42' ), 'delete-item_42' );

// 3. Token puro, por exemplo para repassar ao JavaScript
$nonce = wp_create_nonce( 'my_ajax_action' );

O primeiro argumento é sempre a ação, e é aí que o cuidado compensa. Uma string de ação como delete-item_42, que inclui o ID do objeto, produz um token que só funciona para exatamente aquele item. Uma ação genérica e preguiçosa como my_nonce compartilhada por um plugin inteiro significa que um único token vazado ou de contexto previsível destrava todas as operações que o plugin oferece.

Como verificar um nonce: wp_verify_nonce, check_admin_referer e check_ajax_referer

A verificação tem uma função de baixo nível e dois invólucros de conveniência que você vai encontrar com muito mais frequência em código real:

// Baixo nível: retorna 1, 2 ou false, nunca interrompe
if ( ! wp_verify_nonce( $_POST['my_plugin_nonce'], 'save_settings_action' ) ) {
	return; // para aqui, requisição inválida
}

// Telas de administração: verifica e interrompe com uma página de erro se falhar
check_admin_referer( 'save_settings_action', 'my_plugin_nonce' );

// Handlers AJAX: mesma ideia para requisições ao admin-ajax.php
check_ajax_referer( 'my_ajax_action', 'security' );

Os invólucros interrompem a execução quando a verificação falha, que costuma ser o que você quer no topo de um handler. A função de baixo nível wp_verify_nonce() devolve o valor de retorno, então você pode responder com um erro JSON adequado em um contexto de API. Qualquer que seja a variante, a verificação precisa vir antes de a ação ser executada, e não depois, o que parece óbvio e mesmo assim continua sendo um bug recorrente nos changelogs de plugins.

Nonces na REST API e em requisições AJAX

A REST API do WordPress usa o mesmo mecanismo com um nome de ação fixo. Para qualquer requisição que dependa de autenticação por cookie, o WordPress espera um nonce criado para a ação wp_rest, entregue no cabeçalho de requisição X-WP-Nonce. Scripts registrados da forma padrão recebem isso automaticamente: wp_localize_script() ou o pacote mais novo wp.apiFetch repassam o token, e toda requisição REST de um usuário logado o carrega sem que quem desenvolve precise pensar nisso.

// Repassando um nonce REST para o seu JavaScript
wp_localize_script( 'my-app', 'myAppData', array(
	'restUrl' => esc_url_raw( rest_url( 'my-plugin/v1/' ) ),
	'nonce'   => wp_create_nonce( 'wp_rest' ),
) );

// No JavaScript: envie como cabeçalho
fetch( myAppData.restUrl + 'items', {
	method: 'POST',
	headers: { 'X-WP-Nonce': myAppData.nonce, 'Content-Type': 'application/json' },
	body: JSON.stringify( { title: 'Novo item' } ),
} );

Sem o cabeçalho, a REST API trata a requisição como não autenticada, mesmo que o navegador tenha enviado cookies de login válidos. Isso é proposital: é exatamente a proteção contra CSRF descrita acima, aplicada à API.

Por que um nonce não é uma verificação de permissão

Esta é a coisa mais importante a entender sobre nonces, e é a parte que regularmente dá errado no ecossistema de plugins. Uma verificação de nonce bem-sucedida comprova duas coisas: a requisição partiu de uma página que o WordPress gerou e pertence ao usuário para quem ela foi emitida. Ela não comprova que esse usuário tem permissão para fazer o que a requisição pede. Um assinante pode ter um nonce perfeitamente válido, porque o WordPress emite nonces alegremente para todo usuário logado, e alguns tokens funcionam até para visitantes que não estão logados.

Por isso, um handler correto sempre faz duas perguntas separadas:

// Intenção: esta é uma requisição legítima deste usuário?
check_admin_referer( 'save_settings_action', 'my_plugin_nonce' );

// Permissão: este usuário tem autorização para fazer isso?
if ( ! current_user_can( 'manage_options' ) ) {
	wp_die( 'Permissões insuficientes.' );
}

Os bancos de dados de vulnerabilidades estão cheios do que acontece quando a segunda pergunta é pulada. Controle de acesso quebrado e CSRF aparecem consistentemente entre as categorias mais comuns nos CVEs de plugins WordPress, e boa parte dessas entradas se resume a um handler que verificou um nonce, ou nada, em vez de uma capacidade. Se você ler um aviso de plugin dizendo que qualquer usuário autenticado podia alterar configurações ou que faltava autorização, normalmente é esse padrão por trás.

Erros comuns com nonces em temas e plugins

  • Verificação de nonce no lugar da verificação de capacidade. O clássico, descrito acima. As duas checagens são necessárias, elas respondem perguntas diferentes.
  • Um nonce genérico para tudo. Uma única string de ação em todo um plugin transforma um token restrito em uma chave mestra.
  • Nonces em páginas em cache. Caches de página inteira servem tokens além do tempo de vida de 24 horas, quebrando silenciosamente formulários e AJAX para alguns visitantes. Cache de fragmentos ou buscar o nonce separadamente resolve o problema.
  • Verificar depois de agir. A checagem precisa ser a primeira coisa que o handler faz.
  • Confiar em um nonce como prova de identidade para visitantes deslogados. Nonces para visitantes sem sessão são mais fracos por construção, já que o componente de usuário do hash fica vazio.
  • Vazar nonces em URLs. Tokens anexados a links acabam em logs de servidor, no histórico do navegador e no cabeçalho Referer. Para ações destrutivas, requisições POST com wp_nonce_field() são a casa mais adequada.

Como o InspectWP ajuda você a enxergar as consequências

Você não consegue ver de fora se um plugin verifica seus nonces corretamente, mas consegue ver as consequências quando elas se tornam públicas. O InspectWP detecta os plugins e temas de um site WordPress analisado junto com suas versões e os compara com dados de vulnerabilidades conhecidas, e falhas de CSRF e de autorização ausente exatamente do tipo descrito neste artigo formam uma parcela grande dessas entradas. Se um relatório sinaliza um plugin instalado com uma vulnerabilidade publicada, a correção é quase sempre a mesma e refrescantemente simples: atualizar. Com relatórios automáticos agendados, esse ciclo de detectar, aprender e atualizar roda continuamente, em vez de acontecer quando alguém por acaso se lembra dele.

Verifique seu site WordPress agora

O InspectWP analisa seu site WordPress em busca de problemas de segurança, problemas de SEO, conformidade com GDPR e desempenho — gratuitamente.

Analise seu site grátis