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
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
| Local | Verificação | Uso | O que dá errado |
|---|---|---|---|
| Tratamento de arquivos | Verificação de existência ou permissão | Abrir ou gravar | O arquivo é trocado após a verificação |
| Estoque ou saldo em aplicação web | SELECT da quantidade restante | UPDATE para reduzi-la | Duas requisições simultâneas passam e excedem o limite |
| Pagamentos e cadastros | Ainda está não processado? | Executar a ação | Um envio duplo a executa duas vezes |
| Upload de arquivos | Inspecionar o conteúdo | Armazenar ou publicar | O 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
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.
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.
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.
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.
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.
- 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)
- Para cada um, pergunte se a verificação pode ser eliminada e a etapa transformada em uma única operação
- Escreva um teste que envie a mesma requisição várias vezes ao mesmo tempo e confirme que apenas uma é aplicada
- 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
- Glossário: O que é path traversal · O que é IDOR · O que é o OWASP Top 10
- Guia: Vulnerabilidades de upload de arquivos
- Glossário: O que é um CVE