PdfDragButton R131: 60s-Download-Token statt Access-Token, nur DownloadURL

Pentest R131 (LOW-MEDIUM): Der Drag-Button haengte den 15-Min-Access-
Token an die URL und schrieb ihn per text/plain + text/uri-list beim
Drag mit. Ein Fehl-Drop in ein Text-/Chat-/URL-Feld haette den vollen
Access-Token (alle Berechtigungen, 15 Min) als lesbaren Text geleakt.

Fix:
- fileUrl() akzeptiert jetzt optionalen expliziten Token.
- PdfDragButton nutzt den kurzlebigen 60s-Download-Token
  (authApi.getDownloadToken(), type:download, nur ?token=) statt des
  Access-Tokens. Modul-weiter Cache mit Dedup, auf mount + hover
  vorgewaermt (dragstart ist synchron, kann nicht awaiten).
- Es wird NUR noch DownloadURL im DataTransfer gesetzt, keine
  text/plain- oder text/uri-list-Repraesentation -> Fehl-Drop in ein
  Textfeld erzeugt gar keinen sichtbaren Text.
- Klick-Vorschau nutzt ebenfalls bevorzugt den Download-Token.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-30 12:12:24 +02:00
co-authored by Claude Opus 4.8
parent 8e74f7733a
commit 7d062bf9b2
3 changed files with 95 additions and 14 deletions
+8 -2
View File
@@ -24,9 +24,15 @@ export function viewUrl(path: string | null | undefined): string {
return fileUrl(path, { inline: true });
}
export function fileUrl(path: string | null | undefined, opts?: { inline?: boolean }): string {
export function fileUrl(
path: string | null | undefined,
opts?: { inline?: boolean; token?: string },
): string {
if (!path) return '';
const token = getAccessToken();
// Expliziter Token (z.B. kurzlebiger 60s-Download-Token) hat Vorrang vor
// dem langlebigen Access-Token. Genutzt vom PdfDragButton, damit bei einem
// Fehl-Drop kein 15-Min-Vollzugriffs-Token in fremde Kontexte leakt.
const token = opts?.token ?? getAccessToken();
const normalizedPath = path.startsWith('/') ? path : '/' + path;
// `?disposition=inline` schaltet die Anzeige im Browser-Tab ein,
// der Backend-Controller bleibt aber nur dann inline, wenn die