Autor | Zpráva | ||
---|---|---|---|
Nailen Profil |
#1 · Zasláno: 28. 3. 2021, 23:53:20
Zdravím,
používám jeden americký systém, kde se teď potýkám s následujícím problémem. Edituji záznam. Jsou tam nějaké pole, zatržítka,... Pak odesílám formulář metodou post. Pokud v poli Page Title mám původní anglický název stránky, tak se vše uloží v pořádku. Pokud není žádná změna, tak se nic nestane,... Jakmile ale do tohoto pole napíšu nějakou diakritiku, tak se sice také vše zapíše do DB, ale pokaždé, když dál uložit aniž bych cokoli změnil (nebo měnil jakékoli jiné pole), tak se toto pole Page Title (pole s diskritikou) znovu uloží do databáze. Takže zase se mi přes post předá hodnota editovaného pole a provedou se patřičné akce. Při každém ukládání, se ukládá informace do logu, takže tam jsem to zjistil, že se to takto chová. Zde je ukázka kde se zapisuje do DB a do logu //Changed title for page if($_POST['changeTitle'] != $pageDetails->title){ $newTitle = Input::get('changeTitle'); if ($db->query('UPDATE pages SET title = ? WHERE id = ?', array($newTitle, $pageDetails->id))){ $successes[] = lang("PAGE_RETITLED", array($newTitle)); logger($user->data()->id,"Pages Manager","Retitled '{$pageDetails->page}' to '$newTitle'."); }else{ $errors[] = lang("SQL_ERROR"); } } Zde je příklad formuláře: <form name='adminPage' action='<?=$us_url_root?>users/admin.php?view=page&id=<?=$pageId;?>' method='post'> <input type='hidden' name='process' value='1'> ... <div class="row"> <div class="col-sm-6 col-sm-offset-3"> <div class="form-group"> <label for="title">Page Title:</label> <span class="small">(This is the text that's displayed on the browser's titlebar or tab)</span> <input type="text" class="form-control" name="changeTitle" maxlength="50" value="<?= $pageDetails->title; ?>" /> </div> </div> </div> ... <input type="hidden" name="csrf" value="<?=Token::generate();?>" > <a class='btn btn-warning' href="<?=$us_url_root?>users/admin.php?view=pages">Cancel</a> <input class='btn btn-secondary' name = "return" type='submit' value='Update & Close' class='submit' /> <input class='btn btn-primary' type='submit' value='Update' class='submit' /> </form> Napadá někoho, čím by to mohlo být, že slova s diakritikou způsobí, že tato hodnota je vždy naplněna $_POST['changeTitle'] ? Jakmile zruším diaktitická znaménka, tak vše začne fungovat správně. Děkuji za nápady. |
||
Kajman Profil |
#2 · Zasláno: 29. 3. 2021, 00:04:51
Zkuste si do logu vypsat i původní hodnotu a pak zkontrolujte rozdíly - třeba budou vidět jen při porovnání binárních zápisů.
|
||
Keeehi Profil |
#3 · Zasláno: 29. 3. 2021, 01:10:57
Nailen:
„Napadá někoho, čím by to mohlo být, že slova s diakritikou způsobí, že tato hodnota je vždy naplněna $_POST['changeTitle'] ?“ Otázka je položená špatně. Hodnota v $_POST['changeTitle'] je totiž vyplněná vždy, nezávisle na diakritice. To kde je rozdíl je v porovnání s hodnotou v $pageDetails->title. Když použiješ toto, tak ti to přestane dělat updaty? $newTitle = Input::get('changeTitle'); if($newTitle != $pageDetails->title){ |
||
Nailen Profil |
Kajman:
Dobrý den, na webu je zobrazené písmeno ý ale v db je uloženo ý To bude ten rozdíl, že? Keeehi: Dobrý den, když jsem připsal tu vaši podmínku, tak to začalo fungovat tak jak má. Zjistím někde co dělá ta metoda Imput::get a jak je nadefinovaná? Jak bych to měl najít ve zdrojáku? Díky |
||
Keeehi Profil |
#5 · Zasláno: 30. 3. 2021, 16:01:26
Předpokládám, že jde o starý Laravel. Pak Input:get je fasáda na Request->input.
Předpokládám, že někde něco převádí znaky s diakritikou na entity. Zdá se mi divné, že by to dělalo zrovna Input::get. Ovšem ona spousta věcí v Laravelu funguje tak nějak magicky. Proto ho taky odmítám používat. Mimochodem, myslím, že Input::get je naposledy běžně používané ve verzi 4.2. Ve verzi 5 to je značeno za deprecated a od verze 6 to neexistuje. Respektive to bylo nahrazeno Request::input. |
||
Nailen Profil |
#6 · Zasláno: 30. 3. 2021, 21:13:13
Keeehi:
Děkuji za vysvětlení. I když se musím přiznat, že toto je nad moje aktuální schopnosti v PHP. Takže se zeptám ještě takto. Když mi to teď s podmínkou, kterou jste mi poradil funguje, mám to dál řešit, nebo pokud mi to takto stačí, tak to dál nemám řešit? Je nějaký jednoduchý způsob, jak docílit toho, aby mi to diakritiku nepřevádělo na entity? Aby to bylo čitelné v databázi, tak jak se to do DB nahrálo při importu? |
||
Keeehi Profil |
#7 · Zasláno: 30. 3. 2021, 22:09:50
Nailen:
„Je nějaký jednoduchý způsob, jak docílit toho, aby mi to diakritiku nepřevádělo na entity?“ Asi ano, ale jak jsem psal, kvůli té jeho magii s Laravelem nepracuji, takže ti přímo neporadím. Obecně, dej si ručně do databáze čistá data a pak zjisti, kde se ti to poprvé převedlo na entity. Pokud tohle místo najdeš, mělo by být možné zjistit, jak tomu zabránit. |
||
Nailen Profil |
#8 · Zasláno: 30. 3. 2021, 23:18:50
Keeehi:
OK, díky. Budu pátrat. Ještě se zeptám. Když si vypisuji hodnoty přes echo, tak nikde nenarážím na entity až v DB. Mám je vypisovat nějak jinak, abych to odhalil? Děkuji |
||
Kajman Profil |
#9 · Zasláno: 31. 3. 2021, 00:28:26
Jaké parametry používáte při vypisování do html stránky ve funkci htmlspecialchars?
|
||
Nailen Profil |
#10 · Zasláno: 31. 3. 2021, 01:22:20
Kajman:
našel jsem toto: $query = htmlspecialchars(Input::get('query')); a také jsem našel tu třídu: class Input { public static function exists($type = 'post'){ switch ($type) { case 'post': return (!empty($_POST)) ? true : false; break; case 'get': return (!empty($_GET)) ? true : false; default: return false; break; } } public static function get($item){ if (isset($_POST[$item])) { /* If the $_POST item is an array, process each item independently, and return array of sanitized items. */ return self::sanitize($_POST[$item]); } elseif(isset($_GET[$item])){ /* If the $_GET item is an array, process each item independently, and return array of sanitized items. */ return self::sanitize($_GET[$item]); } return ''; } public static function sanitize($item){ if (is_array($item)){ foreach ($item as $key => $itemValue){ $postItems[$key]=self::sanitize($itemValue); } return $postItems; }else{ return trim(htmlentities($item, ENT_QUOTES, 'UTF-8')); } } } |
||
Keeehi Profil |
Nailen:
Za to převádění na entity je zodpovědná ta funkce htmlentities. Jinak tahle sanitizace je pěkná prasárna. Data z formuláře by měl kód dostat ve víceméně čisté podobě a ne po tom co to projde tímto. Uživatelský vstup je samozřejmě vždy potřeba escapovat, ale ne tímto způsobem, který vůbec nebere kontext do úvahy. Pokud chceš vynechat to escapování, pak stačí ten Input::get prostě nepoužit a šlápnout si na post data napřímo. if($_POST['changeTitle'] != $pageDetails->title){ $newTitle = $_POST['changeTitle']; Samozřejmě, jelikož to teď není escapované, mělo by se to escapovat na výpisu. Jak? No to záleží dle kontextu. |
||
Nailen Profil |
#12 · Zasláno: 31. 3. 2021, 11:47:30
Keeehi:
Skvělé, děkuji za vysvětlení. Upravil jsem to. Ukládání funguje jak má. V DB mám znaky s diakritikou, takže nyní jsem spokojen. Píšete, že by přesto mělo proběhnout escapování na výpisu. Mohu ještě poprosit o vysvětlení jak je to přesně myšleno. To znamená, že bych měl obsah z DB před zobrazením na webu prohnat přes nějakou funkci, která daný obsah (text) ještě escapuje? Uživatelský vstup těchto dat je pouze na úrovni administrátorského rozhraní, takže by v těchto Titlech nemělo být nic nežádoucího. |
||
Keeehi Profil |
#13 · Zasláno: 31. 3. 2021, 11:57:46
Nailen:
„To znamená, že bych měl obsah z DB před zobrazením na webu prohnat přes nějakou funkci, která daný obsah (text) ještě escapuje?“ Ano. Důležité to je u dat nad kterými nemáš kontrolu. U dat z administrace to nemusí být nutnost, ale je to dobrá praxe. On se v budoucnu ten zdroj může změnit a mezitím zapomene, že se to někde vypisuje neošetřené. Proto je dobré escapovat vždy každý výstup. |
||
Nailen Profil |
#14 · Zasláno: 31. 3. 2021, 12:28:36
Keeehi:
OK, díky. Pokud tedy nemám používat htmlspecialchars tak doporučíte mi něco co je lepší varianta? |
||
Kajman Profil |
#15 · Zasláno: 31. 3. 2021, 13:03:56
Funkci htmlspecialchars máte používat až při výpisu všech dat do html stránky. Nemáte ji jen používat pro uložení dat do databáze.
|
||
Nailen Profil |
#16 · Zasláno: 2. 4. 2021, 10:42:39
Kajman:
OK, děkuji moc za vysvětlení. |
||
Časová prodleva: 3 roky
|
0