php bezpieczenstwo

background image

Bezpieczeństwo skryptów PHP

Marek Jakubowicz m@sote.pl

Zagadnienia:

Zasady bezpiecznego pisania kodu PHP

Konfiguracja PHP: safe_mode, open_basedir

Utajnianie danych dostępu do bazy

Sesje PHP zagrożenia, metody zabezpieczania

Dynamiczne moduły PHP

Konferencja PHP 2003

background image

Zasady bezpiecznego pisania skryptów PHP

1. Należy ustawić opcję register_globals=Off

a) php.ini (globalnie dla wszystkich skryptów)

register_globals=Off

b) httpd.conf ( dla danej domeny
np. w <VirtualHost ...></VirtualHost>

php_admin_value register_globals 0

c) .htaccess (dla poszczególnych
katalogów/podkatalogów)

php_flag register_globals 0

Konferencja PHP 2003

background image

Wyłączenie register_globals eliminuje wiele popularnych
ataków na aplikacje napisane w PHP.

Przykład wykorzystania słabości register_globals=On:

<?php
if (

$password

== '

12345

')

$auth

=1;

...
if (

$auth

==1) print '

tajny kod

';

?>

Wystarczy teraz wywołać skrypt z parametrem $auth=1, żeby
otrzymać 'tajny kod':

http://www.przyklad.com/strona.php?auth=1

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003

background image

2. Jeśli nie możemy ustawić opcji register_globals=off
(np. gdy program z tą opcją przestaje działać), to powinniśmy
zawsze definiować wartości dla zmiennych nie przekazywanych
przez użytkownika.
np. dla poprzedniego przykładu może to być:

<?php

$auth

=

0

;

if (

$password

== '

12345

')

$auth

=

1

;

...

if (

$auth

==

1

) print '

tajny kod

';

?>

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003

background image

3. Przy pisaniu i testowaniu skryptów powinniśmy ustawić
odpowiedni poziom raportowania błędów:

<?php
error_reporting(

E_ALL

);

...
?>

otrzymamy wiele przydatnych informacji o prawdopodobnych
błędach w naszym skrypcie m.in: o niezedfiniowanych zmiennych,
o braku załączanych plików (np. poprzez include),
informacje o anomaliach związanych z sesją itp.

Uwaga!
Zalecane jest wyłączenie tej opcji w wersjach stabilnych
skryptów/aplikacji. np. poprzez:

error_reporting(1)

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003

background image

4. Należy sprawdzać poprawność wszystkich danych przekazywanych
przez użytkownika. W szczególności zmienne, które są
wykorzystywane do określania plików np. wykorzystywe w
include,require, czy odczytania zawartości pliku np. w fopen itp.

<?php
include_once (

$dir

.'

/lib/funkcja.php

');

?>

możliwe jest wywołanie strony z parametrem
dir=

http://www.przyklad2.com

przez co otrzymamy działanie identyczne do kodu

<?php
include_once ('

http://www.przyklad2.com/lib/funkcja.php

');

?>

Spowoduje to wykonanie kodu znajdującego się na serwerze

www.przyklad2.com

, a nie kodu, który miał być wykonany.

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003

background image

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003

Schemat wywołania zdalnego kodu i przejęcia
kontroli nad aplikacją.

background image

5. Ważne pliki konfiguracyjne, biblioteki itp. należy umieszczać
poza głównym katalogiem strony (wskazywanym przez
DocumentRoot).
Np.
Jeśli DocumentRoot dla domeny

www.przyklad.com

wskazuje

na

/home/przyklad.com/public_html

to nasze biblioteki i pliki konfiguracyjne powinniśmy umieścić
poza tym katalogiem np. w:

/home/przyklad.com/lib
/home/przyklad.com/config

a nie w

/home/przyklad.com/public_html/lib
/home/przyklad.com/public_html/config

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003

background image

Bardzo często pliki konfiguracyjne mają rozszerzenie '.inc'. Wtedy,
jeśli nasz plik z konfiguracją znajduje się w podkatalogu
DocumentRoot to wystarczy wywołać adres:

http://www.przyklad.com/config/config.inc

żeby otrzymać na stronie WWW pełne dane konfiguracyjne np.
dane dostępu do bazy danych:

<?php

$dbname

='

baza1

';

$dnuser

='

admin

';

$dbpass

='

12345

';

...
?>

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003

background image

6. Należy przejrzyście budować aplikację, poprawnie formatować
kod, dzielić projekt na małe niezależne moduły. Powinno się unikać
zawiłych zależności pomiędzy skryptami, gdyż trudno będzie później
zweryfikować poprawnośc działania takiego programu.

7. Przy projektowaniu aplikacji powinniśmy przewidywać najgorsze
sytuacje. Np. nasza aplikacja powinna radzić sobie
z niestandardowymi danymi, zmodyfikowanymi wywołaniami strony,
w warunkach, kiedy jest wyłączona baza danych, kiedy nie działają
cookie, kiedy przedawni się sesja itp.

Przydatne informacje można znaleźć m.in.. na stronach:

http://www.tldp.org/HOWTO/Secure-Programs-HOWTO/
http://laughingmeme.org/archives/001055.html

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003

background image

Konfiguracja PHP: safe_mode, open_basedir

1. Bezpieczny tryb PHP: safe_mode
Korzystanie z safe mode jest zalecane zawsze, jeśli jest to możliwe.
W szczególności w środowisku multihostingowym.

Najważniejszą cechą safe mode nie zezwala na dostęp plików,
których właścicielem jest inny użytkownik, niż właściciel
wykonywanego skryptu.
Zabezpiecza to nas przed odczytaniem np. pliku /etc/passwd z
poziomu WWW naszego użytkownika/klienta.

Poza tym safe mode posiada wiele mechanizmów zwiększających
bezpieczeństwo naszych skryptów np. ograniczenie dostępu do
zmiennych środowiskowych, ograniczenie uruchamiania programów
systemowych z poziomu aplikacji PHP itp.

Konferencja PHP 2003

background image

Opcje safe_mode oraz inne ważne opcje PHP związane z bezpieczeństwem:

Nazwa Domyślnie Przykład wartości

safe_mode "0" 1
safe_mode_gid "0" 1
safe_mode_include_dir NULL /home/przyklad.com
safe_mode_exec_dir "" /home/przyklad.com/bin
safe_mode_allowed_env_vars PHP_ PHP_, SSL_
safe_mode_protected_env_vars LD_LIBRARY_PATH PATH, LD_LIBRARY_PATH
open_basedir NULL /home/przyklad.com
disable_functions "" system, fopen
disable_classes "" DBClass

Opcji safe_mode nie można ustawić na poziomie katalogów
w pliku .htaccess, można je ustawić w pliku php.ini, lub,
jeśli chcemy ograniczyć działanie do poszczególnych domen i
katalogów, w httpd.conf.

Konfiguracja PHP: safe_mode, open_basedir Konferencja PHP 2003

background image

Oprócz opcji safe_mode bardzo przydatna jest opcja open_basedir.
Pozwala ona na ogranicznie dostępu do plików do określonego
katalogu. Np. jeśli wstawimy:

open_basedir=/home/przyklad.com

to nie będziemy mogli odczytać plików leżących powyżej tego
katalogu np. /home/test/skrypt.php, /etc/passwd

Jeśli w systemie mamy włączoną opcję open_basedir i safe_mode,
to w pierwszej kolejności sprawdzane są zabezpieczenia
open_basedir, a następnie safe_mode (dot. np. dostępu do plików).

Jeśli nie możemy stosować safe_mode i open_basedir razem, to
w 1. kolejności powinnismy probówać ustawić safe_mode, w
ostateczności używamy samego open_basedir (jeśli włączenie
safe_mode nie jest możliwe).

Konfiguracja PHP: safe_mode, open_basedir Konferencja PHP 2003

background image

Konfiguracja PHP: safe_mode, open_basedir Konferencja PHP 2003

background image

Przykład odczytania pliku /etc/passwd z poziomu skryptu
działającego w trybie safe_mode i open_basedir

Pliki:
-rw-rw-r-- 1 rasmus rasmus 33 Jul 1 19:20 scrypt.php
-rw-r--r-- 1 root root 1116 May 26 18:01 /etc/passwd

skrypt.php (safe_mode)

<?php
readfile

('

/etc/passwd

');

?>

Komunikat na stronie (safe_mode=1):

Warning: SAFE MODE Restriction in effect. The script whose uid
is 500 is not allowed to access /etc/passwd owned by uid 0 in
/docroot/scrypt.php ...

Komunikat na stronie (open_basedir=/home/www/test):

Warning: readfile(): open_basedir restriction in effect.
File(/etc/passwd) is not within the allowed path(s):
(/home/www/test) ...

Konfiguracja PHP: safe_mode, open_basedir Konferencja PHP 2003

background image

Utajnianie danych dostępu do bazy

Jeśli korzystamy z bazy danych, to nasza aplikacja
musi mieć dostęp do danych dostępu do bazy.

Przykładowe metody przekazania danych dostępu:
1. w pliku konfiguracyjnym w postaci jawnej
2. dane wprowadzane z formularza
3. dane szyfrowane
(problem bezpiecznego przechowywania klucza)
3.1 klucz zapisany w pliku konfiguracyjnym
3.2 klucz zapisany w httpd.conf, powiązanie wartości klucza
z lokalizacją skryptu

Konferencja PHP 2003

background image

Przykład ustawienia klucza w httpd.conf:

<VirtualHost www.przyklad.com>
ServerName www.przyklad.com
DocumentRoot /home/przyklad.com/public_html
<Directory “/home/przyklad.com/”>
php_admin_value safe_mode 1
php_admin_value open_basedir /home/przyklad.com/
php_admin_value disable_functions KOD1234567890KOD
</Directory>
(...)
</VirtualHost>

Ważne jest, żeby plik konfiguracyjny nie miał praw czytania
dla innych osób niż administrator:

/usr/local/apache/conf/httpd.conf root.root drwx------
/usr/local/apache/conf root.root drwx------

Utajnianie danych dostępu do bazy Konferencja PHP 2003

background image

Do przekazania klucza wykorzystaliśmy opcję 'disable_functions'.
W aplikacji odczytujemy klucz poprzez wywołanie:

<?php

$key

= ini_get(“

disable_functions

”);

// $key -> otrzymamy

KOD1234567890KOD

$user

='

nazwazakodowana

';

$pass

='

haslozakodowane

';

$dbname

='

baza1

';

$dbuser

=dekoduj(

$user

,

$klucz

);

$dbpass

=dekoduj(

$pass

,

$klucz

);

?>

Otrzymany klucz ma tę własność, że jest dostępny tylko w danej
lokalizacji na dysku. Jeśli skrypt przeniesiemy do innego miejsca,
to klucz nie będzie dostępny. Dzięki temu możemy go użyć do
zakodowania danych dostępu do bazy, a także do kodowania innych
ważnych informacji.

Utajnianie danych dostępu do bazy Konferencja PHP 2003

background image

Można też użyć uproszczonej wersji przekazania danych dostępu,
wykorzystując dodatkowo opcję disable_class (bez kodowania):

Konfiguracja httpd.conf (VirtualHost):

php_admin_value disable_functions admin
php_admin_value disable_class 12345

disable_functions-> login dostępu do bazy
disable_class -> haslo dostępu do bazy

<?php

$dbname

='

baza1

';

$dbuser

=ini_get('

disable_functions

');

$dbpass

=ini_get('

disable_class

');

?>

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003

background image

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003

Schemat działania 2 kopii skryptu w różnych lokalizacjach.

background image

Sesje PHP: zagrożenia, metody zabezpieczania

Podstawowe zagrożenia związane z sesjami PHP:
1. podmiana danych sesji
2. podmiana cełej sesji
3. przejęcie sesji innego użytkownika

Podmiana sesji polega na nieautoryzowanym rejstrowaniu
zmiennych w sesji.

Podmiana całej sesji polega na podmianie np. pliku sesji.

Przejęcie sesji innego użytkownika polega na uruchomieniu
aplikacji z sesją zainicjowaną przez inną osobę. Najczęściej
metoda ta służy do uzyskania dostępu do niedostępnych części
serwisu WWW.

Konferencja PHP 2003

background image

-> 1.) Podmiana sesji, przykład:

<?php
if (! empty(

$_GET

['

zamowienie

'])) {

$zamowienie

=

$_GET

['

zamowienie

'];

session_register('

zamowienie

');

}
?>

W w/w przypadku, jeśli przekazana jest zmienna '

zamowienie

',

to system zapisuje ją do sesji. W tej sytuacji, każdy może zapisać
dowolną wartość dla tej zmiennej.

1. Należy unikać rejestrowania w sesji danych bezpośrednio
przekazywanych przez użytkownika.
2. Jeśli już rejestrujemy dane przekazane przez użytkownika, to
pownniśmy dokładnie sprawdzić poprawność tych danych.

Sesje PHP: zagrożenia, metody zabezpieczania Konferencja PHP 2003

background image

-> 2) Podmiana całej sesji

Domyślnie PHP zapisuje sesje w katalogu /tmp. W środowisku
multihostingowym wiele osób zapisuje dane w tym samym miejscu
i z tymi samymi uprawnieniami. W związku z tym podmiana pliku
sesji jest operacją bardzo prostą.

W celu zabezpieczenia się przed podmianą pliku sesji należy zmienić
katalog przechowywania plików sesji (jeśli sesja jest przechowywana
w plikach).

drwx—x--x/drwxrwxrwx

$dir

='

/home/przyklad.com/sesje/tajnykatalog/

';

session_save_path(

$dir

);

Dla zwiększenia bezpieczeństwa, możemy katalog sesji określić przez
klucz przekazany z httpd.conf.

Sesje PHP: zagrożenia, metody zabezpieczenia Konferencja PHP 2003

background image

Sesje PHP: zagrożenia, metody zabezpieczenia Konferencja PHP 2003

Schemat przejęcia kontroli nad sesją innego użytkownika

background image

Przykład zabezpieczenia ograniczjącego uruchomienie tej samej
sesji dla 2 (i więcej) adresów IP:

<?php
if (! empty(

$_SESSION

['

REMOTE_ADDR

'])) {

if (

$_SERVER

['

REMOTE_ADDR

']!=

$_SESSION

['

REMOTE_ADDR

']) {

setcookie('

sess_id'

,'',time(),"

/

");

header ('

Location: http://'

.

$_SERVER

['

HTTP_HOST

']);

exit;
}
} else {

$REMOTE_ADDR

=

$_SERVER

['

REMOTE_ADDR

'];

session_register('

REMOTE_ADDR'

);

}
?>

1. sprawdzamy czy IP jest zapisane w sesji
1.1 tak: sprawdzamy czy IP w sesji zgadza sie z IP klienta ->2.1
1.2 nie: rejestrujemy IP w sesji: koniec
2.1 tak: koniec
2.2 nie: aktywujemy nową sesję dla użytkownika: koniec

Sesje PHP: zagrożenia, metody zabezpieczenia Konferencja PHP 2003

background image

PHP jest językiem skalowalnym i można do niego dokładać moduły
zwiększające jego funkcjonalność. W standardzie mamy moduły
obsługi bazy danych, ftp, imap, gd i wiele innych. Możemy także
samemu w prosty sposób dopisać nowe moduły i dodać je do
naszej instalacji.

Moduły można dodać na 2 sposoby:
1. wkompilować je do kodu PHP
- wymagana kompilacja lub rekonfiguracja PHP

2. załadować je dynamicznie podczas wykonywania skryptu
- możemy załadować moduł z poziomu dowolnego skryptu PHP
( w trybie safe_mode=1 system nie zezwala na ładowanie
modułów z poziomu skryptów)

Moduły PHP Konferencja PHP 2003

background image

Moduły PHP Konferencja PHP 2003

Schemat ładowania modułów PHP

W trybie open_basedir (bez safe_mode) w łatwy sposób można
napisać moduł, który będzie odczytywał dowolny plik z serwera.

background image

Budowanie modułu PHP:

cd

PHP-4.3.4

/ext

./ext_skel –extname=test1
Creating directory test1
Creating basic files: config.m4 .cvsignore
test1.c php_test1.h CREDITS EXPERIMENTAL tests/001.phpt
test1.php [done].

To use your new extension, you will have to execute the following
steps:

1. $ cd ..
2. $ vi ext/test1/config.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-test1
5. $ make
6. $ ./php -f ext/test1/test1.php
7. $ vi ext/test1/test1.c
8. $ make

Repeat steps 3-6 until you are satisfied with ext/test1/config.m4
and step 6 confirms that your module is compiled into PHP. Then,
start writing code and repeat the last two steps as often
as necessary.

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003

background image

test1.c
...

PHP_FUNCTION(confirm_test1_compiled)
{
char *arg = NULL;
int arg_len, len;
char string[256];

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \
"s", &arg, &arg_len) == FAILURE) {
return;
}

len = sprintf(string, "Congratulations! You have successfully \
modified ext/%.78s/config.m4. \
Module %.78s is now compiled into PHP.", \
“test1”,arg);
RETURN_STRINGL(string, len, 1);
}
...

Moduły PHP Konferencja PHP 2003

background image

test1.php

<?
if(!extension_loaded('test1')) {
dl('test1.' . PHP_SHLIB_SUFFIX);
}
$module = 'test1';
$functions = get_extension_funcs($module);
echo "Functions available in the test extension:<br>\n";
foreach($functions as $func) {
echo $func."<br>\n";
}
echo "<br>\n";
$function = 'confirm_' . $module . '_compiled';
if (extension_loaded($module)) {
$str = $function($module);
} else {
$str = "Module $module is not compiled into PHP";
}
echo "$str\n";
?>

Moduły PHP Konferencja PHP 2003

background image

Jeśli skompilujemy moduł poprawnie, to domyślnie zostanie
on dołączony do pakietu PHP. Jeśli chcemy stworzyć moduł
dynamicznie ładowany, to powinniśmy dodać do kompilacji
opcję: -DCOMPILE_DL=1

(...)
/bin/sh /home/maroslaw/Desktop/src/php-4.3.3/libtool --silent \
--preserve-dup-deps --mode=compile gcc -Iext/test1/ \
-I/home/maroslaw/Desktop/src/php-4.3.3/ext/test001/ \
-DPHP_ATOM_INC -I/home/maroslaw/Desktop/src/php-4.3.3/include \
-I/home/maroslaw/Desktop/src/php-4.3.3/main \
-I/home/maroslaw/Desktop/src/php-4.3.3 \
-I/home/maroslaw/Desktop/src/php-4.3.3/Zend \
-I/home/maroslaw/Desktop/src/php-4.3.3/ext/xml/expat \
-I/home/maroslaw/Desktop/src/php-4.3.3/TSRM -g -O2 -prefer-pic \
-c /home/maroslaw/Desktop/src/php-4.3.3/ext/test1/test1.c \
-o ext/test001/test1.lo \
-DCOMPILE_DL=1
(...)
gcc -shared -L/usr/local/lib -rdynamic -o test1.so test1.o

Moduły PHP Konferencja PHP 2003

background image

Koniec

Marek Jakubowicz m@sote.pl

Konferencja PHP 2003

background image

Zasady bezpiecznego pisania skryptów PHP Konferencja PHP 2003


Wyszukiwarka

Podobne podstrony:
PHP Bezpieczne programowanie phpbep
PHP PHP i bezpieczne logowanie 12 2004
PHP Bezpieczne programowanie phpbep
PHP Bezpieczne programowanie 3
PHP Bezpieczne programowanie phpbep
PHP Bezpieczne programowanie
PHP Bezpieczne programowanie
PHP Bezpieczne programowanie
PHP Bezpieczne programowanie phpbep
PHP Bezpieczne programowanie phpbep
PHP Bezpieczne programowanie
Jak wygenerować bezpieczne, PHP Skrypty
Przemek Sobstel Bezpieczenstwo php mysql zagrozenia
Jak wygenerować bezpieczne, PHP Skrypty
Bezpieczenstwo na lekcji wf

więcej podobnych podstron