JavaScript Sandbox tesztelése
Sziasztok!
Nem teljesen megbízható forrásból származó javascript kódot kell futtatnom, ezért csináltam egy homokozó-szerűséget.
A lényege, hogy a beküldött kódot (ami egy függvény lehet) leellenőrzöm, kiveszem belőle a veszélyes elemeket (pl. eval), megnézem hogy milyen lokális változókat akar a kódbeküldő használni, és csupán egy golbális objektumhoz (a neve "arc"), ennek adataihoz és metódusaihoz engedem hozzáférni a kódot, a DOM-hoz, más külső forrásokhoz nem.
Azt hiszem jól kigondoltam az eljárást, de minden javaslatot szívesen fogadok (a szerver oldali ellenőrző algoritmussal, PHP nyelvvel kapcsolatban, de főleg hogy JS oldalon mit kellene még engedélyezni vagy milyen biztonsági rést hagytam meg, stb; illetve hogy egyes böngészők esetleg olyan egyedi JS metódusokat engednek, ami még veszélyes lehet stb stb.)
Ha valakinek van kedve, tesztelheti a homokozót, ezen a linken:
homokozó teszt
Ezen a linken megtalálhatjátok a szerver oldali forráskódot is.
A teszt lehet egy kis játék is:
A baloldalon szerkeszthető és "beküldhető" függvénnyel ha valakinek sikerült kijönnie a homokozóból, úgy mutathatná be, hogy hozzáfér a DOM-hoz, hogy az input2-ként megjelölt mezőbe beleír valamit.
Köszönöm a segítséget és a javaslatokat!
■ Nem teljesen megbízható forrásból származó javascript kódot kell futtatnom, ezért csináltam egy homokozó-szerűséget.
A lényege, hogy a beküldött kódot (ami egy függvény lehet) leellenőrzöm, kiveszem belőle a veszélyes elemeket (pl. eval), megnézem hogy milyen lokális változókat akar a kódbeküldő használni, és csupán egy golbális objektumhoz (a neve "arc"), ennek adataihoz és metódusaihoz engedem hozzáférni a kódot, a DOM-hoz, más külső forrásokhoz nem.
Azt hiszem jól kigondoltam az eljárást, de minden javaslatot szívesen fogadok (a szerver oldali ellenőrző algoritmussal, PHP nyelvvel kapcsolatban, de főleg hogy JS oldalon mit kellene még engedélyezni vagy milyen biztonsági rést hagytam meg, stb; illetve hogy egyes böngészők esetleg olyan egyedi JS metódusokat engednek, ami még veszélyes lehet stb stb.)
Ha valakinek van kedve, tesztelheti a homokozót, ezen a linken:
homokozó teszt
Ezen a linken megtalálhatjátok a szerver oldali forráskódot is.
A teszt lehet egy kis játék is:
A baloldalon szerkeszthető és "beküldhető" függvénnyel ha valakinek sikerült kijönnie a homokozóból, úgy mutathatná be, hogy hozzáfér a DOM-hoz, hogy az input2-ként megjelölt mezőbe beleír valamit.
Köszönöm a segítséget és a javaslatokat!
for in
Köszi, ez kimaradt.
5 perc után
hopp!
Na lám ezt elfelejtettem kivédeni (márminthogy az asszoc. index tömbbel is elérhetők az objektumtulajdonságok).
Ez elgondolkodtató, hogy hogyan lehetne ezt megelőzni...
Azt hiszem hogy a legjobb, ha a "this" kulcsszót is tiltottá teszem.
Van még valamilyen globális objektum, amivel meg lehet ezt tenni?
Köszi ismét, pont az ilyenek miatt dobtam fel ezt a témát.
Mondjuk most beugrott, hogy miért hagytam meg direkt engedélyezettre a "this"-t: mert a későbbiekben ez is egy másik objektumra fog mutatni, így nem lesz veszélyes tulajdonsága. Igen, először ezt fogom tenni itt a tesztben is. (Persze ettől még kérdéses, hogy van-e egyéb objektum, ami kijáratot ad.)
Megjelent a v1.1
Boldogan jelentem be, hogy megjelent az 1.1-es verzió, tesztelhető ugyanott:
sandbox 1.1
Az új változat -- köszönhetően a hozzászólók értékes segítségének -- 13%-kal biztonságosabb és 5%-kal kevesebb bugot tartalmaz.
A bátorító és segítő hozzászólásokat ismét szívesen fogadom és üzemszerűen gyűjtöm :-)
Köszönöm!
v1.11
Hát ennek nincs sok teteje
Ez például egy elfogadott js megoldás:
Vagy itt egy másik:
Csináljunk tetőt
Köszi az észrevételeket, látom lesz min dolgoznom még :-)
Szóval először is a legfontosabb: a leglényegesebb számomra hogy ne lehessen kijönni a homokozóból, az egyelőre másodlagos, hogy túlságosan lekorlátoz.
Ellenben viszont egyértelmű, hogy mindent meg akarok engedni ami nem veszélyes, az észrevételeid ebben mindenképp segítenek.
Az első példádban 2 hiányossága van a homokozónak:
1: (ezt könnyű javítani) nem engedi, hogy a függvénydefinícióban a kapcsos zárójel már az első sorban legyen (ezt megcsinálom)
2: a "function" kulcsszó nem engedélyezett pillanatnyilag.
Ez utóbbival több gondom van:
Előszöris egy rekurzív rendszerbe kell raknom a parsolást, hogy ha a függvényen belül deklarálva van egy újabb, akkor azon is végig kell menni (ezt még nem olyan vészes megoldani)
Másodszor figyelni kell a változó-hatáskörre: amit a külső függvényben lokálisan deklaráltam, az a belsőben elérhető (vagyis engedélyezett kulcsszó a belsőben is) ellenben a külsőben nem engedélyezett.
De azt hiszem, ha odafigyelek, abből nem lesz biztonsági gubanc, úgyhogy megcsinálom.
A 2. példáddal egyrészt semmi gondom nincsen, ha pongyola akarok lenni; másrészt viszont egyelőre nincs ötletem, hogy hogyan valósítsam meg.
A pongyola megoldás, hogy megkövetelem a felhasználóktól, hogy deklarálják le előre az objektumtulajdonságokat helyi változónak is:
(Vagy esetleg azt mondom hogy az object literal nem támogatott)
(
szerk:
egyébként így is jó: d={"hello":"szia"...
)
(Az alapelv, hogy az a kulcsszó, ami nincs helyi változóként var-ral elődeklarálva, az feltételezhetően és kötelezően az "arc" objektum része, és nem globális változó; azt ugyanis el akarom kerülni, hogy globális változókat használjanak, mert az összeütközéseket okozhat, és nem akarom azt sem, hogy globális változókhoz, objektumokhoz férjenek hozzá)
Viszont ha nem akarok pongyola lenni, akkor nincs túl jó ötletem arra, hogy hogyan ismerem fel, hogy egy kulcsszó (a példában a "hello" és a "belo") csupán egy, már előre helyileg deklarált objektum tulajdonsága.
Az szerinted úgy jó, ha egyszerűen megnézem, hogy "{" vagy "," és ":" között van-e?
A ternális operátor, amiben van még ":" az egyetlen ami bekavarhat... (vagy van más is?)
(Azon gondolkodok még, hogy segítene-e a "with" kifejezés használata a változók bekorlátozásában)
Minden javaslatot szívesen fogadok ennek a problémának a feloldására.
Köszönöm!
Sandbox V2.0 tetővel
Nos, eljött a 2.0 ideje, object literal és belső függvény támogatással.
Örülnék, ha lenne valaki aki tesztelné, próbálgatná...
Sandbox 2.0
Köszönöm!
Más megközeltés
A Chrome picit megzavarodik, amikor window nevű helyi változót hoz létre az ember, úgyhogy ezen még dolgozni kell. A fenti kód Chome-ban volt tesztelve.
Szép!
(
Egyébként próbálgattam a kódodat, és érdekes módon az eval az működött, még nem jöttem rá miért:
De más okok miatt akarom ezt mindenképp szerver oldalon levédeni, például azért, mert szerializálni akarok komplett objektumokat úgy, hogy a bennük lévő helyi változó pillanatnyi értéke is rögzüljön, ezt pedig nekem csak úgy sikerült megtennem, ha a függvényekben volt egy getter is ... meg egyéb olyan dolgokat akarok csinálni ami miatt a szerver oldali preparálás egyszerűbbnek (és talán hatékonyabbnak) tűnik (az én speciális esetemben).
Köszi az ötletet!
eval és globál
A globális változó létrehozása valóban hiányossága a módszernek, azonban adat átvitelére nem alkalmas, hiszen a következő futáskor a függvény már maszkolva kapja meg. Legfeljebb, monoton növekvő számsorok átvitalére képes:
eval hogyan marad?
A globális változókkal kapcsolatban most esett le, hogy az invoke minden gyanús függvényhívásnál végigjárja, immunizálja a window objektumot, ami nem túl hatékony. Talán az úgy jobb lenne, hogy csak egyszer állítanánk elő a futási környezetet, aztán már csak meghívnánk az előkészített függvényt. (A megvalósításon nem gondolkodtam, de gondolom closure-ral meg lehet csinálni). Ebben az esetben azonban megmarad a globális változós probléma.
Van azonban még egy gond: a homokozóba zárt eljárásoknak mindenképp kell egy külső objektum, amin keresztül dolgozhatnak (legalábbis az én alkalmazásomban ez mindenképp szükséges) tehát ezt az objektumot is minden meghíváskor klónozni kell.(Sőt talán hívás után még vissza is kell szinkronizálni a hivatalosan megváltoztatható adatokat?) (Míg szerver oldali feldolgozásnál egyszerűen nem engedek meg olyan parancsot kiadni, ami módosítaná az objektumot -- de ezzel még nem vagyok kész)
perzisztencia
Ha szeretnél egy objektumot, ami megőrzi az értékét (gondolom az "arc" nálad erre szolgál), ezer és egy módon teheted elérhetővé a függvény számára. (Pl var, vagy a this-t pótoló objektumban).
Ki lehet egészíteni esetleg azzal a kódot, hogy a függvény lefutása után egy újabb for .. in végigmegy a window-n, és azokat a változókat, amik nem léteztek a függvényhívás előtt egyszerűen undefined-re állítja.
php javascript parser
Ez azért teljesen más dolog...
Ráadásul pillanatnyilag használhatatlan, és nem úgy tűnik, hogy ez változni fog (már 2005 óta nem fejlesztették???)
Mindenesetre az elképzelés jó, hasznos lehet.
Tipp