Bezpecnost aplikace vs komponenty

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
phx
Člen | 651
+
0
-

Zdravim

Konecne jsem se odhodlal napsat tento prispevek. Nekomu to mozna prijde jako blbost, ale sam na sobe obcas pozoruji, ze diky vlastnostem Nette zapominam na bezpecnost aplikace. Schvalne se kouknete na nasledujici kod a reknete zda si myslite ze je to OK.

Predstavte si situaci kdy mate nejakou stranku s nastavenim aplikace kam muze kazdy uzivatel a v zavislosti na opraveni vidi ruzne moznosti. Uzivatel vidi jen neco, administrator vidi vse. I funkci na vymazani databaze (nereste navrh – je to jen priklad, proste neco k cemu by se nemel bezny uzivatel vubec dostat).

Presenter:

class SettingPresenter extends Presenter {

	protected function createComponentForm($name) {
		$form = new AppForm($this, $name);
		$form->addSubmit('ok', 'Vymazat data z databaze')->onClick[] = array($this, 'form_ok_onClick');
	}

	public function form_ok_onClick(SubmitButton $btn) {
		// neco co vymaze vse v DB
	}

}

Sablona:

<html>
<body>
	<h1>Nastaveni</h1>
	<h2>Neco pro uzivatele</h2>
	...
	{if Environment::getUser()->isInRole('admin')}
	<h2>Opravdu vymazat celou databazi?</h2>
	{widget form}
	{/if}
</body>
</html>

Myslite si, ze to je OK?

NENI!!!
Pokud uzivatel odesle spravny POST data tak se komponenta vytvori a databaze se vymaze. FAIL.

Pokud by jste chteli administraci rozdelit na 2 casti (uzivatel vs admin) a v actionForAdmin() zakazat pristup uzivatele tak to je taky FAIL. Komponenta neni vazana na view, ale na presenter. Takze pokud se uzivatel dostane k jakemukoliv view v tomto presenteru tak muze vytvorit i onu komponentu. Pozor taky to plati pro vsechny potomky onoho presenteru.

Dalsi moznost by byla overovat uzivatele v metode form_ok_onClick(), ale to neni KISS, protoze overeni je jiz na 2 mistech (presenter + sablona).

Jako reseni vidim tyto moznosti:

  1. overeni v metode createComponentForm(). Problem je, ze je nutno vytovorit nejakou fake komponentu nebo se vyporadat s vyjimkou „InvalidArgumentException: Component with name ‚form‘ does not exist.“, pri pokusu o pristup k neexistujici komponente.
  2. delit presentery dle prav uzivatelu a pristup k presenteru osetrit v metode startup() + potomci museji mit vzdy vyssi opravneni (admin bude jako posledni potomek).
  3. vytvaret komponenty rucne, kdyz jsou potreba, ale to zase neni hezke vzhledem k vykonu, kdy se napr vytvori nejaka vizualni komponenta a misto vykresleni se presmerovava nekam jinam. Ano jde to napsat inteligentne, ale je to dalsi starost navic.

Tak schvalne, kolik lidi ma diry v aplikaci? Jak to resite? Co je nejlepsi reseni?

Toto tema by chtelo nekde v dokumentaci zduraznit.

Editoval phx (25. 6. 2010 12:52)

22
Člen | 1478
+
0
-

Osobně používám řešení č.2, tedy řeším oprávnění v presenteru a do šablony posílám jen identifikator, jestli se ma to či ono vykreslit danému uživateli nebo ho pošlu na jiný view. Myslím že ověřovat oprávnění až v šabloně není zrovna dobrej nápad…

Editoval 22 (25. 6. 2010 12:27)

phx
Člen | 651
+
0
-

Pokud do sablony posles nejaky bool (je ci neni admin) tak je efekt stejny.

Jedine osetrit ve startup nebo vse VSECH actionXYZ.

Kdyz pises „poslat na jini view“ tak predpokladam, ze posles na jiny view v jinem presenteru. Jinak tam je furt dira:)

Jan Tvrdík
Nette guru | 2595
+
0
-

Ahoj, díky za pěkný příspěvek do fóra. O tomto vím už hodně dlouho a ideální řešení je asi následující:

  1. Pokud lze, tak oprávnění řešit ve startupu (typicky, když má aplikace dva moduly – Front a Admin, tak stačí ochrana v presenteru Admin:Base).
  2. Pokud nelze řešit ve startupu, tak je potřeba hlídat práva v továrničce + v šabloně (to sjednotit nelze, protože v šabloně často skrýváš i další kusy kódu kromě výpisu formuláře – zde např. nadpis).

Poznámka: Ještě bych doplnil, že na první pohled užitečný kód jako tento umístěný v BasePresenteru může vést k velké bezpečností díře.

	// BĚDA VÁM, KDO TOHLE POUŽIJETE!
	protected function createComponent($name)
	{
		$component = parent::createComponent($name);

		if ($component === NULL && class_exists($name)) {
			$component = new $name;
		}

		return $component;
	}

Editoval Jan Tvrdík (25. 6. 2010 13:39)

22
Člen | 1478
+
0
-

no a na zakladě permission to neodchytim?

if ($user->isAllowed('delete'))
{
   form_ok_onClick();
}
Jan Tvrdík
Nette guru | 2595
+
0
-

To záleží, kam tu kontrolu dáš.

Lopo
Člen | 277
+
0
-

osobne v nasom intranete pouzivam overovanie pomocou mierne upraveneho systemu popisaneho niekde tuna na fore – anotacia @secured pred triedou/akciou/etc. presentera ktore maju byt zabezpecene …

pri najdeni anotacie je to overovane voci DB, v ktorej mam zoznam ludi, zabezpecenych veci a povoleni

overenie moze byt aj normalne volanim isAllowed za pouzitia skratky opravnenia

toto mi umoznuje zabezpecit jednotlive funkcie (cele prezentery, pohlady, akcie, …) ale aj casti kodu v sablonach a pod.

pri neprihlasenom cloveku mi to presmeruje na login form a po uspesnom prihlaseni s5 na to co uzivatel pozadoval

pri odopreti pristupu napise ktory clovek je zodpovedny za danu vec a da link na poslanie mailu s poziadavkou o spristupnenie

samotne overovanie pri prihlaseni mam primarne cez localny domain controler, v pripade zlyhania sa skusa este interna DB (ludia zo sesterskej firmy)

Editoval Lopo (25. 6. 2010 13:53)

Jan Tvrdík
Nette guru | 2595
+
0
-

Lopo: Pokud nezabezpečujete ani továrničky, ani submit handlery, ani zpracování dat v modelech, tak je aplikace náchylná na výše zmíněné bezpečností riziko („Komponenta neni vazana na view, ale na presenter. Takze pokud se uzivatel dostane k jakemukoliv view v tomto presenteru tak muze vytvorit i onu komponentu. “).

Lopo
Člen | 277
+
0
-

Jan Tvrdík napsal(a):

Lopo: Pokud nezabezpečujete ani továrničky, ani submit handlery, ani zpracování dat v modelech, tak je aplikace náchylná na výše zmíněné bezpečností riziko („Komponenta neni vazana na view, ale na presenter. Takze pokud se uzivatel dostane k jakemukoliv view v tomto presenteru tak muze vytvorit i onu komponentu. “).

nepovedal by som – @secured mam nahadzane aj pred handlery …

formy spracuvam v render{} a nie cez callbacky, tym padom su osetrene pravami pohladu …
a vacsinu su stejne zabezpecene cele presentery, takze ak clovek nema pravo k presenteru tak nema pravo k ziadnej jeho casti … pripadne aj ak by mal k niektorej casti povolenie ale nie k celemy presenteru, tak zabezpecenie presenteru ma vacsiu prioritu ako niektorej jeho casti

Viem ze to nemam uplne idealne doriesene, ale tuna nema nikto take znalosti aby sa dokazal naburat kam nema a z internetu to neni dostupne vobec

uestla
Backer | 785
+
0
-

Používám ACL – vizte třebas návod zde. Čili ve startup()u BasePresenteru kontroluji povolení přístupu na základě role. Do šablony samozřejmě také posílám booleany, ale to je čistě jen pro vizuální stránku věci – aby se prostě neadminovi nezobrazovaly odkazy na akce, které stejně nemůže provést (byl by odchycen právě na straně severu). A jelikož startup() proběhne dříve než zpracování signálu, je to (doufám ;) ) v suchu…

Editoval uestla (25. 6. 2010 15:22)

Ani
Člen | 226
+
0
-

V nejbližší době se to chystám řešit nějakou univerzální metodou, která bude pro jednotlivé action, zpracování formuláře, továrničky atd. kontrolovat práva někde ve startupu. Myslím, že nějaké takové univerzální řešení je v Nelle, ale zatím sem to moc nezkoumal.
Z hlediska návrhu by mi tohle přišlo nejlepší řešit někde v modelu, ale tam si zas moc neumím představit vracení vyjímek do presenteru (bylo by to až moc robustní).

Editoval Ani (25. 6. 2010 15:25)

Lopo
Člen | 277
+
0
-

dalsie bezpecnostne riziko je napr v nekontrolovani hodnot formu … resp nedokonalom … typicky napr. overenie hodnoty zo select boxu – vacsina sa spolieha ze dostane hodnotu len z pola ktore je v selectboxe

napr vyber mesiaca – overenie ci obdrzana hodnota je v rozsahu 1–12 … taketo veci kontroluje asi malokto (priznavam sa ze ja tiez nie, ale vacsinu mam za tym prepocet obdobi v ramci ktorych sa toto samovolne osetri)

Ani
Člen | 226
+
0
-

Nekontroluje hodnoty ze selectboxu primo nette?

Jan Tvrdík
Nette guru | 2595
+
0
-

Hodnoty selectu kontroluje Nette samo. Pokud dojde v POST požadavku hodnota, která nebyla na výběr, tak se to zachová stejně, jako kdyby uživatel nevyplnil nic.

Jan Tvrdík
Nette guru | 2595
+
0
-

@secured mam nahadzane aj pred handlery

Klasické handlery (navěšené přes onSubmit nebo onClick) takto nelze (AFAIK) kontrolovat (bez upravené definice formuláře). Vzhledem k tomu, že to ale zpracováváš v render fázi (proč vlastně?), tak je ti ale fuk.

pripadne aj ak by mal k niektorej casti povolenie ale nie k celemy presenteru, tak zabezpecenie presenteru ma vacsiu prioritu ako niektorej jeho casti

Tohle mi připadá jako nesmysl. Nedovedu si představit, jak by to vypadalo.

Lopo
Člen | 277
+
0
-

Jan Tvrdík napsal(a):

Hodnoty selectu kontroluje Nette samo. Pokud dojde v POST požadavku hodnota, která nebyla na výběr, tak se to zachová stejně, jako kdyby uživatel nevyplnil nic.

Tak to som si nejako nevsimol … v takom pripade pre mna tym lepsie :)

Jan Tvrdík napsal(a):

@secured mam nahadzane aj pred handlery

Klasické handlery (navěšené přes onSubmit nebo onClick) takto nelze (AFAIK) kontrolovat (bez upravené definice formuláře). Vzhledem k tomu, že to ale zpracováváš v render fázi (proč vlastně?), tak je ti ale fuk.

Mno co som zatial testoval tak som mal pristupy zabezpecene kde bolo treba

>

pripadne aj ak by mal k niektorej casti povolenie ale nie k celemy presenteru, tak zabezpecenie presenteru ma vacsiu prioritu ako niektorej jeho casti

Tohle mi připadá jako nesmysl. Nedovedu si představit, jak by to vypadalo.

Napr. mam prezenter financii … cely je samozrejme oznaceny secured, takze hocico z neho uvidi len clovek ktory ho ma povoleny …

v ramci neho ale mam este dovernejsie informacie … ktorych funkcie su znovu nastavene secured … takze ak nema navyse k nim povoleny pristup, tak sa k nim nedostane … tj na pristup k nim treba uz 2 povolenia …

ak by som mal nejaky prezenter free a len niektoru vec v nom secured … tak po pridani secured na cely prezenter sa k predtym povolenym veciam ludia nedostanu ak im nebude dane povolenie aj na cely prezenter

proste aby clovek mal pristup, tak musi mat pristup ku vsetkemu v retazci spracovania

Editoval Lopo (25. 6. 2010 16:43)

Lopo
Člen | 277
+
0
-

ale ako som napisal – viem ze to nemam dokonale, ale ucel to plni dostatocne pretoze v ramci firmy sa nikdo nebude snazit o naburanie a z vonku je to nedosiahnutelne