ugrás a tartalomhoz

Egy weboldal biztonságos kialakítása

dc-hungary · 2008. Május. 4. (V), 10.20
Üdv!

Egy olyan weboldalt szeretnék kifejleszteni, amely biztonságos.
Szóval nem lehet könnyen bejutni a rendszerbe, a config.php-ban a jelszót egy hacker config.php scanneléssel ne tudja megnézni stb.
Szóval arról kérnék információt, hogy hogyan építsem fel a weboldalam, hogy az biztonságos legyen?
Mindent amit ezzel kapcsolatba tudni kell, osszátok meg velem légyszives!

válaszaitokat előre is köszönöm :)
 
1

Biztonsági wrapper funkciók

vbence · 2008. Május. 4. (V), 11.29
Mostanában már nem fenyeget a register_globals révén az inicializálatlan változók veszlye. A legáltalánosabb a XSS (cross-site scripting) és az SQL injection (bár ez a második lényegesen ritkább).

Hiba amit elküvethetsz például ez:

echo ('<div class="nev">' . htmlspecialchars ($rec["nev"]) . '</div>');
A hiba nem az utasításban van, az biztosnágos, hanem a hozzáállásban. Ha így (explicit módon) gondoskodsz a speciális karakterek kiszűréséről, elég egyetlen helyen kifelejtened a htmlspecialchars-t, és máris támadható az oldalad. Ehelyett egy lehetséges megoldás:

safe_echo ('<div class="nev">%s</div>', $nev);
ehhez persze meg kell írnia függvényt:

function safe_echo () {
    $args = func_get_args ();
    $pattern = array_shift ($args);
    foreach ($args as &$arg)
        $arg = htmlspecialchars ($arg);
    echo (vsprintf ($pattern, $args));
}
Így garantáltan minden átmegy az ellenőrzésen. Ugyanez a módszer működik az adatbázis-elérésnél is. Ott persze a htmlspecialchars helyett a mysql_real_escape_string fogja biztonságossá tennia paramétereket. És van már mysqli kiterjesztés is (ami helyettesíti a hagyományos mysql funkciókat), amibe ez a védelem be van építve.

Hasznos lehet még a referer check amit egy másik kérdésedre írtam.. ;)


A config.php és társainak veszélye egy egészen más probléma. Itt ugyebár a php kiterjesztés miatt nem hézhet bele a fájl forrásába, a veszél főleg az, hogy te elküldöd neki. Ez a fájlkezelés problémaköre. Ha bármilyen fájlhoz hosszáférsz a szerveren, ami nem fix string, hanem valami változó határozza meg, ott mindig alkalmazz ellenőrzést, pontosabban szűrést.

A szűrő lehet átengedő ilyenkor mindent átengedsz, ami nem különösebben tilos. Ez például egy ilyen (ha nincs benne tiltott karakter, akkor átmegy):

function check_name ($filename) {
    if (strpos ($filename, "/") === false) {
        // van benne "forward slash" karakter: NEM biztonságos
        return false;
    } else {
        // nincs benne tiltott karakter: biztonságos
        return true;
    }
}
Tesztelhetnénk még több tiltott katakterre, például pont vagy ékezetes betük, semmit sem változtat azon, hogyez egy alaból átengedő szűrő, mert mindent átenged, amiről nem rendelkezünk. Tehát ha kifelejtünk egy ártalmas karaktert, akkor végünk...

Lehet alapból tiltó is a szűrő... Itt az else ágban lesz a tiltás, tehát mindent tiltunk, amiről külön nem jelentjük ki, hogy biztonságos pl:

function check_name ($filename) {
    if (preg_match ('/^[a-z]+$/i', $filename)) {
        //megfelel a mintának: csak betük
        return true;
    } else {
        // nem felel meg a mintának
        return false;
    }
}
Itt csak betükből álló nevet fogadunk el, semmi mást. Szintén bővíthetnénk még a szűrőt, példul átengedhetnénk a kötőjelet és a pontot is. Általában ez a szigorú "mindent tilos, amit nem szabad" megközelítés a preferált.
2

Itt is le van irva

Ronyn · 2008. Május. 4. (V), 12.15
valahol...
Pl.: includolt fájlok védelme közvetlen meghivás ellen:
if(__FILE__==$_SERVER["DOCUMENT_ROOT"].$_SERVER["PHP_SELF"]){die();}
3

hazsnos lehet

vbence · 2008. Május. 4. (V), 12.33
Átfogóbb védelmet jelent egy .htaccess-es deny from all, vagy ha csak függvényleket tartalmaznak ezek az include fájlok.
4

pontosan

Szekeres Gergő · 2008. Május. 4. (V), 12.50
ha odafigyelsz és átgondoltan áttervezed a programot, akkor lesznek fájlok, amiben az osztályok/függvények találhatóak, illetve lesznek fájlok amiben a végrehajtás. a függvény fájlokat hívogathatja bárki, úgy sem történik semmi, a végrehajtó fájlok pedig pont azért vannak(nyilván az authorizációs funkciókat ide kell beépíteni).
5

config

dc-hungary · 2008. Május. 4. (V), 13.27
Nemtudom..


egy cms-t akarok csinálni, csak nemtom hogy csináljam.
érdemes e az index.php-ba mindent beletenni , (title,meta tagek, stb) vagy mindennek külön php-t csináljak.. vagy nemtudom..

az a lényeg, hogy úgy kell megírni az index-t, hogy váltható téma van , szóval minden témához igazodjon..
próbálkoztam már egy kicsit, de ez még semmi:
<?php
define("title","OLDAL NEVE");
define("template_name","envision");
define("site_name","MD2 Cms");
define("site_slogen","Egy egyszerű cms rendszer mindenkinek!");
$template_name = "envision";
if($template_name == "envision"){
define("headerlinks","<div id='header-links'>
			<p>
				<a href='index.html'>Home</a> | 
				<a href='index.html'>Contact</a> | 
				<a href='index.html'>Site Map</a>			
			</p>		
		</div>");
}
define("felso_menu","<div  id='menu'>
			<ul>
				<li id='current'><a href='index.html'>Home</a></li>
				<li><a href='index.html'>Archives</a></li>
				<li><a href='index.html'>Downloads</a></li>
				<li><a href='index.html'>Services</a></li>
				<li><a href='index.html'>Support</a></li>
				<li class='last'><a href='index.html'>About</a></li>		
			</ul>
		</div>	");

$inc_dir = ".";


$images_mappa = "$inc_dir/portal/theme/$template_name/images/";

include "portal/theme/$template_name/index.php";  //theme betöltése
?> 
és akkor a portal/theme/téma neve/index.php-ba így csinálom a dolgokat:
<link rel="stylesheet" href="<?php print "$images_mappa"; echo template_name; print ".css"; ?>" type="text/css" />
<title><?php echo title; ?></title>

		<!--header -->
		<div id="header">			
				
			<h1 id="logo-text"><a href="index.html"><?php echo site_name; ?></a></h1>		
			<p id="slogan"><?php echo site_slogen; ?></p>		
			
			<?php echo headerlinks; ?>	
			

tanácstalan vagyok,hogy hogyan építsem fel jól ezt a cms-t :(
6

cms

vbence · 2008. Május. 4. (V), 15.03
Nagyon dícséretes, hogy gondolunk az újrafelhasználhatóságra (ne kellessen minden új oldalt nulláró kezdeni), DE puszán azért, mert vannak újrafelhasználható moduljaink, ne dobálózzunk egyből a CMS kifejezéssel.

Szerintem egyszerűen csak modulokat (include-fájlokat) készíts, jól definiált felelősséggel (melyik modulnak mi a feladata). Azokat a PHP-kep pedig, amik a konkrét (weben látható) oldalt építik fel tedd csak az "eldobható" kategóriába. Ha igazi oldalkat készítesz nem lesz két ugyanolyan. Az egyiken cikkek lesznek, a másikon blogbejegyzések. Az egyiken lesznek rovatok a másikon nem. Az egyiken minden cikkhez kötelező lesz képet felvinni,a másikon nem. Itt a cikkek első 100-100 karakterét szeretnék a címlapon látni, ott különszeretnnek lead-et írni minden cikkhez. És így tovább...

Az, hogy hogyan építs fel egy php-s weboldalt pedig megér egy nem-kis cikksorozatot. Nem mondom, hogy nézz utána, hogyan csinálják az open source projektek (wordpress, drupal), mert tisztelet a kivételnek szörnyűnél szörnyűbb példák vannak. Ha valaki ismer idevágó szakirodalmat én is kíváncsi lennék.

(Mellesleg szerintem eza kérdés már új témába illett volna, mivel abszolút semmi köze a témaindítóhoz...)
7

cms

rrd · 2008. Május. 4. (V), 20.00
Ha cms-t gyártasz akkor érdemes utánanézned a MVC elvének, sokat fog segíteni. Másrészről szerintem jobban járnál ha használnál valamilyen PHP-s keretrendszert, mint pl a cakePHP, mert ezek sok sok olyan dologtól megkímélnek, hogy fel kell találnod újra a kereket.

Bocsi, az eredeti kérdésre akartam válaszolni nem erre a hozzászólásra... Úgy látszik kéne aludnom egyet :)
8

vitatkoznék

vbence · 2008. Május. 4. (V), 21.51
Egyrészt az MVC elv eléggé megkérdőjelezhető webalkalmazásoknál, másrészt meg ha az embernek még fogalma sincs, mi micsoda (ahogy a fenti kódból tűnik), jobban jár, ha a PHP alaplogikáját sajátítja el előbb, aztán ha már érti, megkönnyítheti a dolgát mindenféle előcsomagolt kódokkal.
11

mvc csak könnyít

Szekeres Gergő · 2008. Május. 4. (V), 23.24
nem értem miért írod ezt. az mvc fejlesztések elejénél minimális időráfordítás, utána viszont sokszorosan megtérül. szerintem pont, hogy a webalkalmazások egy olyan területe a webfejlesztésnek, ahol igenis lehetőleg követni kell az előre kitaposott utakat, máskülönben elveszünk a dzsungelben.

amúgy a hozzászólás 2. felével egyetértek.
18

Nem értem, miért

Joó Ádám · 2008. Május. 6. (K), 17.57
Miért lenne az MVC megkérdőjelezhető? Szerintem elég jól tud illeszkedni a platformhoz, jelentősen megkönnyíti a munkát.
És nem vagyok híve a „tanuljuk meg, ahogy sikerül, aztán évekig vetkőzzük le a rossz szokásokat” hozzáállásnak.
9

végleges döntésem

dc-hungary · 2008. Május. 4. (V), 21.55
arra a következtetésre jutottam, hogy jobban járok ha írok modulokat.. (login,kereső,hirdetések,stb), és aztán azokat a design oldalon már csak megfelelően meg kell hívni.
ez a legpraktikusabb , nem? s aakkor nem kell újraírni minden alkalommal..

köszi a válaszokat
10

nem

Szekeres Gergő · 2008. Május. 4. (V), 23.21
nyilván attól függ hogy írod meg. ha szigorúan követed az oop paradigmákat, akkor valóban hasznos munkát végzel, de ha beleépíted az üzleti logikát a kódba, akkor nem vagy sokkal előrébb. Ahhoz, hogy egy valóban univerzálisan használható rendszert tudják készíteni jól kell tudni absztrakt módon programozni. Ez viszont messze van a login , kereső, hírdetések moduloktól. Hozz létre hírdetés osztályt, amit késöbb ki tudsz bővíteni. Készíts egy modellt a members táblából, hogy tudják bele könnyen írni úgy, hogy egy esetleges módosítást csak egy helyen kelljen lekövetni a kódba stb. De ennek a tárgyalása kivezet ennek a topicnak a tartalmából.
12

html escape

Protezis · 2008. Május. 5. (H), 00.32
Nekem pl. van egy ilyen fuggvenyem, ami automatikusan meghivodik a $_POST tombbel, mint parameterrel:
protected function html_escape($param) {
		if (is_array($param)) {
			foreach ($param as $key => $value) {
				$param[$key] = $this->html_escape($value);
			}
			return $param;
		}
		return htmlspecialchars($param);
}
13

Fontos dolgok

janoszen · 2008. Május. 5. (H), 09.15
Szerintem, lényeges dolgok:

1. Rendszer a docrooton kívül
A rendszer magját, jelszavakat, stb. mind illik a document rooton kívül tárolni, ugyanis egy hibás apache beállítás és az egész történet megy ki a netre. Ez a hiba nem is túl ritka, a Facebooknál is előfordult. Ha a host nem támogatja, keresni kell másik szolgáltatót, van elég host aki támogatja.

2. register_globals, magic_quotes_gpc
Ezeket nem kellene elmondani, de mégis mindig előkerül, ezeket offra illik állítani.

3. escape, escape, escape
Mindig elmondom, mindig előkerül, minden adatot, legyen az MySQL, fájl vagy bármi más escapelni kell. Ezt nem lehet megkerülni, minden modulnál, minden kódrésznél ami valamilyen adatmozgatást végez, ezt végig kell gondolni. Soha, soha, soha ne halaszd el későbbre! Sok mindent el lehet halasztani későbbre, ezt nem.

4. Elfedés
MySQL-t, fájlműveleteket illik elfedni. Ha nem feded el, a fejlesztőnek ott lesz a csábítás, hogy küldjünk be egy nem escapelt queryt.

5. KISS
Keep It Simple Stupid. Az egyszerűbb sokszor jobb.

6. MVC
Ha rendesen el van választva a megjelenéstől a programlogika és a programlogikának minden eleme (create, update, delete, stb) meg van csinálva, kissebb a veszélye annak, hogy valahol gányolás történik.

7. XSS
User adatokat escapelni kell, ld. escapelés. Az nem megoldás, hogy globálisan escapelsz valamit, az adatmozgás céljától függően kell escapelni. Ha nem így teszel, az kb ugyanolyan rossz mint a magic_quotes.

8. hibaüzenetek
Soha, soha, soha ne engedjünk ki SQL vagy PHP hibaüzeneteket a felhasználónak! var_dump és a haverjai még véletlenül se forduljanak elő a kódban!

+1. Gányolás
A biztonsági hibák 99%-a arra vezethető vissza, hogy valahol ad-hoc módon belenőnek fícsörök. Ez nem baj egészen addig, amíg a megfelelő időpontokban visszabontod a rendszert és értelmesen lefejleszted az előzőleg belegányolt dolgokat. Ha ez nem történik, akkor nő és nő és nő a szarhalmaz egészen addig, amíg a nyakadig ér.

+2. RTFM
Nagyon sok szívástól és biztonsági hibától kímélheted meg magad, ha elolvasod a doksit és a hozzá tartozó user commenteket. php.net a legjobb barátod. Angolul. Nem magyarul.

Ennél még valószínűleg lehetne lényeges dolgokat mondani, de ezek a legfontosabbak.
14

re:fontos dolgok

dc-hungary · 2008. Május. 5. (H), 09.38
1. Rendszer a docrooton kívül, ez alatt mit értesz?

a weblapom a wwwroot-mappán belül van, és az ilyeneket, amiket ehhez felsoroltál a wwwroot-al egy mappába tegyem?
szóval

wwwroot --> és ebben van az index.php, meg a weblap többi része
config.php
stb..
így gondoltad ezt?

az escapelésnek majd utána nézek,mert fogalmam sincs mi az:)

és köszi a sok információt :)
15

docroot

janoszen · 2008. Május. 5. (H), 11.42
Docrooton kívül azt értem, hogy a document rooton belül (azaz ami a webről látszik) egyetlen egy PHP és max egy pár CSS fájl legyen, a rendszer többi (kényes) része pedig egy vagy több szinttel följebb, hogy akkor se lehessen fölhívni, ha a PHP-t kikapcsolod. Ergó igen, a config.php-t és a haverjait ki kell venni a wwwrootból.

Az escapelés tekintetében illik megnézni a mysql_real_escape_string függvényt illetve ha fájlba írsz akkor az addslashes-t vagy hasonló függvényt.
16

kössz

dc-hungary · 2008. Május. 5. (H), 12.07
köszi
mostmár remélem boldogulok ;)