bezpečnost ID v hidden prvku
- basovnik
- Člen | 23
Ahoj, poradili byste mi jak zapezpečit ID v hidden prvku
ve formuláři, aby při ruční editaci (např. přes firebug) zůstala
uchována původní hodnota po odeslání? Našel jsem témata různá ohledně
prvků hidden
, ale žádné nějak neřešilo tento problém. Snad
jen SafeHiddenField.
Také jsem četl něco o atributu hidden prvku forcedValue
, ale
nějak nevím, jak tu hodnotu naplnit. Je to úplně základní problém, který
museli asi řešit všichni. Omlouvám se, zda se to už někde řešilo, ale
žadné setDefault
ani druhý parametr v addHidden
,..
nic nezabralo…
- Filip Procházka
- Moderator | 4668
Paranoia.
Když si v systému změníš ID upravovanýho záznamu a přepíšeš tak jiný, je to tvoje blbost. Pokud upravuješ něco co vytváří více lidí (komentáře, články, …) pak máš mít přístup pouze ke svým záznamům a aplikace ti nemá dovolit ostatní upravovat.
Z principu by ti aplikace neměla dovolit upravit něco, na co nemáš oprávnění. Pokud to upravíš regulérním proklikáním se k tomu a nebo si změníš ID hiddenu v html, je to jedno.
Systému by to mělo být jedno, tobě by to mělo být jedno.
Nastuduj si ACL.
Editoval HosipLan (22. 7. 2011 8:07)
- JakubJarabica
- Gold Partner | 184
Načo potrebuješ ID v hiddene? Zvyčajne stačí pracovať s $this->getParam().
- basovnik
- Člen | 23
Asi mate pravdu… reseni je kontrolovat pristup k zaznamu i po odeslani
editacniho formulare… resil jsem opravneni editace jen pri vstupu do editacni
sekce a pak uz ne, takze uzivatel mohl teoreticky v nejake utilite zmenit id a
neco neopravnmene prepsat. Nejlepsi reseni to je kontrolovat asi pred i po, jak
pisete… Nebo použít to getParam('id')
a nedat mu moznost zmenit
id v hidden prvku.
Dekuji!
Editoval basovnik (22. 7. 2011 15:33)
- JakubJarabica
- Gold Partner | 184
Ono ak sa bavíme o nejakej actionEdit($id), tak je dobre hneď v action kontrolovať ID, plniť setDefaults bez nutnosti hiddenu a pri odoslaní sa vykoná to isté, len naviac sa zavolá signál na spracovanie formu, kde je už zvalidované z action $this->param[‚id‘] (dokonca property access už pri overenom parametre)… Tak nie je treba používať hidden. Či to má nejakú muchu…?
- Jan Tvrdík
- Nette guru | 2595
JAM3SoN wrote:
je dobre hneď v action kontrolovať ID (…) Či to má nejakú muchu…?
Pokud kontroluješ práva pouze v akci edit
a existuje
libovolná jiná akce, kde se práva nekontrolují (třeba view
),
tak ti formulář pošlu přes ni, čímž bezpečnostní prověrku zcela
obejdu :)
- JakubJarabica
- Gold Partner | 184
Hm, to by chcelo implementovať nad továrničky nejakú anotáciu allowed(action=edit) aby to v takomto prípade hádzalo výnimky. Inak dobrá pripomienka, vďaka :-)
- pekelnik
- Člen | 462
Jan Tvrdík napsal(a):
Pokud kontroluješ práva pouze v akci
edit
a existuje libovolná jiná akce, kde se práva nekontrolují (třebaview
), tak ti formulář pošlu přes ni, čímž bezpečnostní prověrku zcela obejdu :)
Tak tak!
A vyplývá z toho, že je nezbytné autorizovat uživatele přímo v
onSuccess
handleru formuláře.
K původnímu dotazu o skrytém poli se raději nebudu vyjadřovat :P
- Filip Procházka
- Moderator | 4668
Legrace je, že taková akce nemusí vůbec existovat, ani jako metoda v presenteru ani jako šablona a stejně to dojde „dost daleko“ aby proběhlo zpracování.
- tatyalien
- Člen | 239
Tak jak nejlépe postupovat například s tímto:
Pod adminem jsem v sekci editovat uživatele, v comboboxu mám dle práv
zobrazené jen ty, na které má dané právo editovat. Po odeslání se
zobrazí část na editování (buď redirect na this se zvoleným id, nebo edit
view s id), ale jak pak mohu jednoduše ověřit, že uživatel si ručně
nezmění hodnotu načteného id a tím pádem i editaci jiného
uživatele?
Za chyby sorry, píšu do neděle z mobilu fujky.
Editoval tatyalien (23. 7. 2011 20:58)
- voda
- Člen | 561
@tatyalien: klidně ať si to změní. Pokud zvolí id uživatele, kterého nemá právo editovat, tak mu to při ukládání neprojde, protože tam probíhá kontrola. Druhý případ, kdy id změní na uživatele, ke kterému má práva, tak (je blbej) se to nijak neliší od případu, kdy si rovnou otevřel editaci toho uživatele.
- Tharos
- Člen | 1030
@tatyalien: Já bych v tomto případě kontroloval práva na následujících místech:
- na začátku
actionEdit
(resp.renderEdit
), kde si dokáži představit, že bych admina, který nemá právo editovat jím zamýšleného uživatele, přesměrovával na přehled uživatelů - na začátku handleru formuláře (tj. například na začátku metody
renderFormSubmitted
), kde bych v případě nedostatečných práv pravděpodobně také přesměrovával na přehled uživatelů a asi bych před tím volal i$this->flashMessage('Permission denied')
U toho handleru se samozřejmě nabízí i možnost volat
$form->addError('Persmission denied')
, ale zde je riziko, že by
se formulář s chybou vytvářel právě „v kontextu“
actionEdit
a kvůli řešení z prvního bodu by pak stejně
došlo k přesměrování na přehled uživatelů. Pracně předaná chybová
hláška by se pak k adminovi ve výsledku vůbec nedostala.
Samozřejmě do toho select boxu v přehledu je nanejvýš vhodné vypisovat pouze ty uživatele, které má admin možnost editovat.
- Filip Procházka
- Moderator | 4668
Podle mě, je ideální ověřovat, zda má uživatel oprávnění zobrazit aktuální presenter, logicky v presenteru. Ale zároveň by měla být kontrola na práci s daty v modelu. Zda může číst, nebo editovat.
Čili souhlasím s kravčo.
- kravčo
- Člen | 721
Upresním. Nehovorím, že model má implementovať kontrolu práv. Len to, že má byť miestom, kde sa kontroluje, či má JankoHraško má právo upraviť článok #23, pretože model je tým, čo tie dáta fyzicky upraví.
Myslím to nejako takto:
class Model
{
/** @var IAuthorizator */
private $acl;
public function editArticle($id, $data)
{
if (!$this->acl->isAllowed('edit', 'article')) {
throw new AccessDeniedException;
}
//TODO: check return value and catch exceptions
return dibi::query('UPDATE ...', $id, $data);
}
}
Teda model vykonáva kontrolu práv na prostredníctvom poskytnutého autorizátora, nie sám o sebe.
- tatyalien
- Člen | 239
Tak jak koukám, tak nevím jak nastavit uživatelům jaký mají právo na editaci.. pokud nastavím v acl že mají uživatelé právo na view edit tak jim povolím zobrazovat a upravovat, tím pádem mají právo na vše… ale u vyhledávacího combobxu mám nastaveno, pokud je přihlášen „superadmin“ nasypu například všechny jména, pokud má roly „admin“ tak všechny mimo superadmina a admina, atd… ale jak nastavím přímo při updatu jestli dané id mohu editovat? To mám cpát ještě kontrolu, že si vytáhnu danou roly editovacího id a porovnám jestli může nebo ne? Nějak v tom plavu…
Editoval tatyalien (24. 7. 2011 19:52)
- tatyalien
- Člen | 239
kravčo: Používám ACL co tu je…
Takže práva na zobrazení stránek mám nastavené, ale jak jednoduše udělat, když mají admin i superadmin právo na zdroj „edit“, a zde můžou oba dva upravovat data, jak nastavit které id může a nemůže upravit o to mě šlo. Jestli před vykonáním si musím šáhnout do DB zjistit jestli editující data mají menší práva než ten co je edituje a dle toho mu to povolit, nebo zakázat…
Práva mám v nástřelu takto.
<?php
$acl->addResource('edit');
$acl->allow('admin', 'edit', Array('user'));
// superadmin bude mít přímo editaci bokem zvlášť, jen jsem chtěl mít to při jednom na stejném místě s adminem...
$acl->allow('superadmin', 'edit', Array('user', 'userAdminem'));
?>
Tak jsem si doděla ještě kontrolu těsně před editaci a asi to tak nechám
<?php
/**
* Vrátí zda zadané id mohu editovat
* @param int $id_editovaneho
* @param int $id_editujiciho
* @param string $role_editujiciho
* @return boolean
*/
public static function kontrolaOpravneniEditaceUser($id_editovaneho, $role_editujiciho, $id_editujiciho) {
try {
if ($id_editovaneho == $id_editujiciho) {
throw new IOException('Zde nemůžete editovat sama sebe.');
}
$query = 'SELECT role FROM ' . self::TABLE_USERS . ' WHERE id = ? LIMIT 1';
$result = self::$connection->query($query, $id_editovaneho);
$row = $result->fetch();
// při nenalezení daného id vracím false
if(!$row) {
throw new IOException('Zadané id uživatele neexistuje.');
}
if($role_editujiciho == 'superadmin') {
return true;
}
if ($row['role'] == 'superadmin' || $row['role'] == 'admin') {
return false;
} else {
return true;
}
} catch (IOException $e) {
throw $e;
// při neúspěchu vracím false
return false;
}
}
?>
Editoval tatyalien (25. 7. 2011 11:03)