Segurança em qub
Data de entrada em vigor: 23 de setembro de 2026 Versão: 1.1 — revisão da precisão da implementação
Para investigadores — referência rápida:
- Para onde enviar relatórios: support@qub.social com o prefixo do sujeito
[SECURITY].- O que incluir: a vulnerabilidade, os passos para reproduzir e qualquer prova de conceito.
- A nossa resposta: reconhecemos a receção no prazo de 3 dias úteis e pretendemos enviar uma correção no prazo de 90 dias.
- Porto Seguro: não iremos tomar ações legais contra pesquisas de boa-fé que sigam as regras no §12 (sem acesso a dados que não são seus, sem degradação do serviço, sem retenção de dados obtidos para além do necessário para demonstrar o problema, conceda-nos um prazo razoável para divulgação).
Todos os detalhes estão no §12 (Divulgação Coordenada).
Quem somos
qub.social é operado por VSPRY AUSTRALIA PTY LIMITED (ABN 41 631 026 330), Level 38, 71 Eagle Street, Brisbane QLD 4000, Australia. As referências a "qub", "nós", "nos" e "nosso" referem-se a essa entidade.
Contacto de segurança: support@qub.social com o prefixo de assunto [SECURITY].
1. Nossa abordagem
qub é infraestrutura de confiança. O produto não vale nada se não for seguro, então segurança não é um recurso — é o substrato. Esta página descreve, em termos concretos, como protegemos nossa stack, seus dados e a integridade do conteúdo selado.
O valor de um compromisso temporal verificável aumenta à medida que mais da internet se torna gerada por máquinas. Uma transação de armazenamento verificada ou um âncora de registo de transparência pode estabelecer que o texto cifrado existia não mais tarde do que o seu tempo de bloco; o artefacto selado prova separadamente a integridade do conteúdo, a ligação à ronda do drand e quaisquer assinaturas de autoria. Manter essas alegações distintas é o padrão ao qual esta página se mantém.
Não pedimos que você confie em nós. Projetamos para que a confiança exigida de nós seja a menor possível e, onde a confiança é exigida, explicamos exatamente o que está a ser confiado e por quê.
Três princípios orientam cada decisão de design:
- Minimise o que o servidor pode ver. No fluxo de mensagens do navegador por defeito, o texto simples e a chave do invólucro permanecem no seu dispositivo. A selagem pelo Builder no lado do servidor, a assinatura conjunta do pacto e a recuperação explicitamente ativada têm diferentes limites de confiança, divulgados abaixo. Onde mantemos metadados, limitamo-los ao que a funcionalidade selecionada necessita.
- Faça o compromisso contido localmente. Uma violação de qualquer componente (o nosso servidor, o fornecedor de email, um nó drand) não deve revelar conteúdo selado que ainda não tenha atingido o seu tempo de revelação.
- Torne o protocolo auditável. O artefacto selado é verificável de ponta a ponta com criptografia pública. Não precisa de confiar qub o serviço para verificar um qub o artefacto.
2. Modelo de ameaças
2.1 Contra o que protegemos
- Um atacante que obtém acesso de leitura aos nossos dados armazenados no lado do servidor antes do momento de divulgação. No fluxo de navegador privado padrão, eles obtêm metadados e bytes embrulhados opacos, não texto simples ou K. Esta proteção não se aplica a um K retido explicitamente para recuperação, à entrega pública/nua após a sua ronda drand, ou ao texto simples fornecido temporariamente ao Builder
/api/v1/seale fluxos de trabalho de pact. - Um atacante que intercepta o tráfego entre o seu navegador e a nossa infraestrutura. O TLS termina na nossa borda de CDN; os conteúdos selados já estão encriptados antes do trânsito.
- Um atacante que manipula uma carga útil armazenada. Autenticação do invólucro externo (quando presente), decodificação canónica, o hash do corpo,
qub_idA re-derivação, a vinculação em volta e as assinaturas opcionais fazem com que a adulteração falhe na verificação; o visualizador recusa-se a apresentá-lo. - Um atacante que tenta vincular um email de autor forjado a uma chave de assinatura. A certificação por email requer a posse tanto da chave privada de assinatura como de um código único enviado para a caixa de entrada do email.
- Um operador de farol drand comprometido. A rede drand utiliza assinaturas BLS por limiar entre múltiplos operadores independentes; uma minoria não pode falsificar assinaturas de libertação antecipada.
2.2 Contra o que não podemos proteger
Somos honestos sobre nossos limites. qub não pode defender contra:
- Um comprometimento do seu dispositivo antes de selar. Keyloggers locais, extensões de navegador maliciosas ou acesso físico a um dispositivo desbloqueado podem capturar o texto simples no ponto de composição.
- Um colapso do limiar drand. Várias organizações independentes gerem a rede drand especificamente para tornar isto difícil, mas não é criptograficamente impossível: se operadores suficientes coludissem, poderiam obter as chaves timelock antecipadamente.
- As propriedades de lançamento de uma cópia válida. Um qub público/nu torna-se decifrável após a sua ronda drand. Um qub privado/embrulhado requer adicionalmente K; qualquer pessoa que obtenha tanto os bytes armazenados como K pode decifrar após a ronda. Registos de armazenamento permanente e de log ancorado não podem ser recuperados simplesmente removendo-os da superfície do produto do qub.
- Um adversário global que quebra a criptografia subjacente (AES-GCM, pressupostos de emparelhamento BLS12-381, SHA3-256, ML-DSA-65). Se estas primitivas caírem, o ecossistema criptográfico em geral terá problemas maiores.
3. Criptografia do lado do cliente
No fluxo de mensagens do navegador padrão, a encriptação do conteúdo ocorre antes do pedido de upload. Dois caminhos explícitos diferem: Builder /api/v1/seal envia deliberadamente texto simples e K gerado pelo chamador ao Trabalhador para selagem em memória, e o encenamento/assinatura do pacto envia o pacto estruturado assinado ao serviço para que este possa finalizar o artefacto bilateral. Nenhuma das exceções deve ser confundida com encriptação de ponta a ponta pelo caminho do navegador.
3.1 Cifragem timelock
qub usa tlock — cifragem baseada em identidade indexada a um round drand futuro. A cifragem ocorre no seu navegador usando a chave pública da rede drand; a chave de decifragem é liberada publicamente pela rede drand somente quando o round alvo é alcançado. Ninguém, incluindo nós, pode reconstruir a chave de decifragem antecipadamente.
Visamos a cadeia quicknet:
- Período de round de 3 segundos
- Modo unchained (cada round é independente)
- Assinaturas BLS12-381 G1
- Chain hash
52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971
A chave pública e o tempo de gênese da cadeia quicknet são compilados no cliente. Não obtemos parâmetros da cadeia em tempo de execução, então um nó malicioso não pode substituir uma cadeia que controlamos.
3.2 Cifragem simétrica
O esquema tlock envolve uma chave de conteúdo AES-256-GCM. AES-GCM fornece cifragem autenticada: um único bit invertido no ciphertext faz a decifragem falhar, em vez de produzir texto plano silenciosamente corrompido.
3.3 Serialização canónica
As estruturas de protocolo são serializadas utilizando CBOR determinístico (RFC 8949 §4.2 codificação determinística principal). Duas implementações que codificam a mesma estrutura lógica produzem CBOR idêntico. Os conteúdos selados completos são não determinístico: tlock e encriptação de outer-wrapper usam aleatoriedade nova. O hash do corpo é calculado sobre os bytes crus do corpo, enquanto a codificação canónica torna as estruturas circundantes assinadas/de rede inequívocas.
Escrevemos o codificador CBOR à mão para nossas implementações de cliente e servidor em vez de depender de uma biblioteca de serialização genérica — o requisito é exatidão, não ergonomia, e testes de propriedade rodam em ambas as implementações para verificar que concordam.
Um teste de regressão afirma que o formato de transmissão canónico não contém nenhuma sequência de bytes da marca qub além da chave de campo qub_id primitiva do protocolo. O formato de transmissão é intencionalmente agnóstico de marca — qualquer leitor conforme (o nosso ou de terceiros) pode renderizar qualquer qub do armazenamento permanente, independentemente de qual deployment o selou. O teste é uma armadilha que evita que uma mudança futura incorpore acidentalmente uma referência de marca em bytes que, uma vez no armazenamento permanente, não podem ser reescritos.
3.4 Hashing do body e integridade pré-revelação
Cada carga útil selada transporta um hash SHA3-256 dos seus bytes de corpo brutos. O hash está vinculado a qub_id e, quando a assinatura de autoria está ativada, na entrada da assinatura V2. Um visualizador recalcúla-a após a descriptação e rejeita uma discrepância.
O identificador de conteúdo de 32 bytes qub_id é derivado de uma pré-imagem de 108 bytes cobrindo a versão do protocolo, tipo de conteúdo, timestamps de criação e desbloqueio, timestamp de resultado opcional (ou o seu sentinela zero), ronda drand alvo, hash do corpo, e SHA3-256 do título opcional normalizado em NFC. Um gateway ou CDN não pode alterar qualquer campo vinculado de forma consistente e ainda assim passar na re-derivação. Os títulos são limitados a 100 pontos de código NFC e rejeitados para a classe partilhada de pontos de código hostis/de controlo (incluindo sobreposições bidi, caracteres de largura zero, o bloco de tags, BOM, C0, C1 e DEL).
3.5 Assinatura (ML-DSA-65)
A assinatura de autoria usa ML-DSA-65 (FIPS 204), um esquema de assinatura pós-quântico padronizado pelo NIST. Escolhemos deliberadamente uma primitiva pós-quântica para assinatura porque o conteúdo selado é permanente: uma assinatura que verifica hoje deve ainda verificar décadas a partir de agora, incluindo após computadores quânticos em larga escala se tornarem práticos.
As chaves de assinatura são geradas no navegador. O segredo local é encapsulado sob uma chave WebCrypto não extraível antes de ser armazenado no IndexedDB. Se a funcionalidade de recuperação entre dispositivos com escopo de conta for utilizada, um blob de chave portátil encriptado com AEAD é armazenado no servidor; o seu texto cifrado da chave secreta está associado ao ID de conta imutável, e o serviço valida o envelope público, mas não consegue decifrar o material secreto. Os bytes da chave privada bruta não são enviados para o servidor. As chaves públicas e os registos de atestação são armazenados para verificação e exibição de identidade.
A mesma decifragem tlock no navegador aplica-se dentro do embed do qub: quando um qub selado é renderizado através de <qub-embed> numa página de terceiros, a decifragem ainda acontece no iframe do embed no navegador do leitor. O embed não muda o modelo de confiança — texto plano nunca é decifrado num servidor do qub.
3.6 Atribuição pública — Opcional
Os qubs selados não carregam nenhum ponteiro on-chain ao seu criador a menos que o criador escolha explicitamente anexar um. Quando você sela um qub, o app de referência emite uma tag de armazenamento Author (um fingerprint hex de 64 caracteres da sua chave pública de assinatura) somente quando "Atribuição pública" está ativada no passo do seletor de data. Com o toggle desativado — a predefinição — nenhuma tag Author é gravada e o qub fica não atribuído no armazenamento permanente: nada no armazenamento vincula o upload ao seu handle, ao seu e-mail ou aos seus outros qubs. Com o toggle ativado, o fingerprint resolve para o seu @handle via a cadeia de atestação em §6.3 / §10 e a contagem decrescente do leitor mostra "Selado por @{handle}" antes da revelação.
Esta é uma proteção deliberada contra o risco de enumeração que uma tag Author sempre ativa criaria: um terceiro que aprende o fingerprint de um criador poderia, de outra forma, varrer o armazenamento permanente pela tag e reconstruir a saída histórica completa daquele criador. A atribuição opcional fecha esse canal — apenas os qubs que o criador escolhe explicitamente atribuir aparecem sob um fingerprint no armazenamento permanente.
A página de perfil /u/{handle} é um cartão de identidade verificada — handle, nome para exibição opcional + URL, pílula de "e-mail verificado" (sem endereço), e a forma curta do fingerprint criptográfico. Não lista os qubs de um criador. Visitantes que querem ver um qub específico de um criador seguem a URL de entrega daquele qub diretamente.
3.7 Invólucro externo de cifragem
Mesmo depois de a descodificação com bloqueio temporal ser matematicamente possível — uma vez que a assinatura drand para a ronda vinculada tenha sido publicada — a camada canónica de bloqueio temporal sozinha permitiria a um indexador descodificar em massa os qubs descobráveis. A entrega privada fecha esse canal com uma camada simétrica adicional em torno dos bytes codificados com bloqueio temporal (Protocolo §13). A entrega pública omite intencionalmente o invólucro para que a notificação, incorporação e os links de descoberta possam funcionar sem um fragmento secreto.
O invólucro usa AES-256-GCM, uma cifra autenticada padronizada pelo NIST, com uma chave K nova de 256 bits gerada por qub pelo CSPRNG do seu navegador. K está vinculado ao qub_id do qub como dado adicional autenticado, então uma chave de um qub não pode ser reutilizada para decifrar um qub diferente.
K nunca chega aos nossos servidores no fluxo de navegador privado padrão. Está codificado no fragmento de URL do link de partilha (https://qub.social/c/<tx_id>#<base64url(K)>). Os navegadores não transmitem fragmentos de URL para os servidores—o RFC 3986 coloca o fragmento fora do pedido—portanto, qub.social, gateways de armazenamento, CDNs e monitorização de pedidos não conseguem ver K nesse fluxo. O armazenado OuterWrapper é CBOR estruturado reconhecível, mas o seu campo de texto cifrado autenticado esconde o interior SealedQub estrutura e não pode ser aberta sem K.
Consequências líquidas:
- qub.social não consegue descodificar selos privados do navegador padrão apenas com os dados armazenados. Uma violação de armazenamento de dados alcança texto cifrado opaco sem K. Qubs públicos e qubs com recuperação habilitada têm exposição diferente por design.
- A perda de fragmentos é irrecuperável sem um canal de recuperação optado. Se guardar um link privado sem o fragmento e não tiver ativado a recuperação, o qub torna-se ilegível através desse link. O fluxo de selo apresenta uma divulgação explícita 'guarde este URL' por este motivo.
- Recuperação mediante opção. Quando opta por receber emails do ciclo de vida do criador para um qub E o email corresponde à sua identidade verificada, aceitamos K com o upload, armazenamos a URL completa de entrega no registo de histórico selado da sua identidade e usamos essa URL como o link no email de confirmação do selo. Esta troca — um canal de recuperação do lado do servidor em troca de alguma pureza de ponta a ponta — acontece apenas mediante opt-in explícito e apenas para esse qub. A postura padrão é a destruição criptográfica.
O endpoint do lado do servidor /api/v1/seal do Worker (usado por agentes de IA e outros chamadores de API) exige que o chamador gere K com um CSPRNG, a retenha localmente e a forneça como wrapper_key_b64url. O Worker vê necessariamente tanto o texto plano como K em memória neste caminho explicitamente confiável, mas não persiste nenhum dos dois. Um Idempotency-Key obrigatório impede que uma resposta perdida crie um segundo qub faturado, enquanto o K retido pelo chamador pode ser combinado com a URL sem fragmento repetida. Isto difere do caminho de navegador padrão, em que K nunca chega ao Worker a menos que o criador ative explicitamente a recuperação.
4. Transporte e edge
4.1 TLS
O tráfego do navegador para o qub é servido via HTTPS na interface da Cloudflare. As respostas definem o HTTP Strict Transport Security (max-age=63072000; includeSubDomains; preload). A versão exacta de TLS negociada e o conjunto de cifras são governados pela configuração activa da borda, em vez de serem definidos pelo código da aplicação. Não expomos um servidor de origem acessível separadamente.
4.2 Segurança de conteúdo
O cliente compilado é servido com cabeçalhos estritos de content-type e cache. O shell do SPA é uma origem única. Não embutimos scripts de terceiros para analytics ou publicidade. Os dois pontos de contacto com terceiros no produto são ambos estritamente delimitados: o fluxo de compra deixa o SPA inteiramente com um redirecionamento de página inteira para o checkout alojado pelo Stripe (https://checkout.stripe.com/…) — a UI do Stripe nunca executa na nossa origem e nunca vemos dados de cartão — e o fluxo de selo carrega o widget Turnstile do Cloudflare, uma alternativa de CAPTCHA respeitosa com a privacidade que o Cloudflare renderiza dentro do seu próprio iframe sandboxed. Nenhuma das partes pode ler o resto da página.
O qub inserir iframe (servido a partir de qub.social/embed/{tx_id} e carregado em sites de terceiros por embed.js) possui a sua própria Política de Segurança de Conteúdo. A sua connect-src lista de permissões é 'self', https://qub.social, https://arweave.net, https://ar-io.dev, https://permagate.io, https://api.drand.sh, e https://drand.cloudflare.com. O iframe funciona com sandbox="allow-scripts allow-top-navigation-by-user-activation" (não allow-same-origin): a página anfitriã não pode ler o seu DOM, e não pode navegar pela anfitriã exceto após uma ação do utilizador.
4.3 CORS e âmbito de fetch
O cliente do navegador faz pedidos fetch apenas para:
- A nossa própria API (
api.qub.sociale equivalentes de encenação) - Passagens de armazenamento (somente leitura, para recuperação de bytes privados encapsulados ou públicos simples — §3.6)
- pontos de extremidade drand beacon (somente leitura, para assinaturas de ronda de tempo de revelação)
Os destinos do embed são aplicados pelo seu CSP. Os destinos pretendidos da SPA principal estão fixos no código e na configuração e são verificados pelo navegador e pelos testes de integração; a Integridade de Subrecursos não é um controlo de destino de rede.
O embed busca bytes armazenados através das origens qub/storage na lista de permissões, desembrulha cargas úteis privadas no navegador usando K a partir do fragmento da sua URL, e busca assinaturas de rondas em tempo de revelação das duas origens drand na lista de permissões. O SPA principal usa o conjunto de fallback de quatro endpoints definido em config/drand-endpoints.json (drand.cloudflare.com, api.drand.sh, api2.drand.sh, e api3.drand.sh) para que uma falha de um endpoint não bloqueie a revelação. O CSP incorporado nega conexões fora da sua lista explícita.
5. Infraestrutura do lado do servidor
5.1 Edge serverless
Nossa API roda inteiramente num runtime serverless gerido no edge. Não há VMs, nem containers, nem processos de servidor persistentes que administremos. Isto reduz drasticamente a superfície de ataque pela qual somos responsáveis: não rodamos um SO, um servidor web, ou um runtime de aplicação que devamos atualizar.
Aplica-se um middleware público-CORS separado Access-Control-Allow-Origin: * para o seguinte conjunto de caminhos implementados: /embed.js, /embed/v1.js, tudo abaixo /embed/; /api/v1/telemetry; /api/v1/openapi.json; tudo abaixo /api/v1/qub/ (incluindo bytes, metadados, prova, envolvimento, notificação e subrotas de envio); tudo debaixo de /api/v1/log/; pesquisas de identificadores públicos sob /api/v1/handle/; e o avatar público lê por baixo /api/v1/identity/avatar/. As suas autorizações de pré-voo GET, POST, e OPTIONS com o Content-Type cabeçalho de pedido. Esta superfície baseada em prefixo é mais ampla do que apenas as chamadas que a incorporação faz atualmente, por isso cada manipulador abaixo desses prefixos deve continuar a aplicar a sua própria validação, autenticação, limites de taxa e controlos de abuso. Outros caminhos de API mantêm a política CORS qub.social-restricted.
5.2 Armazenamento
- Armazenamentos de metadados e coordenação manter registos de identidade e de atestação, direitos e referências de faturação, registos de chave API, entradas em listas de negação, sessões, estado de idempotência, filas e estado de limite de taxa / concorrência. Diferentes necessidades de consistência usam KV, D1 e Objetos Duráveis em vez de uma loja universal.
- A nossa loja de objetos é também um substrato de durabilidade. Ele mantém os bytes qub exatos, embrulhados ou nus, reconhecidos pelo upload, folhas do log de transparência e nós Merkle com chave de coordenadas, material de ancoragem, registos de eventos estruturados e caches de resposta/metadados.
- Armazenamento público permanente mantém âncoras de registo de transparência e, para o caminho T3 ou publicação diferida, transações qub individuais. Nós não operamos essa rede. Os conteúdos privados do navegador permanecem opacos aí, a menos que o titular também possua K; os conteúdos públicos/brutos deliberadamente não têm essa camada extra de capacidade de ligação.
O fluxo de mensagens do navegador por defeito não mantém texto simples na infraestrutura qub. Construtor /api/v1/seal manipula texto simples e K na memória, mas não persiste nenhum dos dois. O staging do Pact armazena necessariamente o pact estruturado assinado até que seja co-assinado, retirado ou expirado. A recuperação opcional armazena uma capacidade de entrega (o link completo com fragmento) para que possa ser recuperada mais tarde. Portanto, não descrevemos todo o nível de armazenamento como “apenas metadados.”
5.3 Segredos
Segredos (carteiras de assinatura, tokens de fornecedor e chaves HMAC) são fornecidos através de ligações de segredos/ambiente da plataforma em vez de controlo de código-fonte. Os componentes em execução recebem apenas as ligações de que precisam. Os procedimentos de rotação e sobreposição são específicos de cada componente; não afirmamos a existência de um único mecanismo universal de rotação automática ou auditada.
5.4 Logging e telemetria
Logs JSON estruturados são gravados em cada pedido da API com um ID de correlação exposto no cabeçalho de resposta X-Request-Id. A telemetria do cliente é anónima — sem identificador de dispositivo, sem endereço IP, sem prévia de conteúdo. Os eventos são bufferizados em memória e despejados na base de melhor esforço; um despejo falhado é descartado, não tentado novamente. A telemetria é projetada para ser desativável na camada de rede sem afetar o produto.
6. Autenticação
6.1 Login por magic-link
O início de sessão utiliza um token de uso único, assinado com HMAC, enviado para a sua caixa de correio eletrónico. O link é válido durante 15 minutos e o resgate é reclamado de forma atómica, de modo que o uso em simultâneo ou repetido falha de forma segura. Em caso de sucesso, o navegador recebe um opaco __Host-qub_session biscoito com Secure, HttpOnly, SameSite=Strict, e Path=/ atributos.
As sessões têm um limite de inatividade de 30 dias e um limite absoluto de 90 dias, rotacionam após 24 horas e aceitam apenas a geração imediatamente anterior durante um período de tolerância de 120 segundos para respostas perdidas. As alterações sensíveis da conta requerem autenticação nos 10 minutos precedentes. O segredo de assinatura HMAC é uma ligação à plataforma; uma leitura apenas de metadados não cria por si só um token válido.
6.2 Chaves de API (plano Developer)
As chaves de API do desenvolvedor usam o prefixo qub_sk_ para fácil reconhecimento e grepabilidade. Cada chave:
- Está ligado a uma conta, a escopos, e a uma lista de permissões de IP CIDR opcional
- É mostrado em forma bruta uma vez; os registos persistentes retêm o seu hash SHA-256, não o segredo do portador
- Pode ser rodado com um mapeamento de tolerância de uma hora no qual a chave antiga é resolvida para o substituto
- Tem quota independente e estado de limitação de taxa
- Nunca é registado na totalidade; os registos armazenam apenas o identificador chave
Os endpoints de gestão de chaves admin estão protegidos atrás de uma credencial admin separada.
6.3 Atestação de e-mail (assinatura de autoria)
Vincular um endereço de e-mail a uma chave de assinatura exige:
- Posse da chave de assinatura privada (você assina um desafio)
- Posse da caixa de entrada de e-mail (você insere um código de 6 dígitos entregue por e-mail)
Qualquer um sozinho é insuficiente. A revogação é um registo assinado na sua própria conta e tem efeito imediato; os leitores que consultam a atestação veem o estado revogado e exibem em conformidade.
7. Pagamentos
A introdução e o processamento de cartões são realizados no checkout hospedado pela Stripe. Nunca recebemos números de cartão, datas de validade ou CVCs. Armazenamos, no entanto, identificadores de clientes e subscrições da Stripe, estado da subscrição e dados de período em registos de direitos/chave API para que o acesso, renovações, medição, cancelamento e reembolsos possam ser conciliados. As declarações de privacidade e segurança da Stripe regem a forma como ela trata os dados de pagamento.
O endpoint de selo verifica de forma cruzada o registo de direitos contra o identificador de dispositivo e, para utilizadores autenticados, contra a identidade vinculada. Um direito não pode ser reutilizado entre dispositivos sem o utilizador explicitamente restaurá-lo via login por magic-link.
8. Resistência a abuso
8.1 Deteção de bots
O fluxo de selo é protegido por uma alternativa de CAPTCHA respeitosa com a privacidade que não usa cookies para rastreamento e não faz fingerprint para publicidade. Um desafio falhado é rejeitado pelo nosso edge Worker antes que qualquer processamento do lado do selo aconteça.
8.2 Rate limiting
Os rate limits são aplicados em várias camadas:
- Limites por IP e por chave nos endpoints de selo, leitura e auth
- Limites por e-mail nos pedidos de magic-link (impede inundação de caixa de entrada)
- Limites por contraparte nos e-mails de convite de pacto (dez por endereço de destinatário por dia UTC, a principal mitigação de spam-relay; pactos honestos quase nunca se aproximam do limite)
- Limites por IP na submissão de telemetria
Contadores e reivindicações atómicas são distribuídos pelo KV, Objetos Duráveis e ligações de limitação de taxa da plataforma de acordo com os requisitos de consistência do endpoint. As requisições com limite de taxa devolvem 429; os endpoints que podem calcular uma janela de nova tentativa incluem Retry-After.
8.3 Moderação de conteúdo
A rota de upload do navegador por defeito não consegue analisar o corpo: recebe apenas o artefacto selado pelo cliente. O Construtor /api/v1/seal o percurso vê o texto simples de forma transitória, e a preparação do pacto mantém os termos estruturados até à finalização, mas essas exceções de confiança não transformam o caminho de carregamento geralmente cego a bytes num scanner de conteúdo. A moderação operacional é uma lista de negação no nível do visualizador: um qub na lista de negações é recusado pelo nosso visualizador independentemente de o payload armazenado continuar acessível. Colocar na lista de negações não retira bytes duráveis, entradas no registo de transparência ou dados de rede permanentes já publicados.
As denúncias de abuso têm rate limit usando um hash unidirecional do IP do denunciante; não armazenamos IPs em claro para esse propósito.
9. Cadeia de suprimentos e integridade do build
9.1 Pinagem do toolchain
As versões do compilador e do tempo de execução estão fixadas na configuração do repositório e as dependências são resolvidas através de ficheiros de bloqueio comprometidos. O CI verifica a atualidade dos ficheiros gerados e invariantes sensíveis à reprodutibilidade. Não fazemos a afirmação mais forte de que cada compilação limpa seja bit a bit idêntica em todas as máquinas suportadas.
9.2 Lints e análise estática
O workspace ativa os nossos grupos de lint mais estritos no nível deny. CI trata cada warning — incluindo warnings de doc-link — como uma falha de build. Isto é deliberado: usamos a estrita lintagem como uma armadilha para regressões sutis.
9.3 Gates de CI
O fluxo de trabalho de CI cobre formatação e lints rigorosos; testes de Rust, WASM/browser, Worker, embed e API; verificação de tipos; cobertura de código; verificação de mutações/invariantes; análise estática de dependências e fluxo de trabalho; verificação de chaves i18n, cobertura, desvio e pontos de código hostis; frescura de documentação gerada/API/base de conhecimento; inventário de documentos e verificação de links internos; orçamentos de folhas de estilo e pacotes; e validação OpenAPI. Alguns trabalhos de mutação dispendiosos são agendados em vez de serem executados em cada push.
Um único necessário ci O roll-up permanece vermelho se algum trabalho necessário falhar. Os fluxos de trabalho de branch protegida e de deploy consomem esse resultado em vez de duplicar uma verificação de segurança menor.
9.4 Teste de mutação
Um job semanal roda teste de mutação contra os módulos puros críticos para a segurança: hashing, CBOR canónico, seal, unlock, os newtypes do formato de transmissão, os validadores de tipo de protocolo, e o namespace de handle. O teste de mutação responde "nossa suíte de testes captura código sutilmente errado?" — se uma implementação mutada ainda passar em todos os testes, sabemos que temos uma lacuna de cobertura de teste e a abordamos.
9.5 Git hooks
Hooks locais (pre-commit, pre-push) espelham os gates de CI para que regressões sejam capturadas antes de saírem da máquina do desenvolvedor. Os hooks são instalados via um script do repositório; não são contornados em nosso fluxo de trabalho e o CI é o gate autoritativo se forem ignorados.
10. Testes
O código crítico para a segurança carrega três tipos de testes:
- Testes unitários verificam o comportamento esperado em entradas conhecidas, incluindo vetores de teste derivados da especificação do protocolo.
- Testes de propriedade geram milhares de entradas arbitrárias e afirmam invariantes: round-trips de CBOR canónico, round-trips de verificação de assinatura, predicados de vinculação de e-mail, determinismo de reconhecimento de pacto.
- Testes entre implementações verificam que nossas implementações de cliente e servidor concordam byte-a-byte sobre as codificações canónicas. Isto captura a divergência entre as duas implementações antes que ela alcance a produção.
11. Higiene de branches e releases
Ramos de funcionalidades avançam staging apenas através de um pedido de pull do Gate 1: obrigatório ci verde, sem pedidos de alteração por resolver, sem conflitos de fusão e uma árvore limpa e revista; a fusão é do tipo 'squash-and-delete'. main avança apenas através do Portão 2 staging → main pull request e preserva a ancestralidade com um commit de merge. Os pushs diretos para a branch não são o fluxo de trabalho de release.
As implementações de staging e produção são acionadas a partir do correspondente protegido staging e main os ramos de estados após a CI. O código do pull request e as credenciais do fork não recebem segredos de deploy.
Os segredos usados em workflows de deploy são limitados ao ambiente de deploy pela nossa plataforma de CI. Eles não estão disponíveis para workflows de pull-request de forks.
12. Divulgação coordenada
Se você acredita que encontrou uma vulnerabilidade de segurança no qub, queremos saber rapidamente e nos comprometemos a tratar o relatório profissionalmente.
- Envie um e-mail para
support@qub.socialcom o prefixo de assunto[SECURITY]. - Descreva a vulnerabilidade, os passos para reproduzir e qualquer prova de conceito.
- Dê-nos uma janela razoável de divulgação (tipicamente 90 dias) antes de tornar público.
- Não aceda a dados que não lhe pertencem, não degrade o serviço para outros utilizadores, nem retenha dados obtidos durante a pesquisa além do necessário para demonstrar o problema.
Acusamos recebimento em até três dias úteis e o mantemos informado à medida que investigamos. Com seu consentimento, creditamos os relatores nas notas de release.
12.1 Safe Harbor
Se sua pesquisa segue as regras acima (investigação de boa-fé, sem dano a outros utilizadores ou ao serviço, janela razoável de divulgação), não tomaremos ação legal contra você, e não pediremos que a aplicação da lei o faça. Tratamos seu trabalho como teste autorizado e preferimos que você encontre o bug a alguém mais.
Este Safe Harbor aplica-se a:
- Pesquisa no serviço ao vivo qub.social (não em fixtures de teste que publicamos para esse fim).
- Engenharia reversa dos nossos binários publicados e dos crates qub-core / qub-app de código aberto.
- Qualquer classe de vulnerabilidade — protocolo, aplicação, infraestrutura, cadeia de suprimentos — que afete qub.
Não se aplica à engenharia social de membros da equipa qub, testes de negação de serviço, ou acesso a dados de outros utilizadores além do necessário para demonstrar o problema. Se você não tem certeza se algo cai dentro do Safe Harbor, pergunte primeiro usando o mesmo prefixo de assunto [SECURITY].
13. Limitações honestas
A segurança é uma prática, não um estado. Algumas limitações merecem ser nomeadas diretamente:
- Somos uma equipa pequena. Nossa profundidade de revisão não corresponde à da função dedicada de segurança de aplicação de uma grande corporação. Compensamos com gates automatizados rigorosos e uma superfície de ataque mínima, mas não reivindicamos infalibilidade.
- A permanência do armazenamento permanente é uma porta de mão única. Se um erro fizer com que o conteúdo selado se torne decifrável mais cedo do que o pretendido, não podemos desfazê-lo. Tratamos o fluxo de selo com cuidado correspondente.
- A rede drand é uma dependência externa. Uma falha catastrófica de drand afetaria o comportamento de revelação de cada qub. Monitoramos a saúde do drand e temos documentação de contingência para a migração de cadeia se necessário. Para datas de desbloqueio a mais de 2 anos, o modal de confirmação no momento do selo mostra uma divulgação explícita: qubs de horizonte longo dependem da durabilidade da cadeia drand, e uma migração futura da cadeia drand pode exigir passos de recuperação para desbloquear o qub. Para datas de desbloqueio a mais de 5 anos, você deve marcar uma caixa adicional confirmando que leu e aceita esse risco antes que o selo prossiga.
- As primitivas criptográficas das quais dependemos são padronizadas e amplamente revisadas, mas a cifragem evolui. Onde temos escolhas (assinatura pós-quântica, cifragem autenticada), escolhemos a opção mais conservadora.
14. Mudanças nesta página
Mudanças materiais são notadas atualizando a data de entrada em vigor no topo. Quando uma mudança reflete uma melhoria concreta de segurança, descrevemo-la brevemente no changelog público. Quando uma mudança reflete uma clarificação de política, descrevemos o que mudou e por quê.
Para perguntas sobre qualquer coisa nesta página, envie um e-mail para support@qub.social com o prefixo de assunto [SECURITY].
15. Registo de mudanças
| Versão | Data de vigência | Resumo |
|---|---|---|
| 1.1 | 23 de setembro de 2026 | Conciliou reivindicações criptográficas, modos de entrega, armazenamento, CSP, sessões, chaves de API, pagamentos, CI e fluxo de trabalho de lançamento com o sistema implementado. |
| 1,0 | 2 de maio de 2026 | Publicação inicial. |