Beveiliging bij qub
Ingangsdatum: 23 september 2026 Versie: 1.1 — beoordeling van de implementatienauwkeurigheid
Voor onderzoekers — snelle referentie:
- Waar rapporten naartoe te sturen: support@qub.social met het onderwerpvoorvoegsel
[SECURITY].- Wat te opnemen: de kwetsbaarheid, stappen om te reproduceren, en enig bewijs-van-concept.
- Ons antwoord: We bevestigen de ontvangst binnen 3 werkdagen en streven ernaar een oplossing binnen 90 dagen te verzenden.
- Veilige haven: we zullen geen juridische stappen ondernemen tegen goedbedoeld onderzoek dat de regels in §12 volgt (geen toegang tot gegevens die niet van jou zijn, geen verslechtering van de dienst, geen opslag van verkregen gegevens langer dan nodig is om het probleem aan te tonen, geef ons een redelijke bekendmakingsperiode).
Volledige details staan in §12 (Gecoördineerde openbaarmaking).
Wie wij zijn
qub.social wordt geëxploiteerd door VSPRY AUSTRALIA PTY LIMITED (ABN 41 631 026 330), Level 38, 71 Eagle Street, Brisbane QLD 4000, Australië. Verwijzingen naar "qub", "wij", "ons" en "onze" betreffen die entiteit.
Beveiligingscontact: support@qub.social met het onderwerpvoorvoegsel [SECURITY].
1. Onze aanpak
qub is vertrouwensinfrastructuur. Het product is waardeloos als het niet veilig is, dus beveiliging is geen feature — het is het substraat. Deze pagina beschrijft, in concrete termen, hoe wij onze stack, je gegevens en de integriteit van verzegelde inhoud beschermen.
De waarde van een verifieerbare temporele verplichting groeit naarmate een groter deel van het internet door machines wordt gegenereerd. Een geverifieerde opslagtransactie of transparantieloganker kan aantonen dat ciphertekst niet later dan de bloktijd bestond; het verzegelde artefact bewijst afzonderlijk de inhoudsintegriteit, drand-ronde binding en eventuele auteurschaphandtekeningen. Het gescheiden houden van deze beweringen is de norm waaraan deze pagina wordt gehouden.
Wij vragen je niet ons te vertrouwen. Wij ontwerpen zo dat het vertrouwen dat van ons wordt verlangd, zo klein mogelijk is, en waar vertrouwen wordt verlangd, leggen we precies uit wat wordt vertrouwd en waarom.
Drie principes drijven elke ontwerpbeslissing:
- Minimaliseer wat de server kan zien. In de standaard browser-berichtstroom blijven platte tekst en de wrapper-sleutel op uw apparaat. Server-side Builder-sealing, pact co-signing en expliciet ingeschakelde herstelmogelijkheden hebben verschillende vertrouwensgrenzen, hieronder bekendgemaakt. Waar wij metadata bewaren, beperken we dit tot wat de geselecteerde functie nodig heeft.
- Maak compromis lokaal beperkt. Een schending van een van de componenten (onze server, de e-mailprovider, een drand-knooppunt) mag geen verzegelde inhoud onthullen die nog niet het tijdstip van openbaring heeft bereikt.
- Maak het protocol controleerbaar. Het verzegelde artefact is van begin tot eind verifieerbaar met openbare cryptografie. Je hoeft geen vertrouwen te hebben qub de dienst om een te verifiëren qub het artefact.
2. Dreigingsmodel
2.1 Waar we tegen beschermen
- Een aanvaller die leesrechten krijgt op onze opgeslagen servergegevens voordat de onthullingstijd. In de standaard private browserstroom verkrijgen ze metadata en ondoorzichtige ingepakte bytes, niet platte tekst of K. Deze bescherming is niet van toepassing op een K die expliciet wordt behouden voor herstel, op openbare/naakte levering na de drand-ronde, of op platte tekst die tijdelijk aan de Builder wordt geleverd
/api/v1/sealen pact-workflows. - Een aanvaller die het verkeer tussen uw browser en onze infrastructuur onderschept. TLS wordt beëindigd bij onze CDN-edge; verzegelde payloads zijn al versleuteld voordat ze worden verzonden.
- Een aanvaller die een opgeslagen payload manipuleert. Authenticatie van de buitenste verpakking (indien aanwezig), canonieke decodering, de body-hash,
qub_idHerafleiding, rondebinding en optionele handtekeningen zorgen ervoor dat manipulatie de verificatie laat mislukken; de kijker weigert het weer te geven. - Een aanvaller die probeert een vervalst auteursemailadres aan een ondertekeningssleutel te koppelen. E-mailattestatie vereist het bezit van zowel de privéondertekeningssleutel als een eenmalige code die naar de e-mailinbox wordt gestuurd.
- Een gecompromitteerde drand-beaconoperator. Het drand-netwerk gebruikt drempel BLS-handtekeningen over meerdere onafhankelijke operators; een minderheid kan geen vroegtijdige handtekeningen vervalsen.
2.2 Waar wij niet tegen kunnen beschermen
Wij zijn eerlijk over onze grenzen. qub kan niet verdedigen tegen:
- Een compromis van uw apparaat voordat u het verzegelt. Lokale keyloggers, kwaadaardige browserextensies of fysieke toegang tot een ontgrendeld apparaat kunnen platte tekst vastleggen op het moment van samenstelling.
- Een instorting van de drand-drempel. Meerdere onafhankelijke organisaties beheren het drand-netwerk specifiek om dit moeilijk te maken, maar het is cryptografisch niet onmogelijk: als genoeg operators samenspannen, zouden ze timelocksleutels vroegtijdig kunnen afleiden.
- De vrijgave-eigenschappen van een geldig exemplaar. Een publieke/blote qub wordt ontsleutelbaar na zijn drand-ronde. Een privé/ingepakte qub vereist daarnaast K; iedereen die zowel de opgeslagen bytes als K verkrijgt, kan na de ronde ontsleutelen. Permanente-opslag en verankerde-logboeken kunnen niet simpelweg worden opgeroepen door ze van het qub-productoppervlak te verwijderen.
- Een wereldwijde tegenstander die de onderliggende cryptografie doorbreekt (AES-GCM, BLS12-381 koppelingsveronderstellingen, SHA3-256, ML-DSA-65). Als deze primitieven falen, heeft het cryptografische ecosysteem in het algemeen grotere problemen.
3. Cliëntzijdige cryptografie
In de standaard browser-berichtstroom vindt inhoudscodering plaats voordat het uploadverzoek wordt gedaan. Twee expliciete paden verschillen: Builder /api/v1/seal stuurt opzettelijk platte tekst en door de beller gegenereerde K naar de Worker voor in-memory sealing, en pact staging/co-signing stuurt het ondertekende gestructureerde pact naar de service zodat deze het bilaterale artefact kan afronden. Geen van beide uitzonderingen mag worden aangezien voor end-to-end encryptie via het browserpad.
3.1 Timelock-versleuteling
qub gebruikt tlock — identity-based versleuteling gekoppeld aan een toekomstige drand-beacon-ronde. Versleuteling vindt plaats in je browser met behulp van de openbare sleutel van het drand-netwerk; de ontsleutelsleutel wordt openbaar vrijgegeven door het drand-netwerk pas wanneer de doelronde wordt bereikt. Niemand, inclusief wij, kan de ontsleutelsleutel van tevoren reconstrueren.
Wij richten ons op de quicknet-keten:
- rondeperiode van 3 seconden
- Unchained mode (elke ronde is onafhankelijk)
- BLS12-381 G1-handtekeningen
- Chain-hash
52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971
De openbare sleutel en het genesismoment van de quicknet-keten zijn in de client gecompileerd. Wij halen geen ketenparameters op tijdens runtime, dus een kwaadaardige node kan geen keten substitueren die wij beheersen.
3.2 Symmetrische versleuteling
Het tlock-schema wikkelt een AES-256-GCM-inhoudssleutel. AES-GCM biedt geauthenticeerde versleuteling: één omgedraaide bit in de ciphertext zorgt ervoor dat ontsleuteling mislukt, in plaats van stilletjes verminkte platte tekst te produceren.
3.3 Canonieke serialisatie
Protocolstructuren worden geserialiseerd met deterministische CBOR (RFC 8949 §4.2 kern deterministische codering). Twee implementaties die dezelfde logische structuur coderen, produceren identieke CBOR. Volledige verzegelde payloads zijn niet deterministisch: tlock en outer-wrapper encryptie gebruiken verse willekeurigheid. De body-hash wordt berekend over de ruwe body-bytes, terwijl canonieke codering de omliggende ondertekende/wire structuren ondubbelzinnig maakt.
Wij hebben de CBOR-encoder met de hand geschreven voor zowel onze client- als server-implementaties in plaats van te vertrouwen op een generieke serialisatiebibliotheek — de eis is exactheid, geen ergonomie, en propertytests draaien in beide implementaties om te verifiëren dat ze overeenstemmen.
Een regressietest stelt vast dat het canonieke wire-formaat geen qub-merkbyte-sequentie bevat buiten de protocol-primitive qub_id-veldsleutel. Het wire-formaat is bewust merk-agnostisch — elke conforme lezer (van ons of van een derde) kan elke qub uit de permanente opslag renderen, ongeacht welke implementatie hem heeft verzegeld. De test is een struikeldraad die voorkomt dat een toekomstige wijziging per ongeluk een merkreferentie inbakt in bytes die, eenmaal in de permanente opslag, niet kunnen worden herschreven.
3.4 Body-hashing en pre-onthul-integriteit
Elke verzegelde payload bevat een SHA3-256-hash van zijn rauwe body-bytes. De hash is ingebonden in qub_id en, wanneer auteurschap ondertekening is ingeschakeld, in de V2-handtekeninginvoer. Een viewer rekent het opnieuw uit na ontsleuteling en wijst een mismatch af.
De 32-byte inhoudsidentificatie qub_id is afgeleid van een 108-byte preimage die de protocolversie, inhoudstype, aanmaak- en ontgrendelings-tijdstempels, optioneel uitkomsttijdstempel (of het nul-sentinel), doel drand-ronde, body-hash en SHA3-256 van de optionele NFC-genormaliseerde titel omvat. Een gateway of CDN kan geen enkel gebonden veld consistent wijzigen en toch de herafleiding doorstaan. Titels zijn beperkt tot 100 NFC-codepunten en worden geweigerd voor de gedeelde hostiele/control-codepointklasse (inclusief bidi-overschrijvingen, nulbreedtekarakters, het tagblok, BOM, C0, C1 en DEL).
3.5 Ondertekenen (ML-DSA-65)
Auteursondertekening gebruikt ML-DSA-65 (FIPS 204), een door NIST gestandaardiseerd post-quantum handtekeningschema. Wij hebben bewust een post-quantum-primitief gekozen voor ondertekenen omdat verzegelde inhoud permanent is: een handtekening die vandaag verifieert moet decennia later ook nog verifiëren, zelfs nadat grootschalige quantumcomputers praktisch zijn geworden.
Ondertekeningssleutels worden in de browser gegenereerd. Het lokale geheim wordt ingepakt onder een niet-uittrekbare WebCrypto-sleutel voordat het in IndexedDB wordt opgeslagen. Als de accountspecifieke cross-device hersteloptie wordt gebruikt, wordt een AEAD-versleutelde draagbare sleutelblob server-side opgeslagen; de ciphertext van de geheime sleutel is gekoppeld aan de onveranderlijke account-id, en de service valideert de publieke envelop maar kan het geheime materiaal niet ontsleutelen. Ruwe privésleutelbytes worden niet naar de server gestuurd. Publieke sleutels en attestatiegegevens worden opgeslagen voor verificatie en identiteitsweergave.
Dezelfde in-browser tlock-ontsleuteling geldt binnen de qub-embed: wanneer een verzegelde qub wordt gerenderd via <qub-embed> op een pagina van een derde, vindt ontsleuteling nog steeds plaats in de embed-iframe in de browser van de lezer. De embed verandert het vertrouwensmodel niet — platte tekst wordt nooit ontsleuteld op een qub-server.
3.6 Openbare attributie — opt-in
Verzegelde qubs dragen geen on-chain verwijzing naar hun maker tenzij de maker er uitdrukkelijk voor kiest er één toe te voegen. Wanneer je een qub verzegelt, geeft de referentie-app alleen een Author opslagtag uit (een hex-fingerprint van 64 tekens van je openbare ondertekensleutel) wanneer "Openbare attributie" is ingeschakeld op de datumkiezerstap. Met de schakelaar uit — de standaard — wordt geen Author-tag geschreven en is de qub niet-geattribueerd in de permanente opslag: niets in de opslag koppelt de upload aan je handle, je e-mail of je andere qubs. Met de schakelaar aan wordt de fingerprint via de attestatieketen in §6.3 / §10 omgezet naar je @handle en toont de lezer-countdown "Verzegeld door @{handle}" vóór de onthulling.
Dit is een bewuste bescherming tegen het enumeratierisico dat een altijd-aan Author-tag zou creëren: een derde die de fingerprint van een maker leert, zou anders de permanente opslag kunnen doorzoeken op de tag en de volledige historische output van die maker kunnen reconstrueren. Opt-in-attributie sluit dat kanaal — alleen qubs die de maker uitdrukkelijk kiest te attribueren verschijnen onder een fingerprint in de permanente opslag.
De /u/{handle}-profielpagina is een geverifieerde-identiteit-kaart — handle, optionele weergavenaam + URL, "geverifieerde e-mail"-pil (geen adres) en de korte vorm van de cryptografische fingerprint. Hij somt de qubs van een maker niet op. Bezoekers die een specifieke qub van een maker willen zien, volgen direct de bezorglink van die qub.
3.7 Buitenste versleutelingswrapper
Zelfs nadat timelock-decryptie wiskundig mogelijk is—zodra de drand-handtekening voor de gebonden ronde is gepubliceerd—zou de canonical timelock-laag alleen een indexer in staat stellen om bulk-decryptie van ontdekbare qubs uit te voeren. Private levering sluit dat kanaal met een extra symmetrische laag rond de timelock-geëncrypteerde bytes (Protocol §13). Publieke levering laat de wrapper opzettelijk weg zodat notificatie-, embed- en ontdekkingslinks kunnen werken zonder een geheim fragment.
De wrapper gebruikt AES-256-GCM, een door NIST gestandaardiseerde geauthenticeerde cipher, met een verse 256-bit sleutel K die per qub door de CSPRNG van je browser wordt gegenereerd. K is als geauthenticeerde aanvullende data gebonden aan het qub_id van de qub, zodat een sleutel van één qub niet kan worden hergebruikt om een andere qub te ontsleutelen.
K bereikt onze servers nooit in de standaard flow van de privébrowser. Het is gecodeerd in het URL-fragment van de deel-link (https://qub.social/c/<tx_id>#<base64url(K)>). Browsers verzenden geen URL-fragmenten naar servers—RFC 3986 plaatst het fragment buiten het verzoek—dus qub.social, opslaggateways, CDN's en verzoekmonitoring zijn blind voor K in die stroom. De opgeslagen OuterWrapper is herkenbare gestructureerde CBOR, maar het geauthenticeerde ciphertext-veld verbergt het binnenste SealedQub structuur en kan niet worden geopend zonder K.
Netto-gevolgen:
- qub.social kan standaard privé browserzegels niet ontsleutelen alleen uit opgeslagen gegevens. Een inbreuk op de gegevensopslag bereikt ondoorzichtig ciphertext zonder K. Openbare qubs en herstel-ingeschakelde qubs hebben verschillend blootstellingsniveau door ontwerp.
- Fragmentverlies is onherstelbaar zonder een gekozen herstelkanaal. Als je een privélink opslaat zonder het fragment en geen herstel hebt ingeschakeld, wordt de qub onleesbaar via die link. De seal-flow toont om deze reden een expliciete 'sla deze URL op'-melding.
- Herstel op aanvraag. Wanneer je je aanmeldt voor maker-lifecycle e-mails voor een qub EN de e-mail overeenkomt met je geverifieerde identiteit, accepteren we K bij de upload, slaan de volledige aflever-URL op in het verzegelde-geschiedenisrecord van je identiteit en gebruiken deze als de link in de verzegelingsbevestigingse-mail. Deze ruil — een server-zijde herstelkanaal in ruil voor enige end-to-end zuiverheid — wordt alleen uitgevoerd bij expliciete aanmelding en alleen voor die qub. De standaardhouding is crypto-vermalen.
Het server-side /api/v1/seal-eindpunt van de Worker (gebruikt door AI-agents en andere API-aanroepers) vereist dat de aanroeper K genereert met een CSPRNG, deze lokaal behoudt en levert als wrapper_key_b64url. De Worker ziet op dit expliciet vertrouwde pad noodzakelijkerwijs zowel de platte tekst als K in het geheugen, maar houdt geen van beide aan. Een verplichte Idempotency-Key voorkomt dat een verloren antwoord een tweede in rekening gebrachte qub aanmaakt, terwijl de door de aanroeper behouden K kan worden gecombineerd met de opnieuw afgespeelde fragmentloze URL. Dit verschilt van het standaard browserpad, waar K de Worker nooit bereikt tenzij de maker uitdrukkelijk herstel inschakelt.
4. Transport en edge
4.1 TLS
Browserverkeer naar qub wordt via HTTPS bediend aan de Cloudflare-edge. Reacties stellen HTTP Strict Transport Security in (max-age=63072000; includeSubDomains; preload). De exact onderhandelde TLS-versie en cipher suite worden bepaald door de actieve edge-configuratie en niet door de applicatiecode zelf. We maken geen afzonderlijk bereikbaar origin-server beschikbaar.
4.2 Inhoudsbeveiliging
De gecompileerde client wordt geserveerd met strikte content-type- en cache-headers. De SPA-shell is een enkele origin. Wij sluiten geen scripts van derden in voor analytics of advertenties. De twee aanraakpunten met derden in het product zijn beide eng begrensd: de aankoopstroom verlaat de SPA volledig met een volledige-pagina-redirect naar Stripe-gehoste checkout (https://checkout.stripe.com/…) — Stripe's UI draait nooit in onze origin en wij zien nooit kaartdata — en de verzegelstroom laadt Cloudflare's Turnstile-widget, een privacy-vriendelijk CAPTCHA-alternatief dat Cloudflare rendert binnen zijn eigen sandboxed iframe. Geen van beide partijen kan de rest van de pagina lezen.
De qub iframe insluiten (geleverd vanaf qub.social/embed/{tx_id} en geladen op sites van derden door embed.js) draagt zijn eigen Content-Security-Policy. Zijn connect-src toegangsbericht is 'self', https://qub.social, https://arweave.net, https://ar-io.dev, https://permagate.io, https://api.drand.sh, en https://drand.cloudflare.com. De iframe draait met sandbox="allow-scripts allow-top-navigation-by-user-activation" (niet allow-same-origin): de hostpagina kan zijn DOM niet lezen, en het kan de host niet navigeren behalve na een gebruikersactie.
4.3 CORS en fetch-bereik
De browserclient doet fetch-verzoeken alleen naar:
- Onze eigen API (
api.qub.socialen podiumequivalenten) - Opslaggateways (alleen-lezen, voor wrapped-private of bare-public byte-ophaling — §3.6)
- drand beacon-eindpunten (alleen-lezen, voor reveal-tijd rondehandtekeningen)
De bestemmingen van de embed worden afgedwongen door zijn CSP. De bedoelde bestemmingen van de hoofd-SPA zijn vastgelegd in de code en configuratie en worden gecontroleerd door browser- en integratietests; Subresource Integrity is geen netwerkbestemmingscontrole.
De embed haalt opgeslagen bytes op via de toegestaan-lijst qub/storage origins, haalt privé-gegevens in de browser uit met K van zijn URL-fragment en haalt reveal-time rondehandtekeningen op van de twee toegestaan-lijst drand origins. De hoofd-SPA gebruikt de vier-endpoint fallback set in config/drand-endpoints.json (drand.cloudflare.com, api.drand.sh, api2.drand.sh, en api3.drand.sh) zodat een storing van één eindpunt het onthullen niet blokkeert. De ingebedde CSP weigert verbindingen buiten zijn expliciete lijst.
5. Serverzijdige infrastructuur
5.1 Serverless edge
Onze API draait volledig op een beheerde serverless runtime aan de edge. Er zijn geen VM's, geen containers en geen persistente serverprocessen die wij beheren. Dit verkleint dramatisch het aanvalsoppervlak waarvoor wij verantwoordelijk zijn: wij draaien geen OS, geen webserver en geen applicatieruntime die wij moeten patchen.
Een aparte public-CORS-middleware wordt toegepast Access-Control-Allow-Origin: * naar het volgende geïmplementeerde pad ingesteld: /embed.js, /embed/v1.js, alles onder /embed/; /api/v1/telemetry; /api/v1/openapi.json; alles hieronder /api/v1/qub/ (inclusief bytes, metadata, bewijs, betrokkenheid, meldingen en push-subroutes); alles hieronder /api/v1/log/; openbare handvatopzoekingen onder /api/v1/handle/; en openbare avatar leest hieronder /api/v1/identity/avatar/. Zijn preflightvergunningen GET, POST, en OPTIONS met de Content-Type aanvraagheader. Dit op prefix gebaseerde oppervlak is breder dan alleen de oproepen die de embed momenteel maakt, dus iedere handler onder die prefixes moet zijn eigen validatie, authenticatie, snelheidsbeperkingen en misbruikcontroles blijven handhaven. Andere API-paden behouden het qub.social-beperkte CORS-beleid.
5.2 Opslag
- Metadata- en coördinatiewinkels bewaar identiteits- en attestatiegegevens, rechten en facturatieverwijzingen, API-sleutelgegevens, entries op de zwarte lijst, sessies, idempotentiestatus, wachtrijen, en status van snelheidslimieten/concurrentie. Verschillende consistentiebehoeften maken gebruik van KV, D1, en Durable Objects in plaats van één universele opslag.
- Onze objectopslag is ook een duurzaamheidssubstraat. Het bevat precies de gewikkelde of kale qub-bytes die worden erkend door upload, transparantielogbladeren en coördinaat-gekeyde Merkle-knopen, anker materiaal, gestructureerde gebeurtenislogboeken en reactie-/metadata-caches.
- Permanente openbare opslag houdt transparantie-logankers vast en, voor het T3-pad of uitgestelde publicatie, individuele qub-transacties. Wij beheren dat netwerk niet. Privé-browserpayloads blijven daar ondoorzichtig tenzij de houder ook K heeft; publieke/naakte payloads hebben opzettelijk die extra link-mogelijkheidslaag niet.
De standaard browserberichtstroom bewaart geen platte tekst op qub-infrastructuur. Builder /api/v1/seal handelt platte tekst en K in het geheugen af, maar bewaart geen van beide. Pact-staging slaat noodzakelijkerwijs het ondertekende gestructureerde pact op totdat het mede-ondertekend, ingetrokken of verlopen is. Opt-in herstel slaat een leveringscapaciteit op (de volledige fragment-dragende link) zodat het later kan worden hersteld. We beschrijven de volledige opslaglaag daarom niet als "alleen metadata."
5.3 Geheimen
Geheimen (ondertekeningsportefeuilles, providertokens en HMAC-sleutels) worden geleverd via platformgeheime-/omgevingsbindingen in plaats van broncodebeheer. Runtime-componenten ontvangen alleen de bindingen die zij nodig hebben. Rotatie- en overlapprocedures zijn component-specifiek; wij beweren geen enkel universeel automatisch of gecontroleerd rotatiemechanisme.
5.4 Logging en telemetrie
Bij elk API-verzoek worden gestructureerde JSON-logs geschreven met een correlatie-ID die naar voren komt in de X-Request-Id-antwoord-header. Cliënt-telemetrie is anoniem — geen apparaat-identificator, geen IP-adres, geen inhoudsvoorbeeld. Events worden in het geheugen gebufferd en op best-effort-basis geflusht; een mislukte flush wordt verworpen, niet opnieuw geprobeerd. Telemetrie is zo ontworpen dat zij op de netwerklaag is uit te schakelen zonder het product te beïnvloeden.
6. Authenticatie
6.1 Magic-link aanmelden
Aanmelden gebruikt een eenmalige, HMAC-ondertekende token die naar je e-mailinbox wordt gestuurd. De link is 15 minuten geldig en inwisseling wordt atomair geclaimd, zodat gelijktijdig of herhaald gebruik faalt. Bij succes ontvangt de browser een ondoorzichtig __Host-qub_session koekje met Secure, HttpOnly, SameSite=Strict, en Path=/ attributen.
Sessies hebben een inactiviteitslimiet van 30 dagen en een absolute limiet van 90 dagen, draaien na 24 uur, en accepteren alleen de onmiddellijk vorige generatie voor een lost-respons gratietijd van 120 seconden. Gevoelige accountwijzigingen vereisen authenticatie binnen de voorgaande 10 minuten. Het HMAC-ondertekeningsgeheim is een platformbinding; een alleen-metadata-leesactie creëert op zichzelf geen geldig token.
6.2 API-sleutels (Developer-tier)
Developer-API-sleutels gebruiken het prefix qub_sk_ voor eenvoudige herkenning en greppability. Elke sleutel:
- Is gekoppeld aan een account, scopes en een optionele IP CIDR-toegestane lijst
- Wordt eenmaal in ruwe vorm weergegeven; blijvende gegevens bewaren de SHA-256-hash ervan, niet het geheime gegeven
- Kan worden gedraaid met een uur durende overgangskaart waarbij de oude sleutel naar de vervanging verwijst
- Heeft onafhankelijke quota- en snelheidslimietstatus
- Wordt nooit volledig gelogd; logs registreren alleen de sleutelidentificatie
Admin-sleutelbeheereindpunten zijn afgeschermd achter een aparte admin-credential.
6.3 E-mailattestatie (auteursondertekening)
Het binden van een e-mailadres aan een ondertekensleutel vereist:
- Bezit van de privé-ondertekensleutel (je ondertekent een challenge)
- Bezit van de e-mailinbox (je voert een 6-cijferige code in die per e-mail wordt geleverd)
Een van beide alleen is onvoldoende. Intrekking is een ondertekend record op je eigen account en treedt onmiddellijk in werking; lezers die de attestatie ophalen, zien de ingetrokken status en tonen dienovereenkomstig.
7. Betalingen
Kaartinvoer en verwerking verlopen binnen de door Stripe gehoste checkout. Wij ontvangen nooit kaartnummers, vervaldatums of CVC's. We slaan wel Stripe-klant- en abonnementsidentificaties, de status van het abonnement en periodedata op in betaal-/API-sleutelrecords, zodat toegang, verlengingen, meting, annuleringen en terugbetalingen kunnen worden afgestemd. De privacy- en beveiligingsverklaringen van Stripe bepalen de omgang met betalingsgegevens.
Het verzegeleindpunt cross-checkt het entitlement-record tegen de apparaat-identificator en, voor ingelogde gebruikers, tegen de gekoppelde identiteit. Een entitlement kan niet over apparaten heen worden hergebruikt zonder dat de gebruiker hem uitdrukkelijk via magic-link aanmelden herstelt.
8. Misbruikweerstand
8.1 Botdetectie
De verzegelstroom is afgeschermd door een privacy-vriendelijk CAPTCHA-alternatief dat geen cookies gebruikt voor tracking en geen fingerprint voor advertenties. Een mislukte challenge wordt geweigerd door onze edge-Worker voordat enige verzegelzijdige verwerking plaatsvindt.
8.2 Rate-limiting
Rate-limits worden afgedwongen op meerdere lagen:
- Per-IP- en per-sleutel-limieten op verzegel-, lees- en auth-eindpunten
- Per-e-mail-limieten op magic-link-verzoeken (voorkomt mailbox-flooding)
- Per-tegenpartij-limieten op pact-uitnodigingse-mails (tien per ontvangstadres per UTC-dag, de primaire mitigatie tegen spamrelay; eerlijke pacts naderen de limiet bijna nooit)
- Per-IP-limieten op telemetrie-indiening
Counters en atomische claims worden verdeeld over KV, Duurzame Objecten en platform rate-limit bindings volgens de consistentie-eisen van het eindpunt. Verzoeken die rate-limited zijn, geven 429 terug; eindpunten die een retry-venster kunnen berekenen, omvatten Retry-After.
8.3 Inhoudsmoderatie
De standaard browser-uploadroute kan de inhoud niet scannen: deze ontvangt alleen het door de cliënt verzegelde artefact. De Builder /api/v1/seal route ziet platte tekst tijdelijk, en pact staging houdt gestructureerde termen vast totdat finalisatie plaatsvindt, maar die vertrouwensuitsluitingen veranderen het algemene byte-blinde uploadpad niet in een inhoudsscanner. Operationele moderatie is een weigerenlijst op de kijkerlaag: een geweigerde qub wordt door onze kijker geweigerd, ongeacht of de opgeslagen payload bereikbaar blijft. Weigerlisting trekt geen duurzame bytes, transparantielogboekvermeldingen of permanent-netwerkgegevens die al zijn gepubliceerd terug.
Misbruikmeldingen zijn rate-limited met behulp van een eenrichtingshash van het IP van de melder; wij slaan geen IP's in helder tekst op voor dit doel.
9. Toeleveringsketen en buildintegriteit
9.1 Toolchain-pinning
Compiler- en runtimeversies zijn vastgelegd in de repositoryconfiguratie en afhankelijkheden worden opgelost via vastgelegde lockfiles. CI controleert de actualiteit van gegenereerde bestanden en reproduceerbaarheidsgevoelige invarianties. We doen niet de sterkere bewering dat elke schone build op bitniveau identiek is op alle ondersteunde machines.
9.2 Lints en statische analyse
De werkruimte zet onze strengste lint-groepen aan op deny-niveau. CI behandelt elke waarschuwing — inclusief documentatie-linkwaarschuwingen — als build-falen. Dit is bewust: wij gebruiken de lintstrengheid als struikeldraad voor subtiele regressies.
9.3 CI-poorten
De CI-workflow omvat formattering en strikte lints; Rust-, WASM/browser-, Worker-, embed- en API-tests; typecontrole; code coverage; mutatie-/invariantcontroles; afhankelijkheids- en workflowstatistische analyse; i18n-sleutels, dekking, drift- en hostiele-codepointcontroles; vernieuwing van gegenereerde documentatie/API/kennisbank; documentinventarisatie- en interne-linkcontroles; stylesheet- en bundelbudgetten; en OpenAPI-validatie. Sommige dure mutatietaken worden gepland in plaats van bij elke push uitgevoerd.
Een enkele vereist ci roll-up blijft rood als een vereiste taak faalt. Workflows voor beschermde takken en implementatie gebruiken dat resultaat in plaats van een kleinere beveiligingspoort te dupliceren.
9.4 Mutatietesten
Een wekelijkse taak draait mutatietesten tegen de security-kritieke pure modules: hashing, canonical CBOR, seal, unlock, de wire-format newtypes, de protocoltype-validators en de handle-naamruimte. Mutatietesten beantwoorden "vangt onze testsuite subtiel verkeerde code?" — als een gemuteerde implementatie nog steeds alle tests passeert, weten wij dat wij een test-dekkingsgat hebben en pakken het aan.
9.5 Git-hooks
Lokale hooks (pre-commit, pre-push) spiegelen de CI-poorten zodat regressies worden gevangen voordat zij de machine van de ontwikkelaar verlaten. Hooks worden geïnstalleerd via een repo-script; zij worden niet omzeild in onze workflow en CI is de gezaghebbende poort als zij worden overgeslagen.
10. Testen
Security-kritieke code draagt drie soorten tests:
- Unit-tests verifiëren verwacht gedrag op bekende invoer, inclusief testvectoren afgeleid uit de protocolspecificatie.
- Property-tests genereren duizenden willekeurige invoer en stellen invariants vast: canonieke CBOR-rondtrips, handtekeningverificatie-rondtrips, e-mailbindingspredicaten, determinisme van pactbevestiging.
- Cross-implementatie-tests verifiëren dat onze client- en serverimplementaties byte-voor-byte overeenkomen op canonieke coderingen. Dit vangt divergentie tussen de twee implementaties voordat ze productie bereikt.
11. Branch- en releasehygiëne
Feature-branches gaan vooruit staging alleen via een Gate 1 pull request: verplicht ci groen, geen onopgeloste wijzigingsaanvraag, geen merge-conflict, en een schoon beoordeeld overzicht; de merge is squash-en-verwijder. main gaat alleen verder via Poort 2 staging → main pull request en behoudt de afstamming met een merge-commit. Directe branch-pushes zijn niet de release-workflow.
Staging- en productie-implementaties worden geactiveerd vanuit de overeenkomstige beschermde staging en main branch-branches na CI. Pull-requestcode en fork-gegevens ontvangen geen deploysecrets.
Geheimen die in deploy-workflows worden gebruikt, zijn door ons CI-platform tot de deploy-omgeving begrensd. Zij zijn niet beschikbaar voor pull-request-workflows vanuit forks.
12. Gecoördineerde openbaarmaking
Indien je gelooft dat je een beveiligingskwetsbaarheid in qub hebt gevonden, willen wij er snel van horen, en wij verbinden ons ertoe de melding professioneel af te handelen.
- E-mail
support@qub.socialmet het onderwerpvoorvoegsel[SECURITY]. - Beschrijf de kwetsbaarheid, stappen om te reproduceren en eventuele proof-of-concept.
- Geef ons een redelijk openbaarmakingsvenster (doorgaans 90 dagen) voordat je openbaar maakt.
- Open geen toegang tot data die niet van jou is, degradeer de dienst niet voor andere gebruikers en bewaar geen data die tijdens onderzoek is verkregen verder dan nodig is om het probleem aan te tonen.
Wij bevestigen ontvangst binnen drie werkdagen en houden je op de hoogte terwijl wij onderzoeken. Met je toestemming crediteren wij melders in release-notities.
12.1 Safe Harbor
Indien je onderzoek de bovenstaande regels volgt (te goeder trouw onderzoek, geen schade voor andere gebruikers of de dienst, redelijk openbaarmakingsvenster), zullen wij geen juridische stappen tegen je ondernemen, en wij zullen wetshandhaving daar niet om vragen. Wij behandelen je werk als geautoriseerd testen en wij hebben liever dat jij de bug vindt dan iemand anders.
Deze Safe Harbor is van toepassing op:
- Onderzoek op de live qub.social-dienst (niet op testfixtures die wij voor dat doel publiceren).
- Reverse engineering van onze gepubliceerde binaries en de open-source qub-core / qub-app crates.
- Elke kwetsbaarheidsklasse — protocol, applicatie, infrastructuur, toeleveringsketen — die qub raakt.
Hij is niet van toepassing op social engineering van qub-teamleden, denial-of-service-tests of toegang tot data van andere gebruikers verder dan nodig is om het probleem aan te tonen. Als je niet zeker weet of iets binnen de Safe Harbor valt, vraag het eerst met hetzelfde [SECURITY]-onderwerpvoorvoegsel.
13. Eerlijke beperkingen
Beveiliging is een praktijk, geen toestand. Sommige beperkingen verdienen het om direct te worden genoemd:
- Wij zijn een klein team. Onze beoordelingsdiepte evenaart niet die van de gespecialiseerde applicatiebeveiligingsfunctie van een groot bedrijf. Wij compenseren met strikte geautomatiseerde poorten en een minimaal aanvalsoppervlak, maar wij claimen geen onfeilbaarheid.
- De permanentie van onze opslag-backend is een eenrichtingsdeur. Als een fout ervoor zorgt dat verzegelde inhoud eerder dan bedoeld ontsleutelbaar wordt, kunnen wij dit niet ongedaan maken. Wij behandelen de verzegelstroom met overeenkomstige zorg.
- Het drand-netwerk is een externe afhankelijkheid. Een catastrofale storing van drand zou het onthulgedrag van elke qub beïnvloeden. Wij monitoren de gezondheid van drand en hebben contingentiedocumentatie voor ketenmigratie indien nodig. Voor ontgrendeldata meer dan 2 jaar in de toekomst toont de bevestigingsmodal op verzegelmoment een uitdrukkelijke bekendmaking: lange-horizon qubs zijn afhankelijk van de duurzaamheid van de drand-keten, en een toekomstige drand-ketenmigratie kan herstelstappen vereisen om de qub te ontgrendelen. Voor ontgrendeldata meer dan 5 jaar in de toekomst moet je een extra vakje aanvinken dat je dit risico hebt gelezen en accepteert voordat de verzegeling doorgaat.
- De cryptografische primitieven waarop wij vertrouwen zijn gestandaardiseerd en breed beoordeeld, maar cryptografie evolueert. Waar wij keuzes hebben (post-quantum-ondertekenen, geauthenticeerde versleuteling), kiezen wij de meer conservatieve optie.
14. Wijzigingen van deze pagina
Wezenlijke wijzigingen worden vermeld door de ingangsdatum bovenaan bij te werken. Waar een wijziging een concrete beveiligingsverbetering weerspiegelt, beschrijven wij deze kort in de openbare changelog. Waar een wijziging een beleidsverduidelijking weerspiegelt, beschrijven wij wat is veranderd en waarom.
Voor vragen over alles op deze pagina, e-mail support@qub.social met het onderwerpvoorvoegsel [SECURITY].
15. Wijzigingenlog
| Versie | Ingangsdatum | Samenvatting |
|---|---|---|
| 1.1 | 23 september 2026 | Geconsolideerde cryptografische claims, leveringsmodi, opslag, CSP, sessies, API-sleutels, betalingen, CI en releaseworkflow met het geïmplementeerde systeem. |
| 1,0 | 2 mei 2026 | Eerste publicatie. |