Autor | Zpráva | ||
---|---|---|---|
Milan1236000 Profil |
#1 · Zasláno: 23. 1. 2016, 19:37:58
Zdravím, zkoušel jsem u vyhledávače ošetřit vstup, ale něco mi tam nesedí. Do vyhledávače jsem vždy psal testovací řetězec: ' or 1=1;-- <a href="d.com">te "x " t</a>
Vždy zadám php skript a výstup v html. $text = mysqli_real_escape_string($pripojeni, strip_tags($_GET['hledanytext'])); \' or 1=1;-- te \"x \" t
$text = mysqli_real_escape_string($pripojeni, htmlspecialchars($_GET['hledanytext'])); \' or 1=1;-- <a href="d.com">te "x " t</a>
$text = mysqli_real_escape_string($pripojeni, htmlspecialchars(strip_tags($_GET['hledanytext']))); \' or 1=1;-- te "x " t
$text = mysqli_real_escape_string($pripojeni, htmlspecialchars(strip_tags(trim($_GET['hledanytext'])))); \' or 1=1;-- te "x " t
$text = mysqli_real_escape_string($pripojeni, htmlspecialchars(strip_tags(trim(stripslashes($_GET['hledanytext']))))); \' or 1=1;-- te "x " t
Proč se u 1., 3. a 4. skriptu neoescapovaly uvozovky a proč se u posledního skriptu nevypsal apostrof bez zpětného lomítka? |
||
Keeehi Profil |
#2 · Zasláno: 23. 1. 2016, 19:45:49
Proč? To nevím, ale správné ošetření uživatelského vstupu by mělo být
mysqli_real_escape_string($pripojeni, ($_GET['hledanytext']); . Z hlediska ochrany je to absolutně vše, co potřebuješ. Pro trochu uživatelské přívětivosti by šlo mysqli_real_escape_string($pripojeni, trim($_GET['hledanytext'])); ale to je tak asi všechno.
|
||
Milan1236000 Profil |
Keeehi:
Chtěl jsem právě jen zkusit co co dokáže. Ano, mysqli_real_escape_string($pripojeni, ($_GET['hledanytext'])) jsem tam měl původně, ale z důvodu, že ten vyhledávaný text i vypisuji do stránky a někdo by tam zadal třeba <a href="page.com">s</a>, tak na výstupu bude klikací odkaz, což bych nerad. Jako rozumný kompromis se mi zdál ten můj 1., nebo 2. skript.
|
||
Dan Charousek Profil |
#4 · Zasláno: 23. 1. 2016, 19:58:04
Milan1236000:
Jak píše Keeehi, vše co potřebuješ je: mysqli_real_escape_string($pripojeni, ($_GET['hledanytext']); To o čem píšeš se ošetřuje až při výpisu z databáze. |
||
Milan1236000 Profil |
#5 · Zasláno: 23. 1. 2016, 20:28:21
Keeehi, Dan Charousek:
Fajn, díky. |
||
CZechBoY Profil |
#6 · Zasláno: 23. 1. 2016, 20:38:54
[XSS]
Při vypisování textu vše escapuj podle toho kde to vypisuješ. Např pokud to vypisuješ do html tak použij htmlspecialchars, pro css a js zase něco jiného. |
||
Milan1236000 Profil |
#7 · Zasláno: 23. 1. 2016, 23:00:07
Ještě jsem narazil na jeden problém, který se tohoto tématu lehce dotýká.
Mám registrační formulář: <?php if(isset($_POST['registrovat'])) $nick = htmlspecialchars(trim($_POST['nick'])); ?> <form action="registrace.php" method="post"> <label for="nick">Nick:</label><input type="text" id="nick" name="nick" value="<?php if(isset($nick)) echo $nick; else {echo ""; $chybi_nick=1;} ?>" placeholder="Zadej nick" maxlength="30"><?php if(isset($chybi_nick) && $chybi_nick==1 && !isset($_POST['registrovat'])) echo "<b style=\"color: red;\"> Zadejte nick</b>"; ?><br> <input type="submit" name="registrovat" value="Registrovat"> </form> |
||
CZechBoY Profil |
#8 · Zasláno: 23. 1. 2016, 23:15:20
Vykřičník znamená negaci podmínky - tzn. pokud není odeslaný formulář (nebo chybí odeslané políčko registrovat) tak je podmínka splněna (s vykřičníkem).
Doporučuju spíš validaci pomocí empty (prázdné/nenastavené pole) a trim (odebrané bílé znaky jak od začátku tak od konce): if (empty($_POST['pole']) || trim($_POST['pole'] === '') { zobrazení chybové hlášky } |
||
Keeehi Profil |
#9 · Zasláno: 23. 1. 2016, 23:56:22
Když data neodešleš, podmínka na 1. řádku je false => proměnná $nick neexistuje => podmínka na třetím řádku je false => $chybi_nick se nastaví na jedna => první 2 částí druhého ifu na třetím řádku jsou splněny.
Ale je to zase celé takové nepěkné, zbytečně komplikované. <?php $nick = !empty($_POST['nick']) ? trim($_POST['nick']) : ''; echo <<<HTML <form action="registrace.php" method="post"> <label for="nick">Nick:</label><input type="text" id="nick" name="nick" value=" HTML; echo htmlspecialchars($nick, ENT_QUOTES); echo <<<HTML " placeholder="Zadej nick" maxlength="30"> HTML; if(isset($_POST['registrovat']) && empty($nick)) { echo <<<HTML <b style="color: red;"> Zadejte nick</b> HTML; } echo <<<HTML <br> <input type="submit" name="registrovat" value="Registrovat"> </form> HTML; |
||
Milan1236000 Profil |
#10 · Zasláno: 24. 1. 2016, 00:06:29
CZechBoY, Keeehi:
Super, díky za inspiraci. |
||
Milan1236000 Profil |
#11 · Zasláno: 24. 1. 2016, 15:18:16
Jako další bych potřeboval poradit ohledně email patternu. Zkoušel jsem následující skripty - oba fungují.
$email = htmlspecialchars(trim($_POST['email'])); if (!filter_var($email, FILTER_VALIDATE_EMAIL) === false) $e="ok"; else $e="no"; $email = htmlspecialchars(trim($_POST['email'])); if(preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/",$email)) $e="ok"; else $e="no"; Je mezi nimi nějaký rozdíl (kdy který vyhodí nějakou chybu)? Jak by šel nejjednodušeji napsat ten druhý? Tento je zkopírovaný, ten zápis moc nechápu. |
||
Keeehi Profil |
#12 · Zasláno: 24. 1. 2016, 15:58:15
Pokud jsem to správně dohledal, FILTER_VALIDATE_EMAIL by měl fungovat stejně jako tento regex
/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22))(?:\.(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-[a-z0-9]+)*)|(?:\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\]))$/iD Rozdíl tam určitě bude. Milan1236000: „Jak by šel nejjednodušeji napsat ten druhý?“ Není to vždy pravda ale většinou jednodušší (kratší) regulární výraz je obecnější, takže jím projdou u výrazy, které by v delším neprošly. Obecně emailová adresa může mít opravdu obrovské množství tvarů a obrovské množsví jich mít zase nemůže. A je velmi obtížné napsat takový výraz, který by postihl všechny varianty. S čím se druhý regulár špatně potýká jsou třeba pomlčky v doméně. Email test@---.cz jím projde, přesto že doména ---.cz nemůže existovat.
A dále v ověřování tvaru emailu nevidím moc smysl. Jaký je tvůj důvod? |
||
Milan1236000 Profil |
#13 · Zasláno: 24. 1. 2016, 16:39:31
Keeehi:
Teda, to je hustej filtr... :D Šlo mi jen o správný tvar emailu, aby si tam nemohl každý psát, co chce. Nechám tam ten filtr a je to. Díky. |
||
Keeehi Profil |
#14 · Zasláno: 24. 1. 2016, 17:09:04
Milan1236000:
„Šlo mi jen o správný tvar emailu, aby si tam nemohl každý psát, co chce.“ Ale k čemu ti je, že tam napíše někdo něco co vypdá jako email. Přece když tam někdo napíše kughocnehgolsiuhlsieuhgcieuhgleriughlwirueg@wfzuggfaugflawgrfkwer.kggff tak to filterm projde ovšem pro tebe to má stejnou vypovídající hodnotu jako kdyby tam někdo napsal ščářž?&]˘°ł . Ani jeden ze vstupů není emailová adresa. Tedy ta první by mohla být ale to je vedlejší. Jediné ověření, které by tě mělo zajímat je tedy zda ten daný člověk zadanou emailovou adresu opravdu kntroluje, že má k ní přístup. A to se dá ověřit jedině zasláním emaiu na tu adresu s něčím tajným co pak bude následně po uživateli vyžadováno.
|
||
Milan1236000 Profil |
#15 · Zasláno: 24. 1. 2016, 19:20:17
Keeehi:
Ano, i ověření správnosti mě napadlo, zatím jsem však řešil jen tvar, nic víc. |
||
Milan1236000 Profil |
Pokud mám skript na ověření, zda zadaný uživatel v registračním formuláři již v databázi neexistuje a do pole napíšu byť jen jeden z těchto znaků: ě, č, ř (ostatní písmena s háčky jdou bez problému, akorát u těchto 3 je problém, mimochodem, proč zrovna tyto 3 zobrazují chybu?) zobrazí se chyba na posledním řádku:
$nick = htmlspecialchars(trim($_POST['nick'])); $vysledek_uzivatel_nick = $pripojeni->query(" SELECT * FROM `uzivatele` WHERE Nick=\"$nick\" "); $zaznam_uzivatel_nick = $vysledek_uzivatel_nick->fetch_object(); SET NAMES utf8 mám. Jak by šlo ošetřit tohle?
|
||
Keeehi Profil |
Milan1236000:
Špatně escapuješ! Funkce htmlspecialchars se používá jen na ošetření dat, které chceš vypsat, ne dat, která obdržíš a už vůbec ne na data, která chceš poslat do databáze. Ty jí cpeš všude a to je špatně. Nevhodné použití ecapovacích funkcí může mít za následek snížení bezpečnosti místo jejího zvýšení. Správně by ten kód měl vypadat takto: $nick = trim($_POST['nick']); $vysledek_uzivatel_nick = $pripojeni->query(" SELECT * FROM `maturitniprace_uzivatele` WHERE Nick='".($pripojeni->real_escape_string($nick))."'"); $zaznam_uzivatel_nick = $vysledek_uzivatel_nick->fetch_object(); Pořádně si nastuduj phpfashion.com/escapovani-definitivni-prirucka a používej správné funkce ve správnou chvíli. |
||
Milan1236000 Profil |
Keeehi:
Díky za super článek, opravím. Už to konečně jde, změnil jsem v mysql porovnávání na utf8_czech_ci. Předtím to bylo defaultně z neznámého důvodu na latin1_swedish_ci. |
||
Časová prodleva: 9 let
|
0