Přejít k navigační liště

Zdroják » Různé » Neautorizovaný přístup k datům

Neautorizovaný přístup k datům

Články Různé

V posledních dnech, týdnech a měsících jsem několikrát slyšel a četl o tom, že velkým hráčům unikla nějaká data, případně se někdo dostal k informacím, které vidět neměl, a to naprosto jednoduchým způsobem. „Útočník“ pouze změnil nějaké číslo v adrese stránky a v prohlížeči se mu najednou ukázaly údaje, k jejichž prohlížení nebyl autorizován. Jak je to jen možné?

Nálepky:

Představte si, že nakoupíte někde v oblíbeném e-shopu, na pozadí se vytvoří objednávka, kterou nějak zaplatíte a pak už jen čekáte na svůj vysněný a tvrdou prací zaplacený kryt na telefon. Kryt chrání váš telefon jak se sluší a patří, a vy si koncem března najednou vzpomenete, že by se vám hodila faktura. Takže jdete do zákaznické sekce vašeho obchodníka, najdete vaši objednávku, kliknete na odkaz ke stažení faktury, vytisknete ji a radujete se, když v tom najednou uvidíte v URL nějaké zajímavé číslo.

O půl vteřiny později se ve vás strhne obrovský vnitřní boj, ve kterém zvítězí temná strana síly, kliknete do řádku s adresou ve vašem prohlížeči a naprosto přirozeně a s klidem v duši to číslo změníte, třeba ho o jedničku snížíte. Adresu potvrdíte a najednou, jako mávnutím kouzelného proutku, zapomenete na nějakou vytištěnou fakturu. V prohlížeči se vám totiž objeví detaily objednávky někoho úplně jiného, včetně uživatelského jména, celkové sumy, seznamu objednaného zboží a kupónu na 10% slevu na příští nákup. A poněvadž síla temna jen tak nepoleví, napíšete si jednoduchý skript, který postupně mění ono číslo v URL a stránku vždy uloží a vy tak získáte hezký přehled o finančních transakcích vašeho oblíbeného obchodníka. A taky spoustu slevových kupónů.

Tahle technika není nic nového pod sluncem, většina z nás má podobné návyky zažité z dob stahování obrázkových galerií z webů z kategorie 18+, tam také často stačilo měnit čísla v URL, abyste se dostali k obsahu, na který zrovna náhodou nevede žádný odkaz.

Zatím jsme si popisovali jen co-by-kdyby příklady, ale tohle se opravdu stává i ve světě před monitorem. Nebo vlastně spíš za monitorem. Vzpomeňme službu Facebooku pro zasílání novoročních přání.

Stačilo měnit parametr id a mohli jste si nejen číst cizí pozdravy, ale mohli jste je dokonce i mazat.

Toto drobné vývojářovo přehlédnutí se nevyhýbá ani naším kotlinám. Josef Průša před pár dny zjistil, že dobré jídlo se na 3D tiskárně vytisknout zatím nedá, a tak zkusil do svého prohlížeče zadat www.damejidlo.cz, nějaké to OMNOMNOM si objednat a během té chvilky, která ho dělila od toho, než kurýr zazvoní u jeho dveří, stihl přijít na to, že na stránce s potvrzením objednávky stačí změnit číslo v URL a dostat se na potvrzení objednávky někoho jiného. Na té stránce není nic podstatného, kromě kreditu v hodnotě 5% objednávky, z čehož se dalo jednoduše prozkoumáním všech objednávek za vydatné pomoci matematické operace zvané součet zjistit třeba to, jak si vlastně DámeJídlo vede. Prý žádné citlivé informace.

Asi známější (tzn. psala o něm Lupa) je případ z roku 2009, který se týkal Sazky a jejího e-sázení. Jména a čísla všech sázejících, to jste mohli získat pouhou změnou parametru id. V případu padla nějaká trestní oznámení, no a tak vůbec, byla to legrace. Sazka tvrdila, že data byla náhodně generována, nicméně náhodně vygenerovat jméno Davida Grudla, které se v datech vyskytlo, to asi umí jen generátor náhody od Sazky.

Nejen ve Spojených státech je relativně hodně sledovaný případ chlapíka jménem Andrew Auernheimer (Weev/@rabite). Jeho kamarád Daniel Spitler totiž jednoho krásného dne roku 2010 podojil server AT&T a dostal z něj přes sto tisíc e-mailových adres majitelů iPadu 3G, včetně adres lidí z vlády, armády a pár šéfů fakt velkých firem. Jenom tím, že trochu upravil HTTP hlavičku User-Agent a měnil čísla v URL, resp. posílal na server různé ICCID (19 až 20 číslic). Seznam e-mailových adres pak získal Andrew a o pár měsíců později byli oba dva obžalováni. Ve Státech totiž platí zákon (Computer Fraud and Abuse Act, CFAA) z doby, kdy v Sovětském svazu vybuchovaly jaderné elektrárny, tedy z roku 1986, který říká, že přístup k počítači není autorizován, pokud se tak rozhodne majitel toho počítače. Není třeba tedy hackovat žádné heslo, není třeba někam injektážovat SQL, stačí si jen v prohlížeči načíst stránku. Takže je možné, že i vy, moji milí čtenáři, tento zákon právě porušujete. Stejně tak ho porušili i Daniel a Andrew, pouhou změnou pár čísel v URL, čímž se dostali v podstatě k veřejným informacím. Daniel nakonec vypovídal proti Andrewovi, ten byl shledán vinným a hrozí mu až 10 let v chládku.

Popisovaný problém nesou na svých bedrech vývojáři, zkrátka ukazují data někomu, kdo je vidět nemá. Odhalit tuto bezpečnostní mezeru nemusí být úplně jednoduché, můžete změnit parametr v URL na nějaké číslo objednávky, která v systému neexistuje (nebo je stornovaná) a systém se bude tvářit, že z něj nic nedostanete. Nicméně pokud budete zkoušet vlastní aplikaci, tak asi budete i vědět, jaké číslo máte vlastně zadat, budete znát číslo existující objednávky a podobně. To je asi jediná možnost, jak vaši aplikaci otestovat, tedy dokončit dvě objednávky pro dva různé uživatele a poté zkusit pro jednoho uživatele zobrazit data z té druhé objednávky zadáním jejího čísla.

Z pohledu vývojáře to není tak jednoznačné. Pokud nechcete náhodného návštěvníka měnícího čísla v URL poslat do chládku, tak ve veřejné aplikaci, která posílá data do prohlížeče, nesmíte v podstatě nikdy mít SQL dotaz, který vypadá nějak takto:

SELECT … FROM orders WHERE id = ?

(použití nebo nepoužití prepared statements nemá na popisovaný problém žádný vliv, tento „útok“ nemá s SQL injection nic společného)

Musíte tedy do podmínky vždy přidat uživatelské jméno nebo session id, nebo něco podobného, co jednoznačně identifikuje návštěvníka:

SELECT … FROM orders WHERE id = ? AND username = ?

No a hlavně na to musíte pamatovat pokaždé, když píšete nějaký SQL dotaz, přeju hodně štěstí.

Jako pomyslnou třešničku na dortu, k tomu pamatování, že musíte přidat další podmínku, byste mohli pro účely zobrazování a přenosu v URL použít něco jiného, než číslo objednávky, třeba GUID, které vypadá např. takto: fa4cee73-8cf5-41be-87d7-dede5d160236 nebo rovnou objednávky vůbec nečíslovat lineárně, ale použít nějaké hausnumero, třeba ono zmíněné GUID. Musím dodat, že samotné použití něčeho takového vaši aplikaci samozřejmě neochrání, spolehlivě to však některé jedince odradí od pokusů jakkoliv tyto čísla měnit, je jich tam totiž nějak moc.

Hezkou možností, tedy vlastně spíš vedlejším efektem při přesunu logiky do databázových funkcí, je to, že do každé funkce budete posílat uživatelské jméno. Budete ho mít pořád na očích a snad do té funkce tu podmínku WHERE username = … napsat nezapomenete. A kromě toho se vám to bude hodit později při škálování a rozdělování databází podle uživatelských jmen. A to se vyplatí!

Napadají vás nějaké další možnosti, jak se proti získávání dat pouhou změnou čísel v URL nejlépe bránit?

Komentáře

Subscribe
Upozornit na
guest
51 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
M.

Například před vrácením odpovědi kontrolovat, že je zalogován ten uživatel, který tu odpověď požaduje. Pokud to není on, tak vrátit login dialog…

Rexxar

Do kazdeho SQL query pridavat id pouzivatela je asi overkill. Prava pouzivatela staci overovat v metode controllera (MVC architektura), alebo niekde v uvode kodu.

pb

Hmm, ale jak chcete ověřit práva uživatele? Asi takhle: Patří tohle číslo faktury, na které se tento uživatel ptá, tomu uživateli? Čili jedním SQL dotazem navíc?

(Ikdyž nadruhou stranu, když předpokládáme normální workflow aplikace, tak aby uživatel kliknul na svou fakturu, musel před tím vidět seznam faktur, takže je máme v nějaké cache, takže by to spíš bylo: Dej mi všechny faktury toho uživatele (z cache), a z nich vyber tu hledanou).

Čelo

Implementační detail :)

Rax

Při práci s fakturami pro uživatele je skutečně nutné do každého dotazu vrazit where na ID uživatele a pokud možno ID uživatele vůbec neposílat na klienta, ale schovat ho třeba v session, jinak dochází přesně k tomu co je v článku. Překvapuje mě, že to v roce 2013 stále není všem jasné.

Martin Hassman

Staré a osvědčené věci se musí opakovat znovu a znovu, jinak je další generace nepřijme a vymizí.

Josef Vybíhal

Tímto trpěla samoobsluha Vodafonu pěkných pár měsíců. Člověk mohl měnit číslo v URL adrese a viděl přesně kolik Kč na které telefonní čislo bylo uhrazeno.

Jakub Vrána

Moje zkušenost je taková, že na co se dá zapomenout, na to se taky zapomene. Proto je důležité používat šablonovací systém s automatickým ošetřováním předávaných dat (jako obrana proti XSS, např. Nette Latte) a nějaký sestavovač dotazů, opět s automatickým ošetřováním dat (jako obrana proti SQL Injection, např. NotORM).

Tenhle problém je k vyřešení těžší, ale napadají mě dva možné přístupy, jak mu systémově zabránit:

  1. Místo unikátního ID používat jako primární klíč dvojici (ID uživatele, pořadové číslo). Někdy to je žádoucí i z hlediska použitelnosti aplikace – např. místo příšerného Bug ID 3601407 na SourceForge.net dostanu hezké Issue #22 na GitHubu. V některých případech se hodí i globální identifikátor (např. číslo objednávky, aby se dala snadno identifikovat po telefonu), tam tohle řešení moc dobře použitelné není.
  2. K tabulce zakázat přístup na úrovni databázových práv a vytvořit uloženou proceduru get_order(user_id, id). V administraci, kde potřebuji přístup ke všem objednávkám, použijeme jiného databázového uživatele, který má přístup i k samotné tabulce. To neztrácí výhody globálního ID, ale je trochu těžší na nastavení a používání.

Pak je tu samozřejmě ještě případ, kdy žádné ID uživatele nemám. Tam se dá aplikovat druhé řešení, jen místo user_id použijeme náhodný token. Použití GUID je v této situaci také možné, ale je potřeba dodat, že v jiných případech je spíš nevhodné. Inkrementace nebo hádání ID totiž není jediný způsob, jak se útočník může k datům dostat – ta můžou někde uniknout a pokud na jejich neuhodnutelnosti stavím zabezpečení, tak jde o pouhé Security by Obscurity.

Rax

1. Primární klíč na fakturu je vždy ID z generátoru nebo autoincrementu a přes to nejede vlak. Navíc pořadové číslo faktury nelze u nové faktury před jejím commitem stanovit spolehlivě, proto ho nelze ani vrazit do primárního klíče a proto se faktury číslují dodatečně v druhém kroku.

2. Do databáze chodí webový server celou dobu pod jedním uživatelem.

Pro URL faktur lidí bez účtu se použije něco jako magic + údaje pro vyhledání faktury + salt dohromady 64 a víc byte to celé zašifrované solidním algoritmem se solidně dlouhým heslem + převod do tvaru vhodného pro URL. Bezpečnost je pak garantována kvalitou šifrovacího algoritmu a kvalitou hesla.
GUID je možné také, ale to se pak musí někde ukládat a opečovávat.

Jakub Vrána

2. Že je to takhle na většině hostingů, ještě neznamená, že to není možné.

Cílem bylo navrhnout řešení, které by fungovalo automaticky, aniž bych na něco mohl zapomenout. Vámi popisované řešení je nejen zbytečně překomplikované, ale této podmínce se ani neblíží.

china

2. bezpecnost na urovni databaze je zaklad kazde seriozni aplikace. To, ze cela aplikace pouziva jednu uroven opravneni se da jete akceptovat u nejakeho soukromeho webu, kam si pise majitel co mel zrovna k obedu ale u business critical aplikaci je to naprosto neakceptovatelne.

Cermi

Proč tak složitě? Já osobně jsem pro takové věci implementoval „kontrolní“ hash pomocí nějaké HMAC funkce (hashovací fce s klíčem), který se hodil do URL v mailu. Má to tu výhodu, že to umožňuje i anonymní požadavky (ve smyslu objednávky), což někdy může zákazník chtít.

Rax

Protože kreativita útočníků je vskutku neuvěřitelná a čím méně toho ví, tím lépe.
Samozřejmě na jednoduchý webshop jde HMAC použít také.

Karel

Nejjednodušší je opravdu dotazy psát stylem „where orderno = .. and userid = …“ nebo „where orderno = … and user_authorized(­…)“. Přičemž to userid zná jen server, v URL se neobjevuje. Server si ho může zapamatovat buď při přihlášení uživatele, nebo ho může vygenerovat při „přihlášení uživatele“. V uvozovkách je proces, kdy uživatel na serveru vlastně žádný účet nemá. V tomto procesu si server vygeneruje dvojici – userid a randomid. Do databáze si uložím tuto dvojici, na klienta jako cookie předám randomid (nebo bude součástí url). Když se pak někdo dotáže, tak já si přeložím randomid na userid a dotaz provedu. Jakmile dojdu k názoru, že už se na to podívat nesmí, tak jen smažu záznam z překladové tabulky, takže už nikdo ani „správné“ userid nepodvrhne.

K přístupu k „cizím datům“ je tedy potřeba znát číslo objednávky a randomid. Randomid má jen omezenou časovou platnost (např. datum dodání + 1 den) a navíc může být (narozdíl od čísla objednávky) skutečně náhodné. V případě potřeby se k němu dá přidat něco dalšího, co není snadné podvrhnout – například IP adresu. I v systému, kde se uživatelé neregistrují, tak není problém zabránit cizím lidem si číst data. Problém je ovšem v tom, že si pak ta data po čase nepřečte ani původní objednatel. To je ale daň za anonymitu.

greeny

Napadá mě řešení – každá objednávka dostane ID, které je unikátní pouze pro daného uživatele – může např. existovat více objednávek č. 3.

Je to jen malinko upravené, ale pomůže to taky…

Ja

mapovanym na skutecne id v tabulce 1:1 a selecty z joinu, co?

Michal

To si děláte srandu že http://www.damejidlo.cz nepoužívá nějaké ACL, ne? IMHO se bez objektového ACL větší tohoto typu aplikace neobejde. Vždyť je na to i tutoriál v Nette pro začátečníky.

roman

Si robite srandu, ze sa autorizacia bez objektov neda naprogramovat?
Ale pokial je tam Nette ok :)

Petr

Rád bych tady pod článkem ještě jednou poděkoval panu Průšovi za report chyby. Chyba byla na základě jeho podnětu opravena.

Opravdový odborník :-)

„Hausnumera“ a GUID jsou jen obskurnost, která neřeší primární problém — uhodnout GUID je sice těžší než uhodnout vzestupně rostoucí ID, ale problém je jinde – v tom, že útočník na základě znalosti nějakého ID obdrží data, která obdržet nemá. Navíc je to systémové špatné řešení, protože míchá dohromady dvě věci: identifikaci objektu a autorizaci uživatele resp. řízení přístupu k obejktu. Je to asi jako kdybyste na disku schovali data do souboru, jehož název nikdo nezná (nebo si to alespoň myslíte). Chyba. Správné řešení je použít příkaz „chmod“ – jednoduché a čisté.

Vložení UID do podmínky v SQL dotazu je naopak dobrá cesta – nepotřebná data se do aplikace ani nedostanou a nelze je zneužít. Má to ale jednu nevýhodu: nelze rozlišit, zda objekt neexistuje nebo zda k němu jen uživatel nemá práva. Většinou je to v pořádku, protože ošklivému útočníkovi nepotřebujeme sdělovat, zda trefil ID objektu nebo ne. Ale někdy je to na škodu – uživatel potřebuje vědět, že nemá práva, aby si o ně mohl zažádat a nebyl zmatený/vyděšený z toho, že daný objekt neexistuje.

Používání databázových procedur však nijak nepomůže. Uložené procedury jsou sice užitečné a jsem pro jejich používání, ale tento problém neřeší – je implementační detail, jestli tohle vyřešíme na úrovni aplikace nebo databáze – zapomenout na kontrolu je možné na obou místech. Stejně je potřeba ošetřit případy, kdy data nežádá běžný uživatel, ale správce nebo systémová úloha.

Rax

A kam si opravdový odborník schová UID pro objednávky vytvořené ad-hoc, tedy uživatel nemá účet, když se mu Hausnumera a GUID nelíbí ?

Opravdový odborník :-)

Každý uživatel má účet resp. záznam v naší databázi, i když třeba nezná svoje heslo. Je zbytečné (a nebezpečné) vytvářet nějakou alternativní cestu pro přístup k datům pro neregistrované uživatele.

Rax

A jak se pak dostane k faktuře když nezná heslo a GUID a Hausnumera nejsou povoleny, nějak takhle ?

https://xxx.cz/faktury.php?uid=42&faktura=4242

Opravdový odborník :-)

To byste si měl jít někam dostudovat, když to nevíte. Ale budu tak hodný a řeknu vám to.

Uživatel bude už přihlášený (relace v prohlížeči – cookies) nebo se přihlásí pomocí jednorázového tokenu (ano, „hausnumero“), nicméně tento token slouží k přihlášení, nikoli k identifikaci objektu (např. objednávky).

Tyto dvě činnosti (přihlášení uživatele vs. identifikaci objektu) je potřeba oddělit (byť to můžou být dva parametry v témže HTTP požadavku, nicméně jsou na sobě nezávislé).

Rax

No já to právě vím, proto čekám co z vás vypadne a vypadlo hausnumero :-)
Problém přihlašování hausnumerem je identický jako problém zobrazování faktury přes hausnumero. Pravděpodobnost uhodnutí 32-bit id faktury + 64-bit hausnumera je +- stejná jako pravděpodobnost uhodnutí 96-bit hausnumera přímo na fakturu.

Opravdový odborník :-)

1) „hausnumero“ není jediná ani první možnost, o které jsem psal.

2) O uhodnutelnost tu vůbec nejde (v obou případech je potřeba použít kvalitní generátor náhodných čísel a dostatečně dlouhé číslo, aby to bylo o několik řádů výš, než co se dá „uhodnout“). O co tu jde je vnitřní složitost aplikace – přístupová práva ověřujeme jednotně (podle aktuálně přihlášeného uživatele) a nevznikají nám tu alternativní větve a dodatečná složitost způsobená tím, že bychom za určitých okolností (přítomnost hausnumera) ověřovala přístupová práva jinak. Kromě toho až příště bude potřeba povolit přístup k jiné entitě, bude se nám duplikovat kód i data. Může to být další objednávka téhož uživatele se třeba bude chtít podívat nejen na fakturu, ale i na objednávku – nakonec to dopadne tak, že datový model bude zaneřáděný a v každé tabulce bude nějaký sloupeček s „hausnumerem“ – místo abychom evidovali jen ID uživatele a tokeny měli jednoduše na jednom místě napojené na uživatele. Proto jsem psal, že je dobré oddělit autentizaci/au­torizaci od identifikátorů objektů.

Rax

Tomu rozumím, mě celou dobu jenom zajímalo jak jste to dokázal bez hausnumer a tedy jenom jste převedl hausnumero z objednávky na usera a říkáte tomu token.

Problém s eliminací zaneřádění datového modelu řeší můj příspěvek z 23.1. 12:22, tokeny ani hausnumera vůbec není třeba do DB ukládat.

Opravdový odborník :-)

Použití kryptografie (v tomto případě spíš hashování než šifrování) může být elegantní (ale i zrádně nebezpečné, pokud se to udělá špatně), ale pořád to neřešít ten problém, že máme více způsobů, jak ověřit práva uživatele k objektu. Z architektonického hlediska mi to přijde špatně a zbytečná složitost – v prvním kroku bych „přihlásil“ uživatele (to může být víc způsobu – klasické jméno/heslo nebo token nebo ještě něco jiného) a v dalším kroku ověřoval práva a dělal všechny ostatní věci (už vždy stejným způsobem – jednotně – bez ohledu na to, jak se uživatel přihlásil). Další věc, na kterou jste zapomněl, je, že je dobré umět spárovat různé objekty patřící jednomu uživateli (více objednávek, více faktur, otázky odeslané přes kontaktní formulář, dotazy ve fóru atd. – vše je dobré mít propojené a evidovat tu entitu „uživatel“).

j

Zeby mel uzivatel trebas session ID co? A ze bych trebas tu session overoval pri praci s tim, co zrovna tvori, co? Nejaky IDcka v linku sou naprosto nezajimavy.

Jan

Čo je zlé na metóde kde url je v tvare: /detail-objednavky/?hash=sha­1(uniqid(micro­time(), true)) ?
(za predpokladu že každá objednávka má stĺpec s náhodným hashom, ktorý je unique)

Pravdepodobnosť že by niekto uhádol 40 miestny kód je velmi malá, netreba žiadne id užívateľa (len málo užívatelov si v obchode vytvorí účet).

expert

Mas poneti, jak funguje hashovani? Pak bys nenapsal takovou blbost. I sebelepsi hash je tak bezpecny, jak nahodny (velky) je jeho vstup.

Predpokladat, ze se bezpecnost zvysi, kdyz ze vstupu ‚xmvkfdkl‘ hashovanim vypocitam vystup ‚csdckliovjev­jioajdsasnkjas­vnjk‘ je samozrejme blbost.

Hash ma smysl jen tehdy, je-li definicni obor mnozina vetsi nez mnozina oboru hodnot hashovaci funkce. Je zrejme, ze uniqid(microtime(), true) negeneruje vetsi mnozinu nez sha1(uniqid(mi­crotime(), true)).

Jan Pobořil

Tady se dobře projevilo, že psát si aplikace na koleně (bez frameworku) je bezpečnostní hazard. Třeba v Drupalu je to jen o konfiguraci, všude pak hlídá, jestli uživatel má oprávnění k stahovanému souboru přistupovat.

diverman

No ale co kdyz nejsi ten, kdo pise ty aplikace, ale ten framework?

Jan Pobořil

Tak by ten framework měl být odkázán na to, že ho bude používat na složitější aplikace jen pár šílenců (WordPress, Joomla :-)).

Žijeme ale v realitě, kde kvalita ne vždy vítězí a tak musí vycházet tyto články. :-)

Honza

Aha, takže vy říkáte „je hazard, abych zabezpečení dělal já, je lepší se spolehnout na framwork“. Čili vy zabezpečení nerozumíte a neumíte to, tak tam radší dáte framework, protože ten to má vyřešené.
Jestli to berete takhle, tak je největší hazard, abyste na to vůbec sahal, protože slepým nabastlením frameworku lidmi, kteří tomu vůbec nerozumí, vznikají nejhorší paskvily.

Framework je dobrý sluha, ale zlý pán – pokud mu rozumíte a víte přesně, co dělá, tak je správné ho využít, protože vám ušetří práci. Pokud je ale framework chytřejší než vy, tak ho nepoužívejte, protože ho použijete špatně a výsledek bude (ne)fungovat úplně jinak než si představujete.

j

Jiste, framework vyresi bezpecnost sam od sebe … lol … tohle muze psat opravdu leda mamlas. Framework vyresi proste podle vyjadrovani nekterych tady uplne vsechno … a proto mame tisice frameworkovych webu a miliony der v nich.

Karel

K te bezpecnosti spousta vyvojaru si verzuje sve scripty bohuzel ne uplne chytre napriklad radi pouzivaji neco.php.bak nebo cislovani, na tom by nebylo nic zleho kdyzby upravily htaccess, protoze se mi parkrat stalo ze sem na podobne stranky narazil kdyz sem neco hledal v googlu.
Googl mi takto jednou hezky ukazal zdrojovy kod jednoho eshopu. A co sem nevidel diru v sql, a ma temna strana se taktez probrala k zivotu, netrvalo dlouho a sesmolil sem asi 30znakovy text, vlozil jej do inputu pro zaslani hesla na email, a zachvyli mi server poslal vypis vsech svych uzivatelu vcetne hesel.

j

Zdrojak v principu ale neni problem, problem je prece ta dira, a na tu by se dalo prijit i bez nej, i kdyz mozna by to trvalo, ze … ostatne, v pripade php a spol (tedy interpretovanych jazyku) s tim clovek proste musi pocitat. Nemusi to byt chyba v nastaveni, staci kdyz nekde neco z nejakeho duvodu zbuchne … a to muze dycinky.

koudy

V dobe GITu a podobnych udelatek mi prijde kazdy, kdo si dela verzovaci system zpusobem file.0.1.1.bak jako blazen!
Vzdyt staci mit 2 adresare – 1 testovaci a jeden „produkcni“.
Ani to nemusite zalohovat, ale predpokladam, ze budete mit git na serveru (kvuli testovani) a u sebe na pracovni pc/ntb a mate rovnou i „zalohu“.

Opravdový odborník :-)

Mít verzovací systém na serveru je jen o trošku menší bastl. Je to použitelné maximálně tak při vývoji/testování (v rámci vývoje, ne AT). Pro seriózní práci se používají balíčky, které se na server nasadí/nainstalují.

maio

Pouzivam 2 pristupy:

1. Validuji vstupy – a to nejen, ze ID je cislo, ale i to jestli je validni pro prihlaseneho uzivatele. Je to o 1 query navic, kazdopadne z hlediska performance to nestoji temer nic. Vetsim problemem je, jak uz bylo zmineno, ze na to muze clovek zapomenout.

2. Nepouzivam primo SQL dotazy, ale dotazuji se objektu. Takze pokud chci treba objednavku ID 123 tak napisu $orders->query->where(„id = ?“, 123) s tim, ze $orders je treba OrdersForUser(‚fran­ta‘) a metoda getQuery zajisti, ze tam bude pokazde i where(„user = ?“, „franta“). Pak se nemuze nikdy stat, ze vratim neco spatne – staci pohlidat, ze $orders je spravne skonstruovan, ale to je temer jistota, protoze se to deje jen na 1 miste v cele aplikaci.

juzna

Přijde mi nesmyslné, že je trestné změnit si číslo v URL a dostat se tak k cizím datům. Pokud má někdo nést odpovědnost za to, že takto někdo neoprávněně získal data, tak by to měl být snad provozovatel aplikace / webu. Nezabezpečil totiž pořádně data jemu svěřená.

Díky tomuto článku by se snad i laická veřejnost mohla dozvědět, že ono slavné hackování není žádná magie a super extra nelegální činnost, ale že je to ve skutečnosti úplně jednoduché.

https://tomasfejfar.mojeid.cz/#bLGPpVT97A

Je to trestné ze stejného důvodu, jako je trestné ukrást odemčené auto. To, že to jde snadno neznamená, že by to nemělo být trestné.

Flašinet

Tady je ale zcela odlišná „obvyklá praxe“. Zatímco auta nebývají volně k dispozici pro kolemjdoucí, u informací na Internetu je to naopak zcela běžné.

Jenda

Vy opravdu nejste schopen poznat, jestli v případě DámeJídlo ta data pro vás byla nebo ne?

juzna

Když bych přijel na parkoviště, dal hlídačovi klíče a on mi odpověděl: „Vaše auto jsme zaparkovali na místě 133“. Já bych pak přišel a řekl: „Mám auto na místě 134 a on mi to auto dal“. A ještě bych dodal „a pak mám taky auta na místech 135, 136, 137, …“

Jenda

Ano, i toto by bylo trestné (pro vás a nejspíš i pro toho hlídače).

JeanSolPartre

Když chceme zajistit autorizovaný přístup k datům jen dotyčnému uživateli
1.uživatel je bezpečně autorizovaný, to tu nepadlo, chtěl bych si napsat javascript generátor jednorázových hesel, poprvé se pošlou hashe, pak se už stále pozná že jis tem, za kterého se vydáváš.
2. uživatel vidí virtuálnmí tabulky s právy SELECT a INSERT (nikoli UPDATE a DELETE)
3. má k nim systémový p

Dělám eshopy a můj framework osCommerce používá kombinace sessions_id a tokenu. Mě to zatím stačilo (když jsem zhruba ve stejné době jako autoři OSC pochopil že je třeba mít token aby se sessions nekradly) a soustředil jsem se na dvě další patra.

– zámek na úrovni řádků databáze, který tady mezi jinými okrajově zmínil Jabub Vrána
pomocí view, ve kterém se uživateli založenému pro zákazníka filtrují do virtuální tabulky jeho data), možná že Jakub Vrána to dělá chytřeji, já pro jistotu zakládám nového uživalte, která má neuhodnutelné nejen heslo ale i username, kdyby se zase v MySQL objevil podobný bug jako když bylo možné heslo známéhjo uživalele uhodnout… )

– citlivá data jsou zašifrována Vernamovou šifrou (znak po znaku je transponován náhodným řetězcem, matematicky neprolomitlené) k rozšifrování dojde po autorizaci každého požadavku zvlášť a rošifrované data jsou klienetem po přečtení smazána.

Tohle všecho mi více-méně funguje za cenu zatím obvykle nooo až několikahodinové konfigurace … trápí mně ještě problém vstupní autentizace, aby byla softwarová a dvoufaktorová, třeba skvencí jednorázových hesel…

JeanSolPartre

1.uživatel je BEZPECNE autorizovaný
2. uživatel ma prava jen k virtualnim tabulkam
3. citliva data jsou zasifrovana

ad 3. Ja jeste resim, ze fozsifrovani rozhoduje pro kazdy jednotlivy SQL dotaz samostatny crypt server jako nezavisla instance, ktera se rozhoden, jestli je pozadavek na rozsifrovani duveryhodny a nebo podvrzeny.

antiamík

Takže je možné, že i vy, moji milí čtenáři, tento zákon právě porušujete.
– Nikoho tady nemusí nějakej amíckej zákon zajímat, takže to je absurdní tvrzení.

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.