« 1 2
Autor Zpráva
krteczek
Profil
hej?: jsi špatně četl? jsem psal že ty funkce vraci v proměnné obsah menu, stránky které uložím do pole a to pole vypíšu na stránce. Výhoda mého rešení je v tom že mám přesně definovane možnosti a jen ty jsou platne, cokoliv jineho vyhodí chybu, a zobrazení že stránka neexistuje. je tu i nevýhoda, přidání stránky znamená přidat do pole řádek s novým klíčem a adresou odpovídající danému klíči. Nicméně jde přidat blok který bude hledat články v databázi, pokud budeme mít články i v ní. Toto používám převážně pro administraci a nemám problém s nějakým podstrčením kodu.
Příklad fce navigace

<?php
function navigace()
{
$nav = '<u>'';
$nav = '<li><a href="./">úvod</a></li>';
$nav = '<li><a href="./index.php?o-nas">O nás</a></li>';
$nav = '<li><a href="./index.php?mapa">Mapa portálu</a></li>';
$nav = '<li><a href="./index.php?neco">stránka3</a></li>';
$nav = '<li><a href="./index.php?jine">stránka4</a></li>';
$nav = '</u>'';

return $nav;
}

krteczek
hej?
Profil *
krteczek
aha, takze mas v navigace.inc.php , function navigace() podla vsetkeho a stranka() deto, iba to som chcel vediet, vdaka ti...
links
Profil *
mila
rabit o tom pise v prispevku: 13.11.2006 18:21:14
Anonymní
Profil *
zdravim vsetkych

co tak pouzit namiesto "page=index.php" "page=111" a vo switchi to skusit takto?

$page = $_GET['page'];

switch($page) {

case 158:
$inc_page = 'xxx.php';
break;

case 169:
$inc_page = 'ccc.php';
break;

case 200:
$inc_page = 'vvv.php';
break;

atd. atd. atd.....

default:
$inc_page = 'index.php';
}

teraz aj ked ti niekto podsype do url nieco ako si pisal 'http://www.nejakejmujweb.net?page=http://0123456789.xpg.com.br/toma.t xt', prepinac switch ti nacita defaultnu stranku. Inac problem zacina o par riadkov kodu skor, bez ohladu na to ci bol napisany zle, alebo vobec. Mam na mysli sterilizaciu vstupu. Posledna osoba ktorej by si mal verit je uzivatel, ako si sa nakoniec presvedcil sam. Stupen dovery niektorych programatorov uzivatelom (utocnikov) jeich aplikacii je neuveritelny.
Prirovnal by som to k nechranenemu sexu s lacnou devou. Vsetko je OK pokial sa neobjavi daaka vyrazka, ktora strasne svrbi. Je to ako adrenalinovy sport.

Preto pravidlo dnesnych dni je: NEVERIT NIKOMU a overovat uzivatelov vstup.

Take drobnosti, ako register_globals = Off v php.ini by mali byt samozrejmostou. Na validaciu vstupu by bolo fajn napisat triedu, ktora sa postara o overenie vstupu, ci uz o data zaslane cez metodu GET, POST, COOKIE, REQUEST???? Ak ocakavas, ze napr. parameter zaslany cez HTTP GET ma byt integer, tak ho vynut:

$page = (int) $_GET['page'];

Ak ocakavas iba pismena, cislice, bla,bla,bla over vstup napr. takto:

if ( !preg_match('/^[a-zA-Z]$/', $_GET['page']) ) { # moze byt aj '/^\w$/', alebo co potrebujes

# vstup nieje validny a teda mozes s nim nalozit ako chces.
# mozes napr. vymazat polozku z pola GET aby si ju nahodou nepouzil.
# mozes najprv zaprotokolovat polozku z pola GET a nasledne ju vymazat.
} else {

$page = $_GET['page']; # ak je vsetko OK pouzij ju
}

No a takto overit vsetko od uzivatela, ci uz data zasielane cez GET, POST, COOKIE ... Taktiez, ak napr. v poli $_POST['txt'] ocakavas daaky text o dlzke 100 znakov a blb ti tam podsunie daake HTML, alebo JavaScript moze nastat pruser. Preto ak ocakavas iba text (bez tagov) odstran ich (strip_tags()), dalej porovnaj dlzku vstupu s tebou povolenou dlzkou atd. atd. atd...

Nakoniec nespravajte sa ako roboty, najprv si trochu premyslite co chcete pisat a az potom to napiste, teraz mam na mysli teba hej?. Sorac, ale 4 prispevky pod sebou od teba, potom 3 a nakoniec 2 je trochu moc, dalo by sa to napisat aj do jednoho, ci nie?. Neide predsa o kvantitu, ale o "kvalitu", teda aspon si myslim. Nevadi ak dakto napise prispevok ktory ma takmer nulovu hodnotu, fora su tu predsa preto, aby sa z povestneho hovna uplietol bic (z hovna bic neupleties) ale horsie je ked to prehlasuje ako najbezpecnejsiu a najlepsiu variantu. Mali by ste si trochu vazit ludi ako je napriklad rabbit a nie ich zbytocne drazdit a ak, tak len aby pustili co najviac svojich vedomosti medzi ludi, ktory sa chcu nieco naucit, ved kazdy sa moze daco od takych ludi naucit. Paci sa mi, ze problem neriesil za vas, ale iba vas naviedol na cestu ako problem vyriesit, cimz sa hodne ludi daco naucilo.
mila
Profil
links
Četl jsem, ale to že je tam použita stejná fce, neznamená, že je to stejně děravé. Tu podmínu tam mám od toho, aby odchytila právě podobné pokusy o útok.
Než se snažit psát nějakou svoji fci, a doufat, že v ní nemám chyby, spolehnu se raději na to, co mi dává php.
finc
Profil
Je vidět, že lepší než přemýšlet je nacpat všude switch-case. A podle toho, co tady čtu, začnu lidem asi nabourávat weby, protože tohle je nehorázné. :)


class Pages
{

const DEFAULT_PAGE = 1;

private static $pages = array(1 => "home", 2 => "kontakt");

public static function isPage($id)
{
return (boolean) in_array($id, self::$pages);
}

public static function getIntPage($id)
{
return (!self::isPage($id) ? self::DEFAULT_PAGE : $id);
}

public static function getPage($id = null)
{
$id = (($id == null) ? $_GET["id"] : $id);
return self::$pages[self::getIntPage($id)];
}

}

include Pages::getPage() .".php";



Samozřejmě, že by to šlo znovu a lépe, ale to už si každý domyslí. Píšu to narychlo tady. Jde o to, že MUSÍM mít přesně uvedeno, které soubory mohu includovat. To, že tady někdo ukazuje, jak pomocí is_file zkontroluje zda soubor existuje a pak ho pěkne includuje, je na vyhazov :)
Kajman_
Profil *
finc
To, že tady někdo ukazuje, jak pomocí is_file zkontroluje zda soubor existuje a pak ho pěkne includuje, je na vyhazov :)

To byla ukázka, jak se může alespoň vyhnout includovaní z www :-) A to že to uvededu jako příklad, ještě neznamená, že to v mých projektech nemám líp, takže to s tím vyhazovem nebude tak žhavé ;-)
links
Profil *
Totalna blbost, pomocou is_file() sa nevyhnes includovaniu z www.
finc
Profil
Kajman_
Pravdou je, že od phpčkářů se málokdy dočkáš nějakého správně konstruktovního nápadu. :)
Mě naštvalo to, že se téměř nikdo nezamýšlel nad tím, že nemůžu nechat includovat jakýkoli soubor. Omezení na adresář je hloupost.

Druhou věcí je to, že klidně lidé vypálí stále se opakující kod (viz. Zasláno: 14.11.2006 14:49:10 krteczek).

Ať si klidně udělá to své include $_GET["dej_sem_co_chces"] .".php", alespoň bude po internetu víc zábavy :)
finc
Profil
links
Nejde o is_file samotné, to beru, ale v konceptu, že stejně includuju co chci (když to existuje), je prostě špatně :)
Timy
Profil
<?php
if(file_exists("./".$page.".php") && $page!="index") include ("./".$page.".php");
else include ("404.php");
?>

Já používám tohle a přijde mi to docela bezpečné... Doufám, že se nemýlím :-).
krteczek
Profil
finc: asi jsem tě nepochopil, to byla reakce na hej?e, doplňoval jsem předchozí příklad jak řeším include o příklad vložení funkce která mi vrací obsah menu, do proměnné, pravda jen fakt zjednodušeně a se zapomenutými tečkami před rovnítky (opraveno).

Dohadujete se, který přístup je lepší, ukázal jsem jeden bezpečný, neříkám že je nejlepší, pro každý projekt se hodí něco jiného.
Pokud potrebuji bezpečne ošetřit vkládáne soubory je to hodně použitelné, hůře se již přidávají další, což lze ale vyřešit náhradou pole za tabulku v db a vytvoření rozhraní přes které ty soubory budu přidávat.
Já toto stejně používám na administraci kde žádné další soubory po dokončení nepřidávám a články umísťuji do db...
krteczek
mila
Profil
Timy
if(file_exists("./".$page.".php") && $page!="index") include ("./".$page.".php");
Tohle bezpečné není.
Pokud budu mít stránku na stejném hostingu, tak ti pošlu něco jako "../../../mujweb/www/mujzakernyskript" a už to jede... Pravda, většinou to nevyjde, protože je nastaveno open_base_dir (prostě jeden uživatel nemůže pouštět skripty druhého)
Ale i tak můžu pustit nějaký tvůj soubor, který k tomu nebyl určen. Pokud máš například konfiguraci v textovém souboru, tak si ji nakrásně vypíšu. A i pokud ne, tak nikdy nevíš, co se může stát, pokud zavolám rovnou nějaký skript, který k tomu nebyl určen. Přinejmenším se mi může podařit vyvolat různé chybové hlášky, které mi pomohou hledat další mezery.
Mimochodem, nedivil bych se, kdyby se i ta tečka na začátku dala ohackovat..
finc
Profil
krteczek: Jde o to, že taková rada za moc nestojí, chce to u psaní více přemýšlet. Mě vadí jen to, že psát opakovaný kod je přesně to, co programátoři nedělají.


$nav = array();
$nav["onas"] = "O nas";
$nav["kontakt"] = "Kontakt";
$nav["links"] = "Links";

function getNavigace(array $nav)
{
if (count($nav) > 0) {
$ret = array();
foreach($ret as $key => $val) {
$ret[] = "<li><a href='./?page=". urlencode($key) ."'>". $val ."</a></li>";
}
return "<ul>". implode("\n", $ret) ."</ul>\n";
} else {
throw new Exception("Nemas navigaci.");
}

}
krteczek
Profil
finc: Aha, no mi šlo jen o doplnění předešlého příkladu a ne o přehlídku programátorského umu. Jen o to že se obsah menu uloží do proměnné a ta se použije jako návratová hodnota funkce. Nepopírám, že tvé řešení je prográmatorsky čistější.
krteczek
Timy
Profil
mila
Aha, no já tomu moc nerozumím, můj více-méně první php script :-).

Ale když tam tu adresu napíšu napevno if(file_exists("http://stranka.cz/".$page.".php") && $page!="index") include ("http://stranka.cz/".$page.".php"); mělo by to už být bezpečnější, ne?

Jinak žádné další soubory na includování tam nemám, jedině bys mohl do indexu includovat zase index (proto tam mám tu podmínku && $page!="index"). Mimochodem trochu by taky mohl pomoci mod_rewrite (IMHO).
mila
Profil
Timy
Includovat to jako "http://stranka.cz/".$page.".php" není dobrý nápad - vlastně hrozný:)
- Nepojedeto, pokud není dovoleno otevírat vzdálené adresy.
- Nebude to includováno jako soubor, ale prostě bude přes internet požadovat nějakou stránku, a tu pak vloží. To znamená, že v includovaném souboru pojede vše od začátku, žádné proměné, žádné připojení k db, ...
- Zbytečně další http požadavek
- Nemůžeš zabránit tomu, aby někdo pustil jednotlivé soubory přímo.

Řešení je dost:
- Na pevno vypsat seznam souborů, které se includovat smí. Je to pár řádků navíc, na druhou stranu je ale z kódu hned vidět, co na webu je. Můžeš to pak použít třeba na generování menu.
- Konktrolovat, že obsahuje pouze alfanumerické znaky.
- Řešení pomocí realpath, které jsem psal dříve (myslím, že tam mám chybu v jednom lomítku)

Jinak to file_exists je vlastně na nic. Stačí zavolat include, a pokud vrátí false, tak ten soubor prostě neexistuje.
Pak bych ještě doporučil místo $page použít $_GET['page'].
Timy
Profil
mila
"Includovat to jako "http://stranka.cz/".$page.".php" není dobrý nápad - vlastně hrozný:)"
Až tak? Jej :-)

"Konktrolovat, že obsahuje pouze alfanumerické znaky."
Tohle řešení se mi líbí, bude stačit, pokud naopak budu kontrolovat, jestli $page neobsahuje lomítka případně tečky? (přijde mi to jednodušší)

"Jinak to file_exists je vlastně na nic. Stačí zavolat include, a pokud vrátí false, tak ten soubor prostě neexistuje."
To je pravda, díky.

"Pak bych ještě doporučil místo $page použít $_GET['page']."
Jo, to tam mám, do $page o pár řádků výš ukládám $_GET['page'], ať už pak můžu pracovat jen s $page.
mila
Profil
Tohle řešení se mi líbí, bude stačit, pokud naopak budu kontrolovat, jestli $page neobsahuje lomítka případně tečky? (přijde mi to jednodušší)
Asi ano, ale nesázel bych na to, nikdy nevíš. Jsou i další ošklivé znaky, třeba nulový (ten třeba použiju na to, abych uříznul to .php co za to přidáváš).

Napiš něco jako
if (preg_match('~^[-a-z0-9_]+$~', $page)) {...}
a máš jistotu.
Ještě bych doporučil, převést na malá písmena, netrestal bych návštěvníka za to, že místo kontakt napsal KONTAKT.
Timy
Profil
mila
výborně, děkuji :-)
links
Profil *
navstevnik nama co pisat do $_GET... :-)
rabbit
Profil
To finc (spíš doplnění než oponování): ano, programátoři nesnášejí opakované psaní kódu, proto používají funkce. A protože správní programátoři mají tendenci (v praxi je to aspoň vysněný cíl ;-) psát nejen na projektu jeden kód jen jednou, ale pokud možno v celém svém životě (trocha nadsázky), máme tady objektové programování. Správně navržený objekt (řešící třeba tu navigaci) je pak znovu použitelný na dalších projektech.

Ale tím výsměchem nad "switch-case" a dalším jsi posunul debatu úplně jinam. V rámci topicu se tady ale řeší "velký průser" ... čili bezpečnost. Z tohoto pohledu je úplně jedno, jestli pro uložení možností použiješ switch(), array(), nebo DB ... a to vše třeba zapouzdřené ve funkcích, třídách, čemkoliv.

Když si přečteš moje předchozí příspěvky, tak zjistíš, že se shodujeme v tom, že programátor sám ví nejlíp, co chce (dovolit) includovat, a to je hlavní.

Pokud někteří lidi tady mají problém pochopit, že píšou děravé aplikace, moc toho ještě nenaprogramovali a je zbytečné je zatěžovat dalšími věcmi.
« 1 2
Toto téma je uzamčeno. Odpověď nelze zaslat.

0