Glossário

O que é TOCTOU: quando o estado muda entre a verificação e o uso

TOCTOU (time-of-check to time-of-use) é uma condição de corrida em que o estado muda após uma verificação. Como funciona e como se defender: combine verificação e uso em uma única etapa.

Publicado 2026-11-15 Atualizado 2026-11-15 6 min de leitura
Nesta página

TOCTOU (time-of-check to time-of-use) é um problema em que o estado de algo muda entre o momento em que é verificado e o momento em que é usado. Esta página explica como ele funciona e como preveni-lo (sem passos de ataque).

O que é TOCTOU

Programas frequentemente funcionam no modelo "verificar e, se estiver certo, usar": por exemplo, "verificar que este arquivo pode ser gravado e depois abri-lo e gravá-lo". Mas existe um pequeno intervalo de tempo entre a verificação e o uso. Se outro programa ou requisição alterar o alvo nesse intervalo, o resultado da verificação deixa de valer.

A CWE-367 da MITRE descreve isso como um produto que verifica o estado de um recurso antes de usá-lo, em que o estado pode mudar entre a verificação e o uso de forma que invalida a verificação. CWE (Common Weakness Enumeration) é um catálogo compartilhado das fraquezas por trás das vulnerabilidades. O TOCTOU é um tipo de condição de corrida, em que o resultado depende da temporização de coisas que rodam ao mesmo tempo.

Por que acontece

1. Verificação: este arquivo pode ser gravado? → OK
2. Intervalo: outro processo substitui o que esse nome aponta
↓ o resultado da verificação não corresponde mais à realidade
3. Uso: o programa grava em um alvo que nunca foi verificado
Quando verificação e uso são etapas separadas, o alvo pode ser trocado no intervalo e o resultado da verificação fica desatualizado.

Segundo a CWE-367, as consequências podem incluir acesso a recursos que deveriam estar fora de alcance, recursos alterados de maneiras indesejadas e registros de log ausentes. O intervalo pode ser curto, mas em sistemas que executam muitas coisas ao mesmo tempo ele é atingido repetidamente, não apenas por acaso.

Onde aparece

LocalVerificaçãoUsoO que dá errado
Tratamento de arquivosVerificação de existência ou permissãoAbrir ou gravarO arquivo é trocado após a verificação
Estoque ou saldo em aplicação webSELECT da quantidade restanteUPDATE para reduzi-laDuas requisições simultâneas passam e excedem o limite
Pagamentos e cadastrosAinda está não processado?Executar a açãoUm envio duplo a executa duas vezes
Upload de arquivosInspecionar o conteúdoArmazenar ou publicarO conteúdo muda após a inspeção

Para inspeção de uploads, veja também vulnerabilidades de upload de arquivos.

Defesa: não separe a verificação do uso

1

Pare de verificar antes de usar

O conselho mais básico da CWE-367 é não realizar uma verificação antes do uso. Use o recurso diretamente e trate o erro caso a operação falhe. Isso elimina o próprio intervalo.

2

Use descritores de arquivo, não caminhos

Abra o arquivo primeiro e, em seguida, verifique o estado e grave pelo descritor de arquivo aberto. Consultar repetidamente o mesmo nome de caminho pode apontar para um alvo diferente a cada vez. Flags como O_NOFOLLOW (não seguir links simbólicos) e chamadas como openat (abrir em relação a um diretório) também ajudam; o que está disponível depende do sistema operacional.

3

Use atualizações condicionais e transações em bancos de dados

Em vez de "SELECT para verificar, depois UPDATE", use um único UPDATE que inclua a condição (por exemplo, decrementar somente quando a quantidade for 1 ou mais). Quando várias instruções estão envolvidas, use uma transação com um nível de isolamento adequado e bloqueios de linha.

4

Bloqueie antes da verificação

Se você usar bloqueios, obtenha-os antes da verificação, como diz a CWE-367. Bloquear depois não garante que o alvo verificado seja o alvo que você usa.

5

Impeça execução duplicada com chaves de idempotência

Para pagamentos e cadastros, atribua a cada requisição uma chave única (uma chave de idempotência) e execute a ação apenas uma vez por chave.

Como verificar o seu próprio código

Faça isso em código que você desenvolve ou gerencia.

  1. Encontre trechos em que o código de verificação e o código de uso são chamadas separadas (verificação de existência e depois abertura; SELECT e depois UPDATE)
  2. Para cada um, pergunte se a verificação pode ser eliminada e a etapa transformada em uma única operação
  3. Escreva um teste que envie a mesma requisição várias vezes ao mesmo tempo e confirme que apenas uma é aplicada
  4. Nunca tente isso contra o serviço de outra pessoa; use o seu próprio ambiente

Visão deste site: coloque a verificação dentro da mesma operação do uso

TOCTOU não é "alguém esqueceu a verificação". A verificação existe; ela apenas está separada do uso. Adicionar mais código de verificação não resolve isso. A correção é colocar a verificação dentro da mesma operação atômica do uso, e não adicioná-la como uma etapa extra. Estudá-lo junto com IDOR ajuda nas revisões de código: ambos são erros em que "a verificação existe, mas não cumpre sua função".

Fontes (primárias)

  • MITRE CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition — cwe.mitre.org (definição, consequências, mitigações)
  • As técnicas concretas (O_NOFOLLOW, openat, chaves de idempotência, transações) são descritas como práticas gerais de implementação; a disponibilidade varia conforme o sistema operacional e o banco de dados, então consulte a documentação oficial de cada produto

Leia a seguir

Classificação

O CWE classifica os tipos de fraqueza por trás das vulnerabilidades; o MITRE ATT&CK classifica as técnicas dos atacantes. Ambos são mantidos pela MITRE e amplamente usados para rotular vulnerabilidades e regras de detecção.

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

FAQ

QO que significa TOCTOU?
A

A sigla vem de time-of-check to time-of-use (momento da verificação até o momento do uso). O estado de um recurso muda entre o momento em que é verificado e o momento em que é usado. A CWE-367 da MITRE descreve como um produto que verifica o estado de um recurso antes de usá-lo, em que o estado pode mudar de forma que invalida a verificação. É um tipo de condição de corrida.

QOnde acontece o TOCTOU?
A

O caso clássico é o tratamento de arquivos: um programa verifica se um arquivo existe ou pode ser gravado e, em uma chamada separada, o abre, e o arquivo pode ser trocado nesse intervalo. Também ocorre em aplicações web e bancos de dados, como 'verificar estoque e depois confirmar o pedido' ou 'verificar o saldo e depois debitar', quando a verificação e a atualização são etapas separadas.

QQual é a principal defesa?
A

Combinar verificação e uso em uma única operação atômica. A CWE-367 diz que o conselho mais básico é não realizar uma verificação antes do uso. Para arquivos, abra primeiro e depois inspecione ou atue sobre o descritor de arquivo aberto. Para bancos de dados, use uma atualização condicional ou uma transação com bloqueio.

QAdicionar um bloqueio sempre torna o código seguro?
A

O bloqueio precisa ser obtido antes da verificação, não depois. A CWE-367 diz que é preciso garantir que o bloqueio ocorra antes da verificação, e não depois. Bloquear após a verificação não garante que o recurso verificado seja o recurso usado. Além disso, um bloqueio não faz nada se o seu escopo for estreito demais ou se outros programas o ignorarem.

QO TOCTOU afeta aplicações web?
A

Sim. Exemplos são salvar um arquivo enviado depois de inspecioná-lo, decrementar um cupom ou a quantidade em estoque após lê-lo, e manipuladores de pagamento que não podem ser executados duas vezes. Se a mesma requisição chegar duas vezes ao mesmo tempo, as duas podem passar pela verificação. Torne a atualização uma única operação condicional e use chaves de idempotência para impedir execução duplicada.

QComo procuro TOCTOU no meu próprio código?
A

Procure trechos em que o código de verificação e o código de uso estejam em linhas ou chamadas separadas. Em código de arquivos, isso é uma verificação de existência ou permissão seguida de abertura por caminho. Em código de banco de dados, é um SELECT de verificação seguido de um UPDATE. Depois, veja se é possível eliminar a verificação e tornar tudo uma única operação, e adicione testes de requisições concorrentes.