NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: htmlspecialchars() a bezpečnost.

V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
katrincsak
Člen
Avatar
katrincsak:19.6.2015 19:22

Zdravím,

rád bych se optal na htmlspecialchars(). Jaký je rozdíl provádět kontrolu při zápisu a při výpisu? Aktuálně provádím kontrolu při zápisu, tak aby tagy byly převedené. Při výpisu mi přeci už škodit nemohou, nebo ano? Na víc si hlídám $_GET počtem znaků. Např. jakmile je $_GET delší než 20 znaků, neprojde to, takže přes URL by neměli jít dělat útoky.

Měl bych používat ještě něco dalšího ?

 
Odpovědět
19.6.2015 19:22
Avatar
Odpovídá na katrincsak
Neaktivní uživatel:19.6.2015 19:32

Funkci htmlspecialchar­s() 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.

Nahoru Odpovědět
19.6.2015 19:32
Neaktivní uživatelský účet
Avatar
Odpovídá na katrincsak
Matúš Petrofčík:19.6.2015 19:40

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ť...

Nahoru Odpovědět
19.6.2015 19:40
obsah kocky = r^2 ... a preto vlak drnká
Avatar
katrincsak
Člen
Avatar
Odpovídá na Neaktivní uživatel
katrincsak:19.6.2015 19:41

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?

 
Nahoru Odpovědět
19.6.2015 19:41
Avatar
Odpovídá na katrincsak
Matúš Petrofčík:19.6.2015 19:45

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š.

Nahoru Odpovědět
19.6.2015 19:45
obsah kocky = r^2 ... a preto vlak drnká
Avatar
katrincsak
Člen
Avatar
Odpovídá na Matúš Petrofčík
katrincsak:19.6.2015 19:46

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;
        }
 
Nahoru Odpovědět
19.6.2015 19:46
Avatar
Odpovídá na katrincsak
Matúš Petrofčík:19.6.2015 19:48

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. :)

Editováno 19.6.2015 19:48
Nahoru Odpovědět
19.6.2015 19:48
obsah kocky = r^2 ... a preto vlak drnká
Avatar
katrincsak
Člen
Avatar
Odpovídá na Matúš Petrofčík
katrincsak:19.6.2015 19:52

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 :D

 
Nahoru Odpovědět
19.6.2015 19:52
Avatar
Odpovídá na katrincsak
Neaktivní uživatel:19.6.2015 19:58

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.

Nahoru Odpovědět
19.6.2015 19:58
Neaktivní uživatelský účet
Avatar
Odpovídá na katrincsak
Matúš Petrofčík:19.6.2015 19:59

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č :D

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é.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
19.6.2015 19:59
obsah kocky = r^2 ... a preto vlak drnká
Avatar
katrincsak
Člen
Avatar
katrincsak:19.6.2015 20:08

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 :D

 
Nahoru Odpovědět
19.6.2015 20:08
Avatar
Odpovídá na katrincsak
Matúš Petrofčík:19.6.2015 20:09

Dúfam že ja! :D

Nahoru Odpovědět
19.6.2015 20:09
obsah kocky = r^2 ... a preto vlak drnká
Avatar
Nahoru Odpovědět
19.6.2015 20:14
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Matúš Petrofčík:19.6.2015 20:28

Príď na zraz v piatok :D

Nahoru Odpovědět
19.6.2015 20:28
obsah kocky = r^2 ... a preto vlak drnká
Avatar
katrincsak
Člen
Avatar
katrincsak:19.6.2015 20:42

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 ;-)

 
Nahoru Odpovědět
19.6.2015 20:42
Avatar
Dominik Klapuch:19.6.2015 21:25

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('é') - é
htmlspecialchar­s('é') - é
htmlentities('ó') - ó
htmlspecialchar­s('ó') - ó

Nahoru Odpovědět
19.6.2015 21:25
Kód a data patří k sobě.
Avatar
Odpovídá na Dominik Klapuch
Dominik Klapuch:19.6.2015 21:26

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.

Editováno 19.6.2015 21:27
Nahoru Odpovědět
19.6.2015 21:26
Kód a data patří k sobě.
Avatar
Odpovídá na Dominik Klapuch
Matúš Petrofčík:19.6.2015 21:37

blbnú tu tie entity, musíš napísať ako:
< sa stane &lt;

< sa stane &amp;lt;
Editováno 19.6.2015 21:37
Nahoru Odpovědět
19.6.2015 21:37
obsah kocky = r^2 ... a preto vlak drnká
Avatar
Dominik Klapuch:19.6.2015 21:40

Přikládám obrázek. Delší varianta je htmlentities. Nemám nastavené UTF-8, takže délka může mást.

Nahoru Odpovědět
19.6.2015 21:40
Kód a data patří k sobě.
Avatar
katrincsak
Člen
Avatar
Odpovídá na Dominik Klapuch
katrincsak:20.6.2015 13:53

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 ;-)

Editováno 20.6.2015 13:54
 
Nahoru Odpovědět
20.6.2015 13:53
Avatar
katrincsak
Člen
Avatar
katrincsak:21.6.2015 0:31

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);
Editováno 21.6.2015 0:34
 
Nahoru Odpovědět
21.6.2015 0:31
Avatar
Odpovídá na katrincsak
Matúš Petrofčík:21.6.2015 0:37

Len tie názvy vlastností a metód mi prídu nejasné, ale to je na tebe :D

Nahoru Odpovědět
21.6.2015 0:37
obsah kocky = r^2 ... a preto vlak drnká
Avatar
katrincsak
Člen
Avatar
Odpovídá na Matúš Petrofčík
katrincsak:21.6.2015 0:44

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ř. ;-)

 
Nahoru Odpovědět
21.6.2015 0:44
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 23 zpráv z 23.