Hlavní navigace

Přihlašte se QR kódem

10. 5. 2015 19:35 (aktualizováno) | Ondřej Novák

Titulek článku není úplně přesný, správně by nadpis měl znít „Přihlaste se oskenováním QR kódu“ – Je to sice dlouhé, ale lépe vystihuje následující obsah. Chtěl bych totiž představit svůj „mini-projekt“ bezpečného přihlašování v prostředí internetu. Něco, co by mělo nahradit velice nebezpečné přihlašování jménem a heslem.

Obrázek

Myšlenka přihlašování oskenováním QR kódu není nová. Asi nejznámější a nejpropracovanější projekt je SQRL od GRC (společnost se proslavila zejména produkty SpinRite a ShieldsUp). Projekt je ve vývoji už od roku 2013 a přímo na stránkách GRC si lze přečíst jejich 20 stránkovou dokumentaci – přičemž se zde stránkou myslí stránka v prohlížeči. O podobný nápad se také kdysi pokoušel i Google – projekt sesame – nicméně dnes mi patřičný odkaz na službu vrací obrázek rozbitého robota a kód 404. Z existujících a zřejmě fungujících projektů jsem objevil pouze getclef.com, který sice nenabízí přihlášení QR kódem, za tímto účelem používá jakýsi „poskakující bar-kód“ (ve skutečnosti je to CODE128 a to nemusí ani poskakovat), uživatelský zážitek je ale podobný, prostě se oskenuje obrazec a po zajímavém grafickém efektu je uživatel přihlášen. Společnost se chlubí 62 tisícími instalacemi, záhy však zjistíte, že k reálnému nasazení budete potřebovat proprietární aplikaci, proprietární protokol, připojení na cizí servery a minimálně $299 měsíčně.

Tolik k úvodu, měl by zhruba shrnovat všechny nevýhody, které jsem v nalezených projektech viděl a proč jsem se rozhodl přijít s vlastním řešením. Kladl jsem si za cíl zejména příjemný uživatelský zážitek a zároveň relativně vyšší bezpečnost a to jak ze strany uživatele, tak ze strany provozovatele nějaké služby, do které se uživatel chce přihlašovat. A tak vznikl QRlogin, projekt, který by měl znovu vrátit do hry přihlašováním přes QR kód. V čem by měl být vlastně jiný?

QRlogin je systém přihlašování oskenováním QR kódu, který si vystačí s běžnou QR čtečkou a běžným prohlížečem (aspoň na úrovni standardního webview v Android 4.0, ale zvládla to i starší Opera). Proces přihlašování přitom zajišťuje identifikační server, který provádí zobrazení QR kódu a download patřičné javascriptové aplikace do zařízení (v tom QR kódu je přece nějaké URL). Kladl jsem důraz i na bezpečnost, a tak jsem pro přenos a ověření identity z telefonu k poskytovateli služby použil systém podepsání výzvy přes ECDSA. A abych se maximálně vyhnul vymýšlení kola a později ladění jeho bezpečnostních problémů, sáhl jsem po systému, který byl vynalezen už někdy v roce 2008 a od té doby čelí dosti brutálnímu útoku na prolomení – řeč je o bitcoinovém protokolu, který také ECDSA používá na podepisování transakcí. Doslova jsem použíl knihovny pro práci s bitcoiny, abych zaručil bezpečné podepsání přihlašovací výzvy.

Jak to tedy funguje?

  1. Uživatel sejme QR kód, který obsahuje challenge (pokaždé náhodnou sekvenci znaků)
  2. V telefonu se mu otevře stránka s aplikaci (psaná v JS)
  3. Aplikace vyzvedne z localstorage soukromý klíč a tím výzvu podepíše
  4. Podepsaná zpráva putuje přes server k poskytovateli služby
  5. Poskytovatel služby ověří podpis a získá veřejný klíč. Protože nikdo jiný, než držitel soukromého klíče není schopen zprávu podepsat, může veřejný klíč použít k nalezení uživatele v databázi a jeho přihlášení na webové stránky. V QRloginu se z veřejného klíče sestavuje bitcoinová adresa, která se nakonec používá jako index do databáze. Je to proto, aby k ověření bylo možné použít standardní bitcoinovou knihovnu bez nutnosti ji dodatečně upravovat.

Je to dost podobné jako přihlašování pomocí SSH při použití soukromých klíčů. Je samozřejmě jasné, že při prvním přihlášení do služby je třeba veřejný klíč spárovat s konkrétním účtem, ale to už je záležitost poskytovatele služby, aby to nějak zařídil.

Jak to celé funguje z hlediska uživatele nejlépe vystihuje toto video:

Bezpečnost

Protože jde o kritické osobní údaje, jistě je zajímavé vědět, jak je to s bezpečností. Na první pohled je vidět, že systém je bezpečnější než kombinace jmeno/heslo, protože odposlechnutím komunikace mezi telefonem a cílovou službou není možné odhalit soukromý klíč (heslo se přenáší v čistém textu a útočníkovi může v cestě maximálně stát protokol https a i tohle není zas tak obtížné překonat). Útočník může odposlechem získat veřejný klíč, který mu ale k ničemu není, protože cílová služba očekává podpis z něhož si veřejný klíč vypočítá. Přihlášení pomocí QR kódu se tak z hlediska zabezpečení dostává na úroveň SSH klíčů.

Phishing.

Přihlašování QR kódem bylo kritizováno z hlediska snadnějšího phishingového útoku. Uživatel totiž může oskenovat libovolný QR kód, i takový, který mu zaslal útočník. Nevědomky tak útočníkovi vystavit povolení k přihlášení. Je to na stejné úrovni, jako když útočník vytvoří falešnou stránku s přihlašovacím formulářem a odkaz na ni pošle uživateli e-mailem, případně po sociální síti. U QR přihlášení jde o to, že uživatel může získat falešný pocit bezpečí. Je třeba uživatele varovat, že naopak u QR přihlašování hraje kontrola domény, pro kterou se přihlašuje, mnohem zásadnější úlohu. QRlogin přitom zobrazuje jméno domény v telefonu a vyžaduje vydání souhlasu. Aby uživatel nebyl zmaten, doporučuji, aby služba otevírala portál s QR kódem (stránka, ve které je zobrazen QR kód) v IFRAME. Prohlížeč nadále zůstane na URL služby (doména bude odpovídat). Tohle je rozdíl oproti třeba přihlašování Googlem, kdy dochází k opuštění původní služby, přesměrování na Google a po přihlášení  přesměrování zpět. Důvodem je také to, že na Google má uživatel zpravidla jeden jediný účet, zatímco u QRloginu má tolik účtů, kolik již navštívil stránek. A protože QRlogin může provozovat kdokoliv, je samotná adresa portálu bezpředmětná, uživatel v tomto případě musí věřit službě do které se přihlašuje, že má portál pod svou kontrolou (ať už přímo, nebo prostřednictvím nějakého smluvního vztahu).

Soukromí

Přihlašovací systémy založené na IdP (identity provider – což je třeba portál na qrlogin.novacisko.cz) jsou často zneužívány ke sledování aktivity uživatelů. Jen kolik informací o uživateli si vede Facebook nebo Google. Nejen to, díky tomu, že se v těchto systémech často uživatel identifikuje unikátním ID, lze aktivity uživatele sledovat i na straně poskytovatele služby, který má přehled o tom, které jeho služby uživatel navštěvuje (případně tyto údaje může sbírat agentura, která „vidí“ do více poskytovatelů). Naproti tomu QRlogin pro každou doménu vede jiný soukromý klíč, takže na každé službě bude uživatel mít jiné unikátní ID. Platí to i v případě, kdy portál QRlogin provozuje někdo třetí na jiné doméně (protože QRlogin je open-source). Ani tento provozovatel nemůže z principu vidět klíče ostatních provozovatelů, protože nejen cílová doména služby, ale i vlastní doména IdP brání k přístupu do úložiště jiných domén (generická vlastnost localstorage)

Ochrana proti ztrátě.

Při představování projektu mezi svými kolegy a na Paralelním Polisu v Praze se objevovaly dotazy, jak je řešena situace, kdy uživatel ztratí telefon, nebo je mu ukraden, případě si smaže úložiště v prohlížeči. To byl v celku zásadní problém, který řeší až poslední verze (aktuálně v1.2), která umožňuje uživateli snadno zálohovat klíče v počítači nebo na papír, přičemž na papír je vytištěn QR kód, který lze oskenováním použít k obnově klíče. Lze takto jeden klíč sdílet i mezi více zařízení – ale nedoporučuji to, je lepší, když služba umožňuje spárovat s jedním účtem vícero identit.

Integrace do webové stránky

Při návrhu systému jsem se také zabýval otázkou snadné integrace do existujících přihlašovacích systémů. Nakonec jsem zvolil protokol OAuth 2.0 s drobnými zjednodušeními, ale i tak plně kompatibilní s OAuth klienty. Tím zjednodušením je fakt, že se není třeba nikam přihlašovat přes client_id a client_secret, protože přihlašovací portál jako rozhodující informaci používá doménu z redirect_uri a to je rozhodující pro určení služby. client_secret není potřebný také proto, že OAuth server poskytuje pouze jediný údaj a to veřejný klíč uživatele, který, jak jsme již napsal, není prakticky kritickou informací – útočník jeho ukradením nezíská žádnou výhodu, uživatel maximálně utrpí drobnou ztrátu soukromí.

Vyzkoušet si QRlogin můžete v oauthplayground, musíte akorát v konfiguraci vybrat možnost vložit vlastní endpointy

  • Authorization endpoint: https://qrlogin.novacisko.cz/auth
  • Token endpoint: https://qrlogin.novacisko.cz/token
  • Identitu pak získáte na url: https://qrlogin.novacisko.cz/ident (GET, Authorization Bearer)

Praktické využití pak vyzkoušíte na cvičném diskuzním fóru forum.novacisko.cz. Jak už jsem psal výše, je dobré, když se integrace provádí v IFRAME tak, aby uživatel mohl porovnat doménu na obrazovce s doménou v telefonu.

Zabezpečení proti provozovateli

Jako poslední jsem si nechal otázku jak je zabezpečen QRlogin proti samotnému provozovateli portálu. QRlogin je k dispozici zdarma v podobě zdrojových kódu, kdokoliv tedy může rozjet vlastní portál, ať již pro své webové stránky, nebo jako poskytovatel služby třetím stranám. To je také jediná a nejlepší ochrana, jelikož, jak bylo řečeno, klíče jednotlivých domén jsou ukládány odděleně, nemůže jeden provozovatel číst klíče jiných provozovatelů (z principu to není možné). Pokud jeden z provozovatelů modifikuje kód, aby ukládal soukromé klíče, poškodí maximálně sám sebe (svou pověst) a všechny služby, kterým poskytuje identifikaci. Provozovatelé služeb a webový stránek si mohou rozjet vlastní portál a získat tak nezávislost. Z hlediska uživatelského zážitku se přitom nic nemění, uživatel nemusí nikde nic přepínat ani nastavovat, protože z jeho pohledu se ovládání nemění.

Samotná JS aplikace nikterak nesnižuje bezpečnost třeba tím, že by byla snadno modifikovatelná ze strany provozovatele přihlašovacího portálu. V dnešní době automatických aktualizací není problém libovolně měnit nativní aplikace v telefonu kolikrát bez vědomí uživatele.

Závěrem

Zdrojáky k systému QRlogin jsou k dispozici na https://github.com/ondra-novak/qrlogin. Na GitHubu také probíhá hlavní vývoj. Portál je postaven z části na specializovaném serveru v C++ a hromadou javascriptu a HTML. Budu rád, když kdokoliv přispěje k vývoji třeba tím, že to vyzkouší, nasadí, pošle něco do issue trackeru, nebo to i forkne a pošle mi občas nějaký ten pull request. Případné příspěvky na vývoj zasílejte na  18BSM9B1dZTMGcLfs2Dck868fjgwrwhjk4