<!-- Test mit zehn Personas der Zielgruppe, 31.07.2026.
     Sechs Vertraulichkeit, vier Tempo. Durchschnitt 3.8/10.
     Impressum und Datenschutz waren ausgenommen. -->

# CloakDrop — Urteil aus dem Test mit zehn Nutzern

*Hinweis vorab zur Datenlage: Von den vier Tempo-Testern liegen mir nur die Noten vor, von den sechs Vertraulichkeits-Testern die vollständigen Berichte. Alle Belege unten stammen aus diesen sechs. Wo ich über die Tempo-Gruppe etwas sage, stützt es sich auf deren Noten und auf die Tempo-Messungen der anderen — das ist gekennzeichnet.*

---

## 1. Die Note

**3,80 im Schnitt. Spanne 3,0 bis 5,5.** Kein einziges "ja" auf die Frage, ob jemand es benutzen würde: fünfmal "nein", einmal "vielleicht", vier Tempo-Noten ohne Volltext.

Die Aufteilung ist das eigentlich Interessante, weil sie andersherum ausfällt, als man erwartet:

| Gruppe | Noten | Schnitt |
|---|---|---|
| Vertraulichkeit (6) | 3,0 · 3,5 · 4,0 · 4,0 · 4,5 · 5,5 | **4,08** |
| Tempo (4) | 3,0 · 3,5 · 3,5 · 3,5 | **3,38** |

Die anspruchsvollere Gruppe benotet besser. Der Grund ist nicht Wohlwollen: Wer prüfen kann, findet hier etwas zum Prüfen und findet es gut — die Krypto trägt die Note allein. Wer nur schnell eine Datei verschicken will, dem bleibt nach dem Wegfall des Transports nichts übrig, was man bewerten könnte; Geschwindigkeit ohne Zustellung ist null. Deshalb liegen die vier Tempo-Noten alle im engen Band 3,0–3,5.

## 2. Der Satz

Sechs von sechs sagen in eigenen Worten dasselbe: **die Verschlüsselung ist echt und gut — und das Produkt verschickt nichts.**

> "Ich habe zwei Stunden nach der Lüge gesucht und keine gefunden — dafür eine Anwendung, die die eine Sache nicht tut, für die man sie öffnet." (Sicherheitsforscher, 4,5)

> "Ich habe sechsundvierzig Megabyte in sechs Zehntelsekunden verschlüsselt und danach niemandem schicken können." (Strafverteidigerin, 3,0)

> "Ich habe eine Datei verschlüsselt, die ich schon hatte, für einen Empfänger, der sie nie sehen wird." (Psychotherapeut, 4,0)

Alle sechs betonen, dass das ehrlich dokumentiert ist. Alle sechs sagen im selben Absatz, dass Ehrlichkeit über eine fehlende Funktion die Funktion nicht ersetzt.

## 3. Die Vertrauensfrage

Das ist der Kern, also präzise. Sechs Leute haben unabhängig voneinander versucht, die Krypto zu brechen oder eine Lüge zu finden. **Sie haben es nicht geschafft.** Was tatsächlich geprüft wurde:

- **Exfiltration aktiv versucht**, nicht nur beobachtet: fetch (fremd und eigen), sendBeacon, WebSocket, Bild-als-Kanal — jedes Mal vom Browser blockiert, mit CSP-Verstoßmeldung. `connect-src 'none'` ist eine Fessel, keine Zusage.
- **Netzwerk mitgeschnitten** von allen sechs, jeweils während des Verschlüsselns: null Requests. Eine ganze Sitzung = drei Dokumentaufrufe.
- **Quelltext durchsucht** nach `fetch(`, `XMLHttpRequest`, `sendBeacon`, `new Image`, `WebSocket`, `eval`: null Treffer. Eine HTML-Datei, keine externen Hosts, Inter als data-URI.
- **Nonce-Konstruktion gelesen** — die Stelle, an der der Sicherheitsforscher den Fehler erwartet hat: 8 Byte Zufallspräfix + 4 Byte Zähler, Manifest auf 0, Chunks ab 1, kein Überlauf bei 500 MB. Richtig gebaut.
- **GCM-Overhead nachgerechnet**: 298 Byte Klartext → 314 Byte gespeichert. 200 MB → 50 Chunks → exakt 800 Byte Overhead.
- **Roundtrip mit sha256** bei 74 kB, 3 MB, 5 MB, 46 MB, 60 MB, 180 MB, 200 MB, 300 MB, 400 MB: jedes Mal byte-identisch.
- **Schlüssel gesucht** in localStorage, sessionStorage, Cookies, beiden IndexedDB-Stores: nirgends. Fünf Drops = fünf verschiedene 256-Bit-Schlüssel.
- **Dateinamen binär gesucht** im gesamten IndexedDB, mit Ködermarkern: null Treffer, Entropie der abgelegten Bytes 7,33 Bit/Byte.
- **Löschen auf Plattenebene geprüft**: erste 24 Byte des Chiffrats gemerkt, komplettes Browserprofil durchsucht — vorher ein Treffer in der IndexedDB-Blobdatei, nach dem Löschen keiner, auch nach Schließen des Browsers keiner.

**Befund: Die Krypto-Schicht hält.** Niemand ist an Klartext oder Schlüssel gekommen. Das ist ein echtes Ergebnis, und der Sicherheitsforscher, der davon lebt, solche Versprechen zu zerlegen, schreibt es genau so hin.

**Die zwei Löcher liegen nicht in der Krypto, sondern daneben:**

1. **Die Ablauffrist ist keine Zusicherung, sondern eine Anzeige.** `expires` liegt im Klartext im IndexedDB, unauthentifiziert. Fünf Tester haben unabhängig einen abgelaufenen Drop wiederbelebt und die Datei im Klartext zurückbekommen. Und Ablauf löscht nichts — das Chiffrat bleibt liegen, bei einem Tester auch nach dreimaligem Neuladen der App. Heute folgenlos, weil ohnehin nur der Erzeuger drankommt. Sobald ein Relay einer clientseitigen Frist glaubt, ist es ein echtes Loch.

2. **Die Auslieferung.** Kein Repo, keine Signatur, keine SRI, keine reproduzierbaren Builds — und die CSP-Hashes, die das Inline-Skript festnageln, kommen aus derselben Antwort wie das Skript. Der schärfste technische Punkt des gesamten Tests kommt vom Privacy-Nerd: ein verändertes HTML könnte den Schlüssel in eine **Bild-URL** hängen. Das käme an `connect-src 'none'` vorbei, weil `img-src 'self' data:` erlaubt ist, und läge im Cloudflare-Log als harmloser GET. Keiner der vier Selbsttests auf /verify würde das bemerken. Eure eigene Seite schreibt den Satz dazu: *"It does not pin down what you are served next time."*

Dazu zwei kleinere Widersprüche zum eigenen Text: **NEL/Report-To** schickt Netzwerkfehlerberichte an `a.nel.cloudflare.com`, an der CSP vorbei — während die Startseite *"this build never sends a byte anywhere"* behauptet. Und **der Schlüssel bleibt nach dem Öffnen in der Adresszeile**, wandert damit in Verlauf, Omnibox und bei aktivem Sync zum Anbieter — während die Seite mit *"Browsers never send fragments to servers, proxies, or logs"* wirbt. Auf dem Draht stimmt das. Auf der Platte nicht.

## 4. Der Aufwand

**Vier bis fünf Klicks bis zum kopierten Link.** Gemessene Kaltstartzeiten: 1,4 s / 1,6 s / 3,43 s (letzteres inklusive 400 MB Verschlüsselung). Verschlüsselungstempo: 3 MB in 0,08 s, 60 MB in 0,72 s, 120 MB in 1,1 s, 180 MB in 1,1 s (164 MB/s), 400 MB in 1,9 s (213 MB/s). Rückweg 200 MB in 5,5 s. Die 500-MB-Grenze greift bei der Dateiwahl, nicht mittendrin.

Gegen WeTransfer: Für 120 MB starrt man dort minutenlang auf einen Balken und gibt vorher eine Mailadresse ab. Hier: 1,1 Sekunden, kein Konto, kein Cookie-Fenster. Der Tempovorsprung ist real und groß — er entsteht aber genau dadurch, dass nichts hochgeladen wird. Er verschwindet an dem Tag, an dem das Relay steht. Ihn heute als Vorteil zu zählen, wäre eine Selbsttäuschung.

**Gezögert wurde an fünf Stellen, mehrfach genannt:**

- **7 Tage sind vorausgewählt** — drei Tester mussten erst begreifen, dass das eine Entscheidung ist und kein Platzhalter.
- **Der Absatz nach dem Fertig-Bildschirm.** Fünf von sechs erfahren erst *nach* dem Kopieren, dass der Link nur bei ihnen aufgeht. Ein Tester: *"Ich habe es dreimal gelesen, weil ich nicht glauben wollte, dass dort tatsächlich steht, der Link öffne nur in genau diesem Browser."*
- **"Press again to delete"** — drei Tester hielten den Löschknopf beim ersten Klick für kaputt. Die Absicherung ist richtig, die Rückmeldung ist zu leise.
- **"Stops opening after"** — zwei mussten im Quelltext bzw. auf /limits nachsehen, ob das "gelöscht" heißt.
- **Der Copy-Knopf** legt den vollständigen Schlüssel in die System-Zwischenablage (auf Windows: Win+V-Verlauf, ggf. Cloud-Sync). Kein Wort dazu.

Für die vier Tempo-Tester ist Punkt zwei mit hoher Wahrscheinlichkeit der Grund für 3,0–3,5: Sie erleben den Bruch nach getaner Arbeit, ohne die Krypto-Hälfte, die die andere Gruppe entschädigt hat.

## 5. Echte Fehler (mehrfach unabhängig belegt)

| # | Was | Wo | Beleg | Finder |
|---|---|---|---|---|
| 1 | Frist löscht nichts und lässt sich zurückdrehen | IndexedDB `cloakdrop` > `transfers` > `expires` | expires in die Vergangenheit → "This link no longer opens", Speicher zeigt weiter `chunks: 1`. expires in die Zukunft → "OPENS FOR 28 MORE HOURS" bzw. "99 MORE DAYS", Datei kam vollständig im Klartext zurück | **5 von 6** |
| 2 | Schlüssel bleibt nach dem Entschlüsseln in der Adresszeile | Empfangsansicht, kein `history.replaceState` | `location.href` = `.../#t=...&k=...`, Prüfung `'&k=' in href` → True, `history.length = 2` | **4 von 6** |
| 3 | Manipuliertes Chiffrat scheitert stumm, obwohl "Tampering fails loudly" auf der Startseite steht | Empfangsansicht + Claim-Block "Integrity" | Ein Bit gekippt: Liste zeigt weiter "1 cloaked file, 976.6 KB, Download". Klick → kein Download in 15 s, keine Meldung. Einziges Signal: Konsole `OperationError at downloadFile (…:2745:49)` | **2 von 6** |
| 4 | /limits widerspricht sich selbst und dem Produkt | cloakdrop.com/limits | Tabelle Z. 66/67: "Delete a drop early \| Yes, from the app" gegen FAQ Z. 89/90: "Removed early, not in this build". Dieselbe FAQ: "seven days is the lifetime every link is created with" — die App bietet 1 h / 24 h / 7 Tage, die 60-Minuten-Frist wurde im Speicher nachgemessen. Zusätzlich Tabelle "Extend a link — Not possible", widerlegt durch #1 | **2 von 6** |
| 5 | Voreinstellung ist die längste Frist | `#exp-grp` | `aria-checked`: 1 hour false, 24 hours false, 7 days **true** | **3 von 6** |
| 6 | NEL/Report-To an Dritte, während der Text es bestreitet | Antwortkopfzeilen | `Nel: {"report_to":"cf-nel",…}`, Endpoint `https://a.nel.cloudflare.com/report/v4` gegen "never sends a byte anywhere" | **3 von 6** |
| 7 | HSTS `max-age=86400`, ohne includeSubDomains, ohne preload; daneben `Access-Control-Allow-Origin: *` auf dem HTML, das die Krypto trägt | Antwortkopfzeilen | curl -D -, direkt neben `cross-origin-resource-policy: same-origin` | **2 von 6** |

**Einzelfunde, aber konkret und billig zu beheben:** Widerspruch auf der Empfängerseite im fremden Browser (Hero sagt *"decryption happens right here"*, die Karte darunter *"Nothing here"* — beides gleichzeitig im Bild, zweimal reproduziert). Nicht abgefangene Ausnahme bei `#t=…` ohne `&k=`: *"Failed to execute 'querySelector' on 'Document': '#t=-2d4ms011zya' is not a valid selector"* — der Fragmentwert geht ungeprüft an einen Selektoraufruf. Help-Center bewirbt "16 articles · four topics", jeder Titel springt auf `index.html#security`, kein Artikeltext. 620.000.000 Byte werden als "591.3 MB" angezeigt (MiB als MB etikettiert). Keine Drop-Übersicht: wer den Link verliert, kann diesen Drop mit der App nicht mehr löschen. `navigator.storage.persisted() = false` — 500-MB-Drops liegen in Best-Effort-Storage. "Download all" erzeugt bei drei Dateien drei Einzeldownloads plus Chrome-Rückfrage. Drop-Token nur 12 base64url-Zeichen = 72 Bit, für einen globalen Relay-Namensraum knapp.

**Drei Widersprüche im Testfeld, die ich nicht unterschlage:**
- Ein Tester hält die Frist für **manipulationssicher** ("sitzt im signierten Teil"). Er hat die Zeitstempel *zurück*gedreht — das öffnet nichts, es lässt den Drop älter aussehen. Die anderen fünf haben `expires` *vor*gedreht. Der Fund steht.
- Vier Tester bekommen bei geändertem Schlüssel sauber **"The key doesn't fit"**, einer bekommt dreimal **"Nothing here"** und belegt per grep, dass der Satz genau einmal im ausgelieferten HTML steht. Das heißt: es gibt zwei Fehlerpfade für denselben Fehler, und einer davon meldet etwas Falsches ("nicht in diesem Browser" für einen Drop, der in diesem Browser ist). Zusammen mit Fehler 3 ist das ein Muster: **Krypto-Fehler werden von catch-Blöcken verschluckt.**
- Der 404 auf "Open source" ist **kein Fehler**, sondern ein Testerfehler: er hat `/open-source` geholt, im DOM steht `opensource.html`. Drei andere haben die Seite problemlos gelesen.

## 6. Was überraschend gut ankam

Das Ungewöhnlichste am ganzen Test: **Die Selbstauskunft wird von allen sechs ausdrücklich gelobt** — von Leuten, die beruflich misstrauisch sind.

> "Die Seite /verify hat einen Abschnitt 'What this does not prove', der genau die Einwände nennt, die ich erheben würde." (Journalistin)

> "Die Seite /verify listet ihre eigenen Grenzen schärfer auf, als ich es in den meisten bezahlten Audits lese." (Sicherheitsforscher)

> "Wer eigene Fehler ins Changelog schreibt, lügt mich woanders wahrscheinlich auch nicht an." (Privacy-Nerd, über den entfernten ungesalzenen Passwort-Hash)

> "Ich habe in diesem Markt noch nie jemanden gesehen, der so gegen sich selbst schreibt."

Dazu: `/opensource` beginnt mit *"The code isn't public yet"* statt mit einem GitHub-Badge — das hat jeder Einzelne positiv vermerkt. Weiter gelobt: die Kopfzeilen insgesamt, das Tempo, dass die 500-MB-Grenze *vor* der Verarbeitung greift, die zweistufige Löschbestätigung (inhaltlich, nicht optisch), die karge Oberfläche ohne Konto und Cookie-Banner, und der Satz auf der Kontaktseite: *"Never paste the drop link — it carries the key to your files."*

## 7. Was zu tun ist, nach Hebelwirkung

| Prio | Maßnahme | Nennungen | Ohne Relay lösbar? |
|---|---|---|---|
| 1 | **Relay bauen.** Ohne Zustellung bleibt die Note strukturell unter 5, egal wie gut alles andere wird | 10/10 | Nein, per Definition |
| 2 | **Die Browser-Bindung vor den Klick ziehen.** Ein Klartextsatz über "Cloak & create link", nicht "RELAY IN THE WORKS" in grauen Kapitälchen darunter. Kostet einen Satz und hebt vermutlich die vier Tempo-Noten am stärksten | 5 | **Ja, heute** |
| 3 | **Abgelaufene Drops beim App-Start wirklich löschen** und den Wortlaut ehrlich machen: "stops opening" ≠ "gelöscht". Die Frist manipulationssicher zu machen geht im Besitzer-Browser nicht — also nicht behaupten | 5–6 | Aufräumen ja, Manipulationsschutz nein |
| 4 | **`history.replaceState` nach dem Entschlüsseln.** Eine Zeile. Nimmt den Schlüssel aus Verlauf, Bildschirmfreigaben und Sync | 4 | **Ja, eine Zeile** |
| 5 | **Fehler laut machen.** Tamper → sichtbare Meldung statt Konsolen-`OperationError`; falscher Schlüssel darf nicht als "nicht in diesem Browser" erscheinen. Die catch-Blöcke trennen | 3 | **Ja** |
| 6 | **Doku entwidersprüchen:** /limits Tabelle gegen FAQ, "Tampering fails loudly", "never sends a byte anywhere" gegen NEL. Wer bei Ehrlichkeit punktet, verliert bei jedem Widerspruch doppelt | 4 | **Ja, ein Nachmittag** |
| 7 | **Voreinstellung auf 1 Stunde** | 3 | **Ja, eine Zeile** |
| 8 | **Löschbestätigung sichtbarer** (Farbwechsel oder Zähler, nicht nur Beschriftung) | 3 | **Ja** |
| 9 | **Optionales Passwort auf den Drop** (PBKDF2 zusätzlich zum Link-Schlüssel). Heute wirkungslos, weil ohnehin nur du öffnest — am Tag des Relay-Starts Pflicht. Jetzt entwerfen, dann ausliefern | 5 | Entwurf ja, Nutzen erst mit Relay |
| 10 | **Kleinkram:** MiB/MB-Etikett, querySelector-Exception, HSTS hoch, ACAO weg, Help-Center-Artikel schreiben oder die "16 articles" streichen, Drop-Übersicht, `navigator.storage.persist()`, Token auf mehr als 72 Bit | je 1–2 | **Ja** |
| 11 | **Missbrauchsantwort vor dem Relay.** Vier Tester nennen Firefox Send namentlich: Mozilla hat 2020 nicht wegen schwacher Krypto abgeschaltet, sondern weil REvil, FIN7, Zloader und Ursnif verschlüsselte Uploads über eine vertrauenswürdige Domain an Scannern vorbeigeschleust haben und es keine Missbrauchsmeldung gab. Auf /opensource steht dazu ein Halbsatz: *"will handle traffic and abuse"* | 4 | Nein — aber jetzt zu entscheiden |

## 8. Die härteste Wahrheit

Du hast die schwierige Hälfte gebaut, und sie hat einem Sicherheitsforscher zwei Stunden lang standgehalten, der davon lebt, solche Versprechen zu zerlegen — das kann dir niemand nehmen, und es ist selten genug, dass alle sechs es ausdrücklich hinschreiben. Trotzdem beurteilt jeder einzelne Tester das Produkt am Ende nach demselben Satz: es verschickt nichts, also gibt es das Produkt noch nicht, und deshalb steht da 3,80 und nicht 8. Die verbleibende Hälfte ist nicht die kleinere — Transport, Missbrauchsabwehr und die Frage, wer garantiert, welchen Code der Browser beim nächsten Aufruf ausgeliefert bekommt, sind zusammen mehr Arbeit als alles, was heute steht, und die letzte Frage ist die, an der Browser-Krypto grundsätzlich hängt, nicht nur deine.