Bezpečnost Nette aplikací aneb správné ověření, zda-li uživatel je přihlášen

Petr Parolek
Člen | 455
+
+2
-

Ahoj,

před pár dny díky neúmyslné „chybě“ v testech přes velmi šikovný https://github.com/…enter-tester jsem objevil fakt velkou bezpečnostní díru ve svém systému, útočník mohl poslat post data z formuláře v administraci na přidávání uživatele, mohl se zaregistrovat jako admin a dělat si aplikaci, co chtěl! Tuto díru jsem tam měl několik let.

Dávejte si i na toto všichni pozor při vývoji v Nette

Kod s bezpečnostní dírou

<?php
declare(strict_types = 1);

namespace App\Presenters;


/**
 * Base presenter for all application presenters.
 */
abstract class BaseAuthPresenter extends BasePresenter
{


	public function beforeRender(): void
	{
		parent::beforeRender();

		if (!$this->getUser()->isLoggedIn()) {
			$this->redirect('Sign:in');
		}

	}

}
?>

a správný kod vypadá takto:

<?php
declare(strict_types = 1);

namespace App\Presenters;


/**
 * Base presenter for all application presenters.
 */
abstract class BaseAuthPresenter extends BasePresenter
{


	public function startup(): void
	{
		parent::startup();

		if (!$this->getUser()->isLoggedIn()) {
			$this->redirect('Sign:in');
		}

	}

}
?>

Editoval Petr Parolek (21. 9. 2021 12:44)

Šaman
Člen | 2635
+
+5
-

Obecně všechno …Render… patří vpodstatě do MVC pohledu. V takových metodách by měly ideálně jen předávat data do šablony.

Kcko
Člen | 465
+
+1
-

Nejsem žádný (s)killer v Nette i když s ním už nějaký pátek dělám, ale v životě by mě nenapadlo ověřovat tohlecto v beforeRender, znát životní cyklus Nette je IMHO základ.

Editoval Kcko (21. 9. 2021 16:56)

David Grudl
Nette Core | 8138
+
0
-

Tyhle věci je potřeba vždycky ověřit, už proto, že v názvu startup se dá snadno udělat překlep a pak to taky nebude fungovat.

m.brecher
Generous Backer | 758
+
+1
-

Stejně jako ve formulářích nelze důvěřovat ničemu co přijde jakoukoliv metodou od uživatele a vedle javascriptové validace musí vždy být i serverová validace, stejně tak nelze v principu důvěřovat ničemu co formulář předá ke zpracování modelu. Proto je dle mého názoru naprosto nezbytné mít pro důležité operace s databází neprůstřelnou validaci přímo v modelu.

Model je totiž jádrem celé business logiky – data včetně metadat i validačních pravidel by měly být primárně zde. Potom chybné umístění ověření oprávnění uživatele neumožní útočníkovi průnik do systému. Doporučuji školení @MichalŠpaček na bezpečnost webových apliací, kde jsem se dozvěděl zásadu vícenásobné obrany. Nestačí Nette Framework, nestačí umístit ověření autorizace do startupu BasePresenteru, nestačí javascriptová i serverová validace formulářů, vždycky je dobré mít kvalitně postavený model, který bude neprůstřelný a nepovolí operaci ke které nemá uživatel oprávnění.

Nette Framework ohlídá 50% všech možných bezpečnostních děr a druhých 50% je na správném návrhu aplikace, doporučených postupech, prověřených rozšířeních a na kvalitním testování podle nějakého doporučeného schématu.

Sám jsem před půl rokem zkusil přemýšlet jako @MichalŠpaček – tj. jako kdybych byl hacker a chtěl bych se vlámat do vlastní aplikace. Nestačil jsem se divit, že těch děr jsem tam měl několik. Jako nejlepší řešení mě přišlo dát neprůstřelnou obranu do modelu – vedle dalších opatření.