Modelo de ameaças e autoatestação OWASP ASVS L1
As ameaças que o Vaulted foi projetado para derrotar, as que não, e uma atestação controle por controle frente a uma base de referência do setor.
Versão 1.0 · Publicado em 2026-04-27 · Origem: main · Autor: Maxim Novak
Sobre este documento
Isto é uma autoatestação, não uma auditoria de terceiros. Ela existe para que você possa ver exatamente o que o Vaulted afirma proteger, o que não, e como cada decisão de projeto se relaciona com controles reconhecidos. Vamos contratar uma revisão independente e publicar seu relatório junto a esta página quando o orçamento permitir. Até lá, você pode verificar você mesmo a afirmação central de zero-knowledge em cinco minutos com as DevTools do navegador.
1. Escopo e premissas
Este modelo cobre a implantação de produção do vaulted.fyi incluindo seu frontend web, suas rotas de API e o armazenamento no Upstash Redis. Também cobre o CLI publicado e o servidor MCP na medida em que interagem com a mesma API.
Fora do escopo:
- O dispositivo do usuário (navegador, sistema operacional, extensões, área de transferência, tela).
- O canal de comunicação pelo qual o link compartilhado é entregue (e-mail, Slack, SMS, etc.).
- O tratamento posterior do texto simples por parte do destinatário.
- Vulnerabilidades no Vercel ou Upstash abaixo da superfície de API que consumimos.
2. Ativos e fronteiras de confiança
Ativo principal: o segredo em texto simples. Ele nunca deve chegar ao servidor, persistir fora dos navegadores do remetente e do destinatário, nem ser recuperável apenas a partir do estado do lado do servidor.
Ativos secundários: o texto cifrado, os IVs, os contadores de visualizações, os carimbos de tempo de expiração e a integridade / disponibilidade do serviço.
Fronteiras de confiança (em ordem decrescente de confiança):
- Navegador do remetente — confiável com o texto simples e a chave.
- Navegador do destinatário — confiável com o texto simples e a chave após abrir o link.
- Rede entre o cliente e o servidor — não confiável; mitigado por TLS 1.3 e pela decisão de projeto de que apenas o texto cifrado a atravessa.
- Servidor do Vaulted (nós) — parcialmente confiável. Tratado como um armazenamento passivo de texto cifrado. O modelo de ameaças assume que o próprio Vaulted poderia ser comprometido sem expor o texto simples.
- Upstash Redis — mesmo nível de confiança que o servidor. Apenas blocos criptografados.
3. Atores de ameaça
Observador passivo da rede. ISP, ator no caminho com acesso a metadados de TLS. Derrotado pelo TLS e pela ausência de texto simples ou chave no canal.
Atacante ativo da rede. Pode tentar um MitM. Derrotado por TLS, precarga de HSTS e validação de certificados. Um comprometimento bem-sucedido do TLS ainda revela apenas texto cifrado.
Servidor comprometido / operador hostil. Inclui nós. Não consegue ler os segredos armazenados porque a chave nunca chega. Pode negar o serviço ou modificar o bundle de JS servido — o que é abordado nos riscos residuais mais abaixo.
Atacante não autenticado com um link compartilhado válido. Por design, qualquer pessoa com o link completo pode descriptografar. Os limites de visualizações, a expiração e a frase-senha opcional reduzem a janela. É uma propriedade deliberada, não uma falha.
Atacante direcionado contra um remetente ou destinatário específico. Pode explorar o dispositivo, o canal de entrega ou o tratamento do texto simples pelo destinatário após a descriptografia. Fora do controle do Vaulted; documentado por honestidade.
4. Controles
- AES-256-GCM no lado do cliente com IVs aleatórios de 96 bits de
crypto.getRandomValues. - Chaves de 256 bits geradas por segredo via
crypto.subtle.generateKey; colocadas no fragmento da URL, nunca transmitidas. - Encapsulamento opcional com frase-senha usando PBKDF2 (alta contagem de iterações) e encapsulamento de chave AES-GCM.
- Aplicação atômica da contagem de visualizações via
HINCRBYdo Redis com exclusão na mesma transação ao atingir o limite. - Expiração automática baseada em TTL limitada a 30 dias; sem prorrogação após a criação.
- Limitação de taxa por IP com janela deslizante nos endpoints de criação e visualização.
noindexnas páginas de visualização /s/[id] para que as URLs dos segredos não possam vazar por meio de buscas.- TLS 1.3 com precarga de HSTS, cabeçalhos de segurança robustos, sem registro de IP além das janelas de limitação de taxa.
5. Riscos residuais (não defendidos)
São decisões de fronteira deliberadas, documentadas para que os usuários possam decidir se o Vaulted se encaixa em seu modelo de ameaças.
- Comprometimento do dispositivo. Um keylogger, um navegador infectado ou uma extensão hostil podem ler o texto simples após a descriptografia.
- Vazamento do canal de entrega. Se o link compartilhado for encaminhado, arquivado ou citado em uma thread de e-mail respondida, esse canal se torna a superfície de ataque.
- Troca direcionada do bundle. Uma CDN ou um edge do Vercel comprometidos poderiam servir um JS diferente a um usuário específico. Subresource Integrity e builds reproduzíveis são mitigações parciais e estão no roadmap.
- Comportamento do destinatário. Uma vez descriptografado, o destinatário pode copiar, fazer captura de tela ou encaminhar.
- Frase-senha fraca. Se usada, uma frase-senha fraca é vulnerável a força bruta por qualquer pessoa que tenha a chave encapsulada.
- Coação / tortura. Fora do escopo de qualquer controle técnico.
6. Autoatestação OWASP ASVS L1
A matriz a seguir mapeia a implementação do Vaulted contra uma seleção de requisitos do OWASP ASVS nível 1. As categorias que não se aplicam (sessões, autenticação, upload de arquivos) são marcadas como N/A com uma breve justificativa em vez de omitidas, para que a ausência de uma entrada não seja interpretada como evasão.
| ID | Categoria | Requisito | Status | Evidência |
|---|---|---|---|---|
| V1.1.1 | Arquitetura | SDLC seguro com modelagem de ameaças para a aplicação | Pass | Este documento. Revisado a cada mudança material de arquitetura. |
| V1.4.1 | Arquitetura | Os pontos de aplicação confiáveis impõem os controles de acesso | Pass | Os manipuladores de rotas da API validam as entradas e consomem visualizações de forma atômica via Redis HINCRBY em src/lib/redis-secrets-store.ts. |
| V2.10.x | Autenticação | Autenticação de serviço / usuário | N/A | O Vaulted é anônimo. Sem contas de usuário, sem autenticação de serviço a serviço. A autorização se baseia no conhecimento do ID do segredo e da chave do fragmento da URL. |
| V3.x | Gerenciamento de sessões | Requisitos de gerenciamento de sessões | N/A | Sem sessões, sem cookies para estado autenticado. |
| V5.1.3 | Validação de entradas | Validação de entradas na camada de serviço confiável | Pass | Validação manual em tempo de execução em src/app/api/secrets/route.ts. Payload ≤ 1000 caracteres aplicado no servidor; máximo de visualizações e TTL limitados. |
| V5.2.5 | Sanitização | Codificação de saída conforme o contexto (HTML, JS, URL) | Pass | O React escapa por padrão todos os valores interpolados. As únicas chamadas a dangerouslySetInnerHTML renderizam literais JSON-LD construídos no servidor a partir de dados tipados. |
| V6.2.1 | Criptografia armazenada | Usar algoritmos criptográficos aprovados com padrões seguros | Pass | AES-256-GCM via Web Crypto API. NIST SP 800-38D. Veja src/lib/crypto.ts. |
| V6.2.2 | Criptografia armazenada | Geração de números aleatórios criptograficamente forte | Pass | crypto.getRandomValues para os IVs e o material de chave. crypto.subtle.generateKey para as chaves AES. |
| V6.2.5 | Criptografia armazenada | Sem primitivas criptográficas inseguras ou obsoletas | Pass | Sem MD5, SHA-1, DES, RC4, ECB ou CBC sem MAC em nenhuma parte do caminho criptográfico. |
| V6.3.1 | Criptografia armazenada | Chaves protegidas contra acesso não autorizado | Pass | A chave de criptografia nunca chega ao servidor. Vive apenas no fragmento da URL, processada no cliente conforme o RFC 3986. Uma frase-senha opcional encapsula a chave com PBKDF2 antes do compartilhamento. |
| V7.1.1 | Tratamento de erros e registro | Sem informações sensíveis nos registros | Pass | O servidor registra apenas a forma da requisição e as decisões de limitação de taxa. Sem texto cifrado, sem IDs de segredo de forma que possam ser correlacionados, sem IPs persistidos além da janela de limitação de taxa. |
| V7.4.1 | Tratamento de erros e registro | Mensagens de erro genéricas | Pass | As rotas da API retornam códigos de status HTTP genéricos e strings de erro curtas. Sem vazamento de stack traces ou estado interno. |
| V8.1.1 | Proteção de dados | Dados sensíveis identificados e protegidos | Pass | O servidor nunca recebe o texto simples. O texto cifrado é armazenado criptografado em repouso no Upstash Redis, com exclusão baseada em TTL e aplicação atômica do limite de visualizações. |
| V8.3.1 | Proteção de dados | Dados sensíveis não expostos em URLs ou referrers | Pass | A chave de criptografia vive no fragmento da URL; os fragmentos nunca são enviados ao servidor e são removidos do document.referrer pelos navegadores conforme o RFC 3986 §3.5. |
| V9.1.1 | Comunicações | TLS para toda a conectividade do cliente | Pass | TLS 1.3 aplicado no edge do Vercel. HSTS precarregado. As requisições HTTP são redirecionadas para HTTPS. |
| V10.3.2 | Código malicioso | Código da aplicação revisado em busca de código malicioso | Pass | Base de código de um único mantenedor. Todos os commits são do proprietário do projeto; commits assinados quando possível. As atualizações de dependências via Dependabot são revisadas antes do merge. |
| V11.1.1 | Lógica de negócio | Fluxos de lógica protegidos contra abuso | Pass | Limitação de taxa por IP via Upstash Ratelimit (10 criações/min, 30 visualizações/min). Os contadores de visualizações são decrementados de forma atômica. |
| V12.x | Arquivos e recursos | Requisitos de upload e processamento de arquivos | N/A | O Vaulted não aceita uploads de arquivos. |
| V13.2.1 | API e serviços web | Os endpoints RESTful validam o esquema da requisição | Pass | Todos os manipuladores POST/GET validam os parâmetros de caminho, a forma do corpo e o content-type antes de processar. |
| V14.4.3 | Configuração | Cabeçalhos de segurança padrão configurados | Pass | HSTS, X-Content-Type-Options, Referrer-Policy e Permissions-Policy definidos via configuração do Next.js. Content-Security-Policy aplicada por requisição em src/proxy.ts com um script-src strict-dynamic baseado em nonce; as rotas da API recebem uma política restritiva default-src none. |
A numeração segue a estrutura do ASVS 4.0. A lista é selecionada, não exaustiva — o objetivo é ser honesto sobre os controles que se aplicam de forma significativa a um armazenamento de texto cifrado sem estado e sem contas.
7. Processo de mudanças
Qualquer mudança que afete um item deste documento — novo endpoint, mudança criptográfica, refatoração que afete dependências, mudança de infraestrutura — deve disparar uma revisão desta página no mesmo PR. A versão e a data de publicação acima serão incrementadas quando o documento for atualizado; a versão anterior permanece acessível no histórico público do git.
Assinatura
Este modelo de ameaças é publicado de boa-fé pelo mantenedor do Vaulted. Erros, omissões e discordâncias com as atestações acima são explicitamente bem-vindos — por favor, reporte-os para [email protected] ou por meio do programa de divulgação responsável.
Maxim Novak — mantenedor, vaulted.fyi · 2026-04-27