Zabezpečené streamování audia

TL;DR
Článek popisuje výzvy a řešení spojené se zabezpečením audio streamingu pro projekt Knížkomat, kde bylo klíčové zabránit neoprávněnému stahování audioknih. Upozorňuje na omezení standardní značky HTML <audio>, která může odhalit adresy URL zvukových souborů a umožnit jejich přímé stahování. Navrhované řešení zahrnuje použití skrytého tagu audio s vlastním ovládacím panelem a middlewarem pro správu autorizace uživatelů a zabezpečení požadavků. Toto nastavení brání uživatelům ve snadném stahování obsahu a zároveň umožňuje řízený přístup, čímž je dosaženo rovnováhy mezi použitelností a bezpečností.

Jedním z požadavků na projektu Knížkomat bylo “zajistit přehrávání audio-knížek tak, aby si je lidé nemohli stáhnout”. V praxi není možné absolutního zákazu stažení dosáhnout, jelikož pokud se audio přehrává na uživatelově počítači, nic mu nebrání v tom, si zvuk nahrát prostřednictvím externích programů. To samé platí i pro přehrávání videí nebo pouhé zobrazování textu. Veškeré informace je možné nějak stáhnout. Reálným úkolem tedy bylo zabránit hlavním a nejjednodušším způsobům stažení audio záznamu z webové stránky. Později se tento problém rozšířil i na základní zabránění uživateli přehrát si audio záznam, pokud není přihlášený, nebo nemá k danému záznamu mít přístup, jelikož i to není zajištěno základní implementací audia na webu.

Formulace problému

Pokud budeme vycházet ze základní implementace přehrávání audia pomocí HTML tagu <audio>, který obsahuje odkaz na audio soubor umístěný někde na serveru, vytváří nám to hned několik problémů. 

  1. Tento element často poskytuje přímo tlačítko pro stažení audia, které přehrává.
  2. Pokud je uživatel znalý, může si zobrazit zdrojový kód stránky, kde najde adresu audio souboru. Když tuto adresu otevře, soubor se mu rovnou celý stáhne.
  3. Audio tag si generuje vlastní požadavky, kterými získává jednotlivé části audio souboru pro načítání. Tyto požadavky obsahují pouze cookies, které má uživatel nastavené a samotnou URL adresu souboru. V cookies může být uložená identifikace uživatele, ale v případě Knížkomatu, kdy cookies slouží pouze k autorizaci mezi frontendem a middleware (middleware se backendu autorizuje přes JWT tokeny), by backend, který obdrží požadavek na část audia, nebyl schopen identifikovat uživatele. Dále by bylo možné do URL adresy přidat nějakou identifikaci, které by rozuměl backend, ale pak by přihlášený uživatel mohl tuto adresu distribuovat dalším nepřihlášeným uživatelům.

Možná řešení

První problém lze vyřešit relativně snadno, stačí skrýt objekt audia na stránce a vytvořit vlastní ovládací panel, který nebude obsahovat tlačítko pro stažení nebo snadné zkopírování URL adresy. Už tento krok odradí většinu neznalých uživatelů a hodně stránek se tedy s tímto řešením spokojí, jelikož je tzv. “good enough”.

Druhý problém je už komplexnější a platformy jako třeba Spotify ho řeší kompletní vlastní implementací přehrávání audia, kdy adresa původního souboru není vidět v kódu stránky, což je ale velice složitý a nákladný způsob. Existují i už hotová řešení na přehrávání audia, ale ta mají často problémy s průběžným načítáním, posouváním se po audio stopě atd., základní audio tag je v tomto směru nejlepším možným základem.

Třetí problém je opět řešitelný pouze vlastní implementací přehrávání audia, kdy programátor využívá vlastní formáty pro komunikaci mezi frontendem a backendem. Ale i zde platí, že uživatel může sledovat požadavky, které odcházejí z jeho počítače, získat z nich adresu souboru.

Naše řešení

Přestože třetí problém je způsobený naším využitím middleware, ve finále právě tato vrstva hraje klíčovou roli v zabezpečení našeho řešení.

Nejprve si pojďme představit implementaci frontendu. Zde využíváme standardní HTML audio tag, který je skrytý a k němu je vytvořený vlastní ovládací panel, který interaguje s audio tagem pomocí JavaScriptu. To nám zajistí jak uživatelsky přívětivé a hezky vypadající ovládání, tak robustní systém postupného načítání audia, tedy streamování, které si zajišťuje sám audio tag.

Požadavky z audio tagu přijdou na middleware, kde je uživatel autorizovaný pomocí cookies, které přišly spolu s požadavkem. Tím se zajistí, že uživatel má k audiu skutečně přístup. Nabízelo by se pouze k požadavku přidat uživatelův JWT token a poslat ho na backend, pokud by ale uživatel nějak zjistil adresu backendového API (standardně je od něj odstíněn middlewarem, ale jedná se o veřejnou URL adresu) a svůj JWT token (k němu také nemá standardně přístup), mohl by z backendového API stáhnout celý soubor najednou. Proto se na middleware k požadavku přidává tajný kód sdílený mezi middleware a backendem, který potvrzuje, že požadavek byl skutečně vygenerován v middleware. Jelikož middleware i backend běží na stejném serveru, jedná se o komunikaci na localhostu a není tedy potřeba se bát zveřejnění tohoto kódu.

Pojďme si tedy zrekapitulovat jak naše řešení eliminuje nastíněné problémy:

  1. Používáme vlastní ovládací panel, který neumožňuje snadné stažení přes tlačítko.
  2. URL adresa a všechny požadavky, které vidí uživatel, směřují na middleware, který nemá přístup k celému audio souboru najednou a není tedy schopen ho najednou poskytnout uživateli ke stažení.
  3. I kdyby uživatel získal skutečnou adresu souboru na backendu, tak si ho nemůže stáhnout, jelikož nezná tajný kód.

Tento překlad požadavků na middleware nepřináší žádné výrazné zpomalení přehrávání a splňuje v rozumné míře všechny požadavky. Samozřejmě si uvědomujeme, že naše řešení není dokonalé a samotné nás napadá několik možných způsobů, jak ho obejít. Přesto jsme však dosáhli toho, že streamování audia na Knížkomatu je zabezpečené nad schopnosti bežného i znalého uživatele.

frontendbackend

NoxLabs je tým inženýrů a designérů, kteří se specializují na vývoj webových a mobilních aplikací. S nadšením vytváříme krásný software a vítáme nové nápady na projekty.

Chcete s námi spolupracovat? Napište nám