ugrás a tartalomhoz

Egy valódi példa XSS támadásra

Anonymous · 2007. Feb. 12. (H), 21.57
Egy Zive.cz elleni sikeres XSS támadás részletes leírása.
 
1

Betyárbecsület?

Dualon · 2007. Feb. 12. (H), 22.52
A publikálási jogot senki nem tagadhatja meg a szerzőtől, de az ilyesmit azért illik úgy csinálni, hogy sikeres behatolás után elküldi a belógás részleteit a lapgazdáknak, ad nekik pár nap haladékot, és csak utána írja meg nyilvánosan a leleplező cikket.
Mer' ugye "nem áll szándékában kárt okozni"...
2

Ámátőriznus és súlyos PHP hiányosságok

vbence · 2007. Feb. 13. (K), 11.20
Elég kis amatőr konstrukciónak tűnik a felület (ami az abszolút designmentességből elsőre lejött). Meg aztán az ilyen dolgok ellen alapból teszteli az ember az oldalt..

A másik viszont az, hogy az ehhez hasonló dolgokat egyértelműen a nyelvnek kéne kiküszöbölnie. Nem megoldás, hogy 99 helyen írjam oda, htmlspecialchars, mert a századikon talán kimarad. Milyen szép lenne ha a változóhoz tartozna egy (vagy több) flag, ami azt jelzi, hogy biztonságos-e. És mielőtt (pl echo-ban) használja az ember fel kell oldania egy egyszerű függvényhívással pl untaint ($username) - emlékeztek a javascriptre? - ez már elég lenne, hogy védjen a figyelmetlenségből átcsúszó értékekkel szemben. Ugyanúgy echo-ban, mint adatbázisban stb. Talán írok rá egy modult...

Azoknak ez nem tűnt fel akik szerint a REGISTER_GLOBALS veszélyes?
3

A másik viszont az...

presidento · 2007. Feb. 16. (P), 20.21
http://hu.php.net/manual/hu/ref.filter.php
4

nem ilyen egyszerű

Hodicska Gergely · 2007. Feb. 17. (Szo), 00.17
A másik viszont az, hogy az ehhez hasonló dolgokat egyértelműen a nyelvnek kéne kiküszöbölnie.
Azért ez messze nem ilyen egyszerű, ráadásul nem is logikus. Abszolút alkalmazás függő, hogy egy adott változót nyugodtan kiirathatsz-e echoval, vagy sem. Ráadásul nem feltétlenül webre echozol. ;)

Ha meg mindig Neked kell beállítani a megbízható flaget, akkor meg ugyanott vagyunk.

És akkor még ott van az, hogy sok esetben a böngésző értelmezőjének hibáit használja ki egy-egy támadási módszer, ezekből meg bármikor kiderülhet egy újabb, ilyenkor adjanak ki mindig egy új PHP verziót?


Üdv,
Felhő
5

szerintem nem olyan bonyolult

vbence · 2007. Feb. 17. (Szo), 01.06
A böngészők hibái egy dolog. (Helyes ez így?) Ha viszont az echo meg a mysql függvények védve lennének ezzel az esetek 90%át (vagy többet) lefednénk.

A konkrét megoldást nem abban látom, hogy egy adott funkciót kell mindig hívogatni. A htmlspecialchars például beállíthatná a HTML biztos flaget, a mysql_real_escape_string a mysql biztosat stb stb... Egy explicit flag állítás csak akkor kellene, ha azt akarjuk jelezni, hogy "tudunk róla, és más módon már védekezünk".

Arról, hogy az echo hova ír, tud a php, és így a védelmi funkciók is ennek megfelelően működhetnének.

De jó lehetőség, ha okosítjuk a különböző kimenetkezelő függvényket. Ha echo-zunk az echo nem tudja, hogy éppen html kódot, vagy megjelenítendő adatot fog kiírni, a mysqli funkciók viszont már lehetőséget adnak, hogy az adatokat elválasszuk az utasításoktól. Gondolom ilyenkor már nincs szükség az escape-re (legalább is így lenne logikus).
6

arányok, használati esetek

Hodicska Gergely · 2007. Feb. 17. (Szo), 03.20
Ha viszont az echo meg a mysql függvények védve lennének ezzel az esetek 90%át (vagy többet) lefednénk.
Túl sok féle használati eset van. Tipikusan oda jutnánk, mint a magic_quotes. Egy ilyen szintű védelemt szerintem framework szinten kell megoldani, hogyha nem akarsz bíbelődni minden esetben az adatokkal.

Pl. mysql szinten védelemre semmi szükség, használhatsz prepared statementet. Simán jöhet egy adat ellenőrzött forrásból, akkor minek hívjak meg rá bármilyen függvényt (escape vagy biztonságosságot jelölöő) fölöslegesen.

Arról, hogy az echo hova ír, tud a php
Már honnan tudna? Webre is írhatsz rengeteg féle dolgot (HTML, REST, JSON stb.), parancssorban is nyugodtan írhatsz ki HTML-t is, szóval az escapelés mindig attól függ, hogy mire használod az adott dolgot.

Szóval szerintem nem igazán lehet általános megoldást találni, mint ahogy a magic_quote sem oldott meg anno semmit. Túl sok féle használati lehetőség van.


Üdv,
Felhő
7

Nem szeretném

janoszen · 2007. Feb. 18. (V), 10.36
Én személy szerint nem szeretném, ha a PHP belekontárkodna az adataimba. Az első két dolog, amit ki szoktam kapcsolni a tárhelyeken, ahol dolgozom az a register_globals és a magic_quotes.
8

pontosan az arányok

vbence · 2007. Feb. 18. (V), 13.14
Kedves Felhő. Ami problémákat felhozol szerintem részletkérdések a nagy képhez képest. Elsődleges, hogy a használati esetek minél nagyobb százalékát fedjük le. A témaindító blogmarkban a legelterjedtebb (és talán legveszélyesebb) példa az echo -> HTML szerepelt. Ha ez ellen védekezni tudunk úgy hogy nem okozunk lényeges plusszmunkát a többi esetben, akkor nagyot léptünk előre.

Lényges plusszmunka pl a magic_quotes-nál, a stripslashes hívása minden kintről kapott változó esetén. Egészen más az eset, ha valamit csak a szkript elején egyszer kéne meghívni.

Olyan esetben, amikor nem ez a kívánt viselkedés (őszintén mennyi a JSON és REST aránya a HTMLhez képest?) kikapcsolhatjuk a figyelést. (Egy függvényhívással a kód elején vagy iniből vagy htaccessből).

Megválaszthatjuk (ini, htaccess), hogy a keletkező üzenetek milyen súlyosak (notice, warning, error) legyenek.

Ha a modul kész és az echo védve van. semmi nem akadályoz meg minket, hogy hozzáadjuk egy-egy flaget a REST, JSON stb. felhasználásoknak. Ilyenkor (ha szeretne speciális védelmet) a szkript elején aszondja, hogy protect_json (); és már is más flageket figyel az echo.

A magic_quotes-szal (legalább is ezért nem használom) az a baj, hogy be és kikapcsolt állapotban egészen más kód kell hozzá. Flageknél csak annyi lenne a különbség, hogy nem figyelmeztet, de a kód ugyanúgy lefut. (Feltételezve, hogy a php része a védelem).

A magic_quotes-néál, ha "átcsúszik" valami (nem figyelünk a stipslashes-re), nem kapunk figyelmeztetést, ellenkezőleg a kódunk egyszerűen rosszul működik. Ez nem is biztos, hogy kiderül a munkaasztalon (nekem sokszor volt, hogy egy-egy mezőt tesztadatai között nem volt idézőjel, mert mindek...). Ezzel szemben a flagek egy intelligens védelmet jelentenének, ami pont az átcsúszó változókat fogná meg.

Még egyszer leírom, hogy nem úgy képzelem el, hogy

<?
    htmlspecialchars ($a);
    untaint ($a);
?>
egszerűen a htmlspecialchars álatal visszaadott változó már magán viselné a html-biztos flaget. (Ugyanígy a mysql_real_escape_string egy mysql biztos változót adna vissza).

Nem kéne mostani kódodon változtatni, egszerűen kapnál jelzést a php-tól, ha valami potenciálisan veszélyes dolgot csinálsz.

Azt én is írtam, hogy a mysqli már megoldást kínál a dologra.
9

re: pontosan az arányok

Hodicska Gergely · 2007. Feb. 18. (V), 18.17
Ami problémákat felhozol szerintem részletkérdések a nagy képhez képest.
Szerintem nagyon nem. És pont a leglényegesebb pontra nem reagáltál: ha van egy olyan védelmi mechanizmus, amire nincs minden esetbe szükség, akkor ugyanazt a hibát követjük el, mint a magic_quotes esetében. Ott is az volt a lényeg, hogy a felhasználókat megvédjék önmaguktól, csak épp a koncepció volt rossz.

őszintén mennyi a JSON és REST aránya a HTMLhez képest?
Hát pont manapság egyre hangsúlyosabbak ezek, hiszen terjed a webes alkalmazások (nem oldalak!) száma, amik rengeteg XHR hívást használnak. Rengeteg a webes API is, amik szintén többek között defacto használják ezeket a formátumokat.

Nálunk pl. elég sok olyan oldal van, amiknek a diszkrét JS miatt van HTML kimenete, XHR hívásnak megfelelő kimenete, de van amikor még flash interfésze is van. Akkor a kódba ki-be kapcsolgassam, hogy most mit is szeretnék? Szerintem ebből is látszik, hogy egy ilyen védelemnek nem nyelv szinten kell lennie, hanem például a megjelenítési logika része lehetne.

SQL esetén sem az lett a megoldás, hogy a PHP véd meg, hanem hogy az adott API-k nyújtanak erre lehetőséget.


Üdv,
Felhő

u.i.:
A magic_quotes-szal (legalább is ezért nem használom) az a baj, hogy be és kikapcsolt állapotban egészen más kód kell hozzá.
Ha olyan kódot szeretnél, ami ezen beállítástól független, akkor a script elején kell a magic_qoutes bekapcsolt állapota esetén annak hatását eliminálni, és akkor a kódod többi része egységes lehet.
10

a lényeges pont

vbence · 2007. Feb. 18. (V), 20.17
A lényges pontra: tegyük fel, hogy JSON az egyik php-nk célja. Telepítjük a védelmi modult, erre warningok lesznek a logunkban.
(Tételezzük fel a legbutább implementációt, ami a "Content-type" headerből nem találja ki, hogy most nem kell a HTML védelem.) Miután elolvassuk a hibaüzenetben megadott linket világos lesz, hogy egy ilyen sort kell beírjunk a szkriptünk elejére, hogy ne kapjunk több warningot:
ini_set ('output_protection_type', 'text/x-json');
Ezután nem kapunk több warningot. Ehelyett notice-t kapunk, hogy a text/json tipusra még nincs kész a védelem, és json outputunkra ugyanúgy kell figyelni, mint eddig (nehogy a biztonság hamis illúziójába ringassuk magunkat).

Ha végignézzük az esetek számát, amikor nincs szükség a védelemre (szerintem 5% alatt), és a szükséges pluszmunkát amit ez okoz, világos hogy nem hasolítható össze a magic_quotes féle megoldásokkal. A mérleg másik serpenyőjében meg ott van, hogy gyakorlatileg megszünne a php legnagyobb sebezhetősége.
13

amire nem reagáltál

Hodicska Gergely · 2007. Feb. 18. (V), 23.09
"Abszolút alkalmazás függő, hogy egy adott változót nyugodtan kiirathatsz-e echoval."
"Simán jöhet egy adat ellenőrzött forrásból, akkor minek hívjak meg rá bármilyen függvényt"

Ez a kettő már szerintem elég indok a dolog ellen, és messze nem az esetek 5%-ban fog előfordulni.

hogy JSON az egyik php-nk célja
Egyazon PHP hívható meg több féle forrásból, az határozza meg a kimenetet. Nem szükséges pl. JSON esetben külön fejlécet kiadnom (ami amúgy application/json), ha meg emiatt igen, akkor az egy újabb felesleges kötöttség.

Más részről tekintve teljesítmény szempontból sem érzném egy jó dolognak. Minden egyes szöveg esetén követni kell ezeket a flageket, ha kombinálod őket, akkor plusz munka, ami a flageket is updateli, mindezt a felkészületlen programozók miatt.


Üdv,
Felhő

u.i.: Amúgy meg ott a lehetőség egy javaslat írására a php-dev listára. Kíváncsi lennék a reakciókra.
14

le voltunk maradva ;)

Hodicska Gergely · 2007. Május. 13. (V), 02.37
Épp most akadtam rá erre (még nem olvastam végig a javaslatot sem), azt hiszem, hogy pont arról szól, amit Te is szeretnél:
http://groups.google.ca/group/mailing.www.php-dev/browse_thread/thread/dfa503a483dcb925/65ffa930a404c320


Üdv,
Felhő
15

hogy mik vannak..

vbence · 2007. Május. 13. (V), 10.33
Köszi a linket. Végigolvastam. Az alapötlet ugyanez, bár ő inkább a függvények oldaláról közelítette meg a dolgot. A kommentek nagyrésze nem túl konstruktív..
16

És a konstruktívak? ;)

Hodicska Gergely · 2007. Május. 20. (V), 20.18
Volt pár tényleg, ami kicsit már néha tipikus Zend féle, marketinggel is kevert érvelés volt, de volt ott egyéb is. Pl. ami a megoldás szempontjából talán érdekes, hogy itt inkább az lett volna a cél, hogy fejlesztés alatt kapjon a fejlesztő visszaljelzést az esetleges hibáiról.

Illetve a felvetett problémák is valósak, amiket említenek a megoldással kapcsolatban.


Üdv,
Felhő
11

Döntés minden esetben

presidento · 2007. Feb. 18. (V), 21.33
Nem lenne könnyebben használható, ha például a $_POST tömb egyes elemeit nem lehetne közvetlenül lekérdezni, csak döntve kiírás típusáról?

<?
$_POST['data'] // hibát generál
$_POST['data']->html(); // form-ba
$_POST['data']->sql();  // sql-be
$_POST['data']->raw();  // ,,ahogy jött''
?>
Így nem fordulna elő az ,,elfelejtettem kitenni'', hiszen nem lenne egyszerűbb mindig raw-ot használni...
12

Nem ilyen egyszerű

vbence · 2007. Feb. 18. (V), 21.51
Néha összefűzünk stringeket, egyébb műveleztet végzünk velük. Ha például összehasolítjuk valamivel akkor már mindjárt nem jó a htmlentities verzió. Ha meg már a raw benne van egy változóban, akkor azt akarjuk kiírni, nem megint a posthoz fordulni. Arról nem is beszélve, hogy nem csak a postból jöhet hibás adat, hanem akár az adatbázisból is. (Hacsak nem a htmlentities-es változatot tároljuk, ami nem megoldás).