Skip to main content
Ze zákulisí
Ze zákulisíSecurityPremium

Co odhalil audit našeho vlastního platebního systému

Dvě kritická zjištění, a ani jedno nebylo tam, kde bychom hledali. Otevřená zpráva o chybách, které jsou mezitím opravené.

Zveřejněno od AlphaCloud4 min čtení

V srpnu 2026 jsme od základu prošli náš platební systém. Ne proto, že by se něco stalo, ale protože byl krátce předtím spuštěn a chtěli jsme vědět, co jsme přehlédli.

Přehlédli jsme toho docela dost. Tenhle článek ta zjištění jmenuje. Všechno, co je tu popsané, je opravené, a většina z toho byla stejně už ve veřejném changelogu.

Chyba v modelu, ze které vzešla obě kritická zjištění

Když si u nás někdo koupí Premium, vznikne u našeho platebního poskytovatele záznam zákazníka. Ten jsme ukládali pod ID serveru, protože Premium přece přistává na serveru.

To je přesně ten špatný model a byl kořenem dvou nejzávažnějších zjištění.

Záznam zákazníka patří kupujícímu. Nese jeho platební metodu, jeho historii faktur a, jakmile někdo platí za dva servery, i několik předplatných. Když ho klíčuješ podle ID serveru, ukazuje na stejný řádek několik lidí.

Zjištění 1: Cizí zákaznická data, přepsatelná bez placení

Nákup je otevřený každému členovi serveru a funkce, která záznam zákazníka načte nebo vytvoří, běží před platbou. Našla řádek podle ID serveru a potichu ho přepsala na nového zájemce, včetně jeho e-mailové adresy u platebního poskytovatele.

V praxi to znamenalo: stačilo jedno kliknutí na serveru, kde někdy někdo nakoupil. Potom by faktury ke každému předplatnému toho původního kupujícího chodily na e-mail toho cizího člověka. Žádná platba, žádné potvrzení.

Opraveno tak, že se před jakýmkoli opětovným použitím ověří, jestli záznam opravdu patří tomuto účtu. Při neshodě se vytvoří samostatný a ten druhý zůstane nedotčený.

Zjištění 2: Portál pro fakturaci odhaloval předplatná jiných lidí

Stejná chyba v modelu, o úroveň dál. Kontrola vlastnictví se vztahovala na předplatné serveru, ale relace portálu se otevírala pro záznam zákazníka, který podle návrhu může nést několik serverů.

Kdokoli tedy legitimně nakoupil na jednom serveru, mohl vidět a spravovat předplatná, která stejný záznam nesl pro jiné servery.

Opraveno tak, že se záznam zákazníka určuje z konkrétního nákupu, ne z řádku serveru.

Dvě zjištění, kde kód odporoval našim vlastním podmínkám

Tohle je kategorie, která nás trápila nejvíc, protože není technická.

Blacklist bral zaplacený čas. Naše podmínky říkají, že předplatné končí na konci aktuálního období. Při blokování serveru ale kód volal okamžité zrušení: žádné vrácení peněz a od té chvíle žádná služba za období, které už bylo zaplaceno. Kód dělal něco jiného, než jsme písemně slíbili. Teď zaplacené období doběhne.

Vzdání se práva na odstoupení nebylo prokazatelné. Před nákupem musíš potvrdit, že služba začíná okamžitě. To potvrzení žilo čistě v prohlížeči, nikdy se neposílalo a nikde se neukládalo. Důkazní břemeno leží na nás a my jsme prostě žádný důkaz neměli. Teď je souhlas povinným polem routy pro checkout, ukládá se s časovou značkou a verzovaným zněním, a samotné znění je verzované: existující text se nikdy neupravuje, vždy se vytvoří nová verze, jinak by staré záznamy už nešly reprodukovat.

Druhé kolo bylo horší než první

Po prvních 21 zjištěních jsme se o pár týdnů později podívali znovu. To bylo správné rozhodnutí, protože to vůbec nejzávažnější zjištění vyšlo najevo až tehdy.

Vrácení peněz na serveru B smazalo zaplacenou doživotní licenci serveru A. Oznámení o vrácení peněz a chargebacku jmenují jen platbu, ne server. Řešili jsme je přes záznam zákazníka. Když jsme v prvním kole správně stanovili, že záznam patří kupujícímu napříč několika servery, právě tohle přiřazení už nebylo jednoznačné. Kdo zaplatil za dva servery a za jeden dostal peníze zpět, mohl přijít o doživotní licenci toho druhého.

Přiřazení teď probíhá ve čtyřech přesných krocích a cokoli, co nejde jednoznačně přiřadit, se nahlásí, místo aby se hádalo.

Vyhraný chargeback nic neobnovil. Při chargebacku kód smazal řádek nákupu, jediný doklad, že tento server kdy měl doživotní licenci. Pozdější výhru sporu nešlo vrátit zpět. Teď se řádek označí, místo aby se smazal.

Uchovávání dat mazalo zaplacené servery. Když bot opustí server, jeho data se po 30 dnech odstraní. Tohle čištění se nikdy nezeptalo, jestli k němu není připojené běžící předplatné.

Co jsme si z toho vzali

Chyby nebyly v platebním kódu. Ani jedno kritické zjištění se netýkalo částky, měny nebo výpočtu. Všechna byla v modelu za tím: komu patří záznam zákazníka, komu patří platba, komu patří server. Kdo audituje platební systém tak, že se dívá na částky, dívá se jinam než na tu nebezpečnou část.

Audit potřebuje druhé kolo. Nejzávažnější zjištění bylo přímým důsledkem opravy z prvního. To není náhoda: oprava modelu zneplatní předpoklady, se kterými se jinde pořád počítá.

„Stojí to v našich podmínkách“ je ověřitelná věta. Dvě zjištění byla rozpory mezi tím, co jsme písemně slíbili, a tím, co dělal kód. To se dá přečíst, a nikdo to nedělá, protože to vypadá jako právo, ne jako inženýrství.

Nákupní podmínky v plném znění najdeš v našich obchodních podmínkách, právo na odstoupení v sekci odstoupení.

Další články