Diskuze: htmlspecialchars() a bezpečnost.
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 23 zpráv z 23.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Funkci htmlspecialchars() používej, jen když vypisuješ nějaký text na stránku. Text totiž může obsahovat některé HTML tagy, které by nadělaly na stránce paseku. V PHP skriptu ti takový neošetřený řetězec nic nemůže udělat, jde jen o to, vypsat pomocí této funkce do HTML proměnnou, která by měla být jako text a ne jako kus HTML kódu.
Kromě výpisu dat na stránku se ještě ošetřují proměnné, které se vkládájí do SQL dotazu, viz SQL injection. Dále se používají funkce na odstranění krajních mezer trim(), ty se používají ihned po získání dat z $_GET.
Ak ukladáš užívateľské vstupy do databázy, mal by si ich ošetriť proti sql injekcii, aby ti náhodou niekto nevymazal databázu. Vhodné je použiť PDO triedu, a v nej prepared statements, kedy si najprv vytvoríš sql dotaz, a až potom do neho (pri spúšťaní) vložíš dáta od užívateľa (napr. email).
Inak by vstup (imho) nemal byť ošetrovaný, a to ošetrenie sa aplikuje až pri výpise dát.
<?= $nebezpecna_premenna ?>
<?= htmlspecialchars($bezpecnejsia_premenna) ?>
<?= htmlspecialchars($bezpecna_premenna, ENT_QUOTES) ?>
a takto vypisujem ja:
<?= htmlentities($premenna, ENT_QUOTES) ?>
Najlepšie je si na to napísať funkciu a prípadné zmeny sa aplikujú všade:
<?php
// najlepšie do objektu
function osetriPremennu($premenna){
return htmlspecialchars($premenna, ENT_QUOTES);
}
a pre výpis používať
<?= osetriPremennu("dačo nekalé") ?>
alebo si premenné hromadne pred výpisom ošetriť...
To já chápu jak funguje htmlspecialchars() ale jakmile z určitého místa třeba formuláře načtu data, prosypu je htmlspecialchars(), pak je uložím do DB, tak už při výpisu přeci škodit nemohou. Nebo jak bych mohl docílit toho, aby již uložený etxt přes htmlspecialchars mohl najednou mít html tagy?
Ulož tak ako ti to užívateľ zadá, a upravuj podľa potreby až pri výpise na stránku. Ak nechceš html tagy, tak ich ostrániš, a ak ich chceš, tak to proste vypíšeš.
PDO používám a dokonce jsem si i vytvořil svojí funkci, ale hážu do ní data při zápisu a znovu je házet při výpisu mi už přijde zbytečné. Proč bych to měl dělat 2x ? Když v DB ty tagy mít nechci. Myslím, že na MySQL je taky nějaká funkce, ale opět bych to dělal dvojí cestou.
public function htmlTag($pole)
{
$this->ochrana = array_map('htmlspecialchars', $pole);
return $this->ochrana;
}
No rob ako chceš, ja ti radím ukladať do databázy dáta tak ako sú (maximálne použiť trim() alebo niečo ľahkého), a ošetrovať ich až pri výpise.
To já si rád nechám poradit, ale rád znám i proč a tak mě zajímalo proč ošetřovat při výpisu, když mohu při zápisu. Třeba nějaká injekce, nebo je to absolutně hloupé atp
Při výpisu se ošetřuje proto, protože bys měl mít v databázi originál, co uživatel napsal. Někdy například budeš chtít něco vyhledat a nenajdeš, protože tam nebude originál. Ta funkce se používá čistě pro výpis.
Napríklad ma napadlo, že budeš mať na stránke editor článku, ktorý bude mať nejaký javascriptový supereditor na formátovanie textu, na pridávanie nadpisov, odsekov, listov... ale nebude to nejaký značkovací jazyk typu texy, ale klasické html značky. Ty to dostaneš, odstrániš formátovanie, uložíš... a námaha naformátovať pekný článok je fuč
Takto ak uložíš do DB neupravený text, presne tak ako ti ho užívateľ poslal, tak sa môžeš pri výpise rozhodnúť, či chceš html tagy odstrániť, alebo ponecháš formátovanie, alebo s tým urobiť niečo iné.
Jasně, asi mi to jako odpověď takto stačí. Mě šlo spíše o nějaké možné nekalé praktiky, když bych to dělal opačně. Přeci jen je i náročnější např. 1 tisíc uživatelům převádět 20x text než ho jenom vypsat.
Otázka kdo dostane bodíky
Já bodíky dám Matúš Petrofčík Každopádně jste mi odpověděli oba. Neaktivní uživatel Již načal "slovník" takže když dokončí radu, kterou doporučil tak bodíky ho neminou.
Oběma děkuji
Nevím zda to tu už někdo nepsal, nechtělo se mi to pročítat, ale jeden důležitý důvod:
Pokud bys napřed ošetřil a potom uložil, mohlo by nastat, že bys již nezískal zpět stejný text.
Řekněme, že mám na sloupeček limit 20 znaků:
V případě, když použiji htmlspecialchars či htmlentities, tak se řetězec
přeloží takto:
< se přeloží jako < Z jednoho znaku se najednou stanou čtyři.
Pokud bych použil na písmenko é htmlentities, dostal bych é, což je 8 znaků.
Myslím si, že to může být vážná hrozba díky tomu, že když nedodržíš limit 20 znaků na sloupec, tak DB ti to sama ořízne, takže na výstupu dostaneš zcela něco jiného.
BTW: Je lepší používat htmlspecialchars. Díky tomu pak na výstupu dostáváš míň znaků, než s htmlentities.
htmlentities('é') - é
htmlspecialchars('é') - é
htmlentities('ó') - ó
htmlspecialchars('ó') - ó
Sakra, jak koukám, tak se to tady špatně přeložilo... Zkus si v PHP napsat ty příklady co jsou dole a uvidíš rozdíly.
blbnú tu tie entity, musíš napísať ako:
< sa stane <
< sa stane &lt;
Přikládám obrázek. Delší varianta je htmlentities. Nemám nastavené UTF-8, takže délka může mást.
Dominik Klapuch -> Škoda, že jsem již řešení předal protože tohle je přesně jedna z věcí co jsem přesně potřeboval vědět. Tohle už rozhodně stojí za zamyšlenou proč to dělat tak a ne tak. Parádní odpověď, plnohodnotná
Děkuji
Každopádně již jsem to předělal a hned jsem poznal rozdíl i v testování. Nemusel jsem zkoušet vytvářet xxx článků, abych viděl změnu. Je to tak skutečně lepší
class Karantena
{
public function text($pole)
{
$this->ochrana = array_map('htmlspecialchars', $pole);
$this->slovnik($this->ochrana);
return $this->ochrana;
}
Pak už jen prolívám výstup:
$karantena->text($VÝSTUP);
Len tie názvy vlastností a metód mi prídu nejasné, ale to je na tebe
Občas mi je to taky dost nejasné, ještě si v tomhle dělám trošku pořádek. Jsem docela začátečník a tak jsou věci ve kterých solidně plavu z důvodu zaměření myšlenek na provedení a funkčnost. Zřejmě začnu používat slovesa nebo přídavná jména např.
Zobrazeno 23 zpráv z 23.