Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

16 Stron V   1 2 3 > »   
Reply to this topicStart new topic
> Bezpieczeństwo skryptów PHP, Jak zabezpieczyć się przed włamaniem
Diwi
post 5.05.2005, 13:21:40
Post #1





Grupa: Zarejestrowani
Postów: 245
Pomógł: 4
Dołączył: 22.01.2005

Ostrzeżenie: (0%)
-----


Witam.

Chciałbym rozpocząć temat o bezpieczeństwie skryptów php. Na forum istnieje już temat o bezpieczeństwu przy wykonywaniu zapytania SQL lecz nie ma o ogólnym bezpieczeństwie skryptów.

1. Złe używanie include.

Często dołączamy pliki dynamicznie pobierając miejsce gdzie znajduje się plik metodą GET.

Przykładowy adres:
http://www.jakas-strona.pl/index.php?plik=katalog.php

Kod php:
  1. <?php
  2. include($_GET['plik']);
  3. ?>


Taki skrypt dokonałby dołączenia pliku katalog.php do skryptu lecz co by się stało gdyby włamywacz wpisał taki adres:
http://www.jakas-strona.pl/index.php?plik=...t-niszczacy.php

Dajmy na to że skrypt znajdujący się na serwerze hakera wygląda tak:

  1. <?php
  2.  
  3. $katalog = opendir('./'); /* skrypt otwiera katalog w którym się znajduje (zostaje wywołany */
  4.  
  5. while ($plik = readdir($katalog)) {
  6.  
  7. unlink($file);
  8.  
  9. }
  10.  
  11. ?>


No i jeżeli pliki w katalogu mają uprawnienia pozwalające na usunięcie ich przez skrypt to możemy się pożegnać z plikami w katalogu.

Jak temu zapobiec questionmark.gif

Rozwiązanie 1.

Tworzymy taki include:
  1. <?php
  2. include('./'.$_GET['katalog']);
  3. ?>


Taka instrukcja pozwala na dołączanie jedynie plików które znajdują się w katalogu ze skryptem czyli nie można załączyć pliku z innego serwera.

Ja narazie pamiętam tylko tyle lecz jeżeli znacie jakieś inne błędy popełniane przez programistów a także sposoby walczenia z nimi to się tutaj dopiszcie smile.gif

Pozdrawiam

// prosiłbym moderatorów (jeżeli można) o przyklejenie tego tematu

---
Przyklejone - hwao
Go to the top of the page
+Quote Post
bregovic
post 5.05.2005, 15:49:34
Post #2





Grupa: Zarejestrowani
Postów: 562
Pomógł: 15
Dołączył: 8.08.2003
Skąd: Denmark/Odense

Ostrzeżenie: (0%)
-----


Zaczynając od podstaw, to jakiekolwiek używanie zmiennej $_GET razem z konstrukcja require lub include jest pomyłką, błędem i koszmarem. Jeśli już naprawdę musisz include'ować coś pochodzącego z adresu, to zrób sobie tablicę w skrypcie, coś w stylu:
  1. <?php
  2.  
  3. $tablica[1] = 'jakisplik1';
  4. $tablica[2] = 'jakisplik2';
  5. $tablica[3] = 'jakisplik3';
  6. $tablica[4] = 'jakisplik4';
  7.  
  8. include $tablica[$_GET['costam']];
  9.  
  10. ?>


Oczywiście to rozwiązanie jest koszmarkiem jeśli masz dużą ilość akcji - wtedy trzeba zrobic cos w tym stylu:
  1. <?php
  2.  
  3.  
  4. if(file_exist('bezpieczny_katalog/'.$_GET['costam'].'.php'))
  5. {
  6. include 'bezpieczny_katalog/'.$_GET['costam'].'.php';
  7. }
  8.  
  9. ?>


Generalna zasada to zawsze zakładać że input inny niż tego chcemy, i że user próbuje nas zaatakować. winksmiley.jpg


--------------------
Prank - for the fun. Mac - for the simplicity. Deviantart - for the kick.
Life is ours, We live it our way -- Metallica
Go to the top of the page
+Quote Post
Wave
post 5.05.2005, 16:24:58
Post #3





Grupa: Zarejestrowani
Postów: 332
Pomógł: 6
Dołączył: 13.01.2005

Ostrzeżenie: (0%)
-----


A najczęstszym błędem jest stosowanie zmiennych bez odnoszenia się do tablic superglobalnych.
np.
  1. <?php
  2.  
  3. $var; // zamiast
  4. $_COOKIE['var'];
  5. $_POST['var'];
  6. $_GET['var'];
  7. $_SESSION['var'];
  8.  
  9. ?>

Co daje pole do popisu, dla potencjalnego hax0ra.
Jeżeli nie chce nam się pisać tych długich zmiennych można zastosować coś takiego:
  1. <?php
  2.  
  3. while (list($k, $v) = each ($_GET)) {
  4. ${$k} = $v;
  5. }
  6.  
  7. ?>


----
Sorka ze sie dopisze ale smile.gif nie chce mi sie pisac nowego posta smile.gif)

Jak komus sie nie che to polecam
  1. <?php
  2. $g = & $_GET;
  3. // i mammy
  4. $g['id'];
  5.  
  6. ?>

Go to the top of the page
+Quote Post
sobstel
post 5.05.2005, 16:36:52
Post #4





Grupa: Zarejestrowani
Postów: 853
Pomógł: 25
Dołączył: 27.08.2003
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Cytat(bregovic @ 2005-05-05 15:49:34)
Zaczynając od podstaw, to jakiekolwiek używanie zmiennej $_GET razem z konstrukcja require lub include jest pomyłką, błędem

a na przyklad w takiej konstrukcji :

  1. <?php
  2.  
  3. if (ctype_alnum($_GET['go'])) {
  4. include $_GET['go'].'.php';
  5. }
  6.  
  7. ?>


questionmark.gif?

tak czy owak moim zdaniem najwazniejsze w tym wszyskim jest odpowiednie filtrowanie wszystkiego co pochodzi z zewnątrz lub w czym zewnętrzny użytkownik mógł maczać palce ... i zdawać sobie sprawę z tego, że nigdy nei jesteśmy w pełni bezpieczni.


--------------------
"If debugging is the process of removing bugs, then programming must be the process of putting them in..."
sobstel.org
Go to the top of the page
+Quote Post
Speedy
post 5.05.2005, 17:06:27
Post #5





Grupa: Zarejestrowani
Postów: 651
Pomógł: 28
Dołączył: 4.12.2004

Ostrzeżenie: (0%)
-----


To ja dodam od siebie jeszcze, że niektóre osoby pisząc aplikacje internetowe, stosują coś takiego jak przechowywanie poufnych danych o userze (po zalogowaniu) w pliku cookie. Taki potencjalny H4X0R może sobie potem swobodnie przeglądać zawartość tych plików i dowolnie je modyfikować. Najgorzej jest wtedy, gdy w takim pliku przechowywana jest wartość zmiennej odpowiedzialna np. za uprawnienia administratora... Wtedy wystarczy ją odpowiednio podmienić i śmiga winksmiley.jpg .
Rozwiązaniem są sesje, które przechowują dane na serwerze.

Pozdrawiam.


--------------------
Sygnatura niezgodna z regulaminem.
Go to the top of the page
+Quote Post
yavaho
post 8.05.2005, 15:03:31
Post #6





Grupa: Zarejestrowani
Postów: 449
Pomógł: 0
Dołączył: 26.05.2004
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


Mozna nieco przefiltrowac zmiena ktora pzechowuje nazwe dolaczanego pliku. I jezeli jest to plik z innej domeny to adres zostanie nieco zmodyfikowany na tyle ze nie zostanie znaleziony.
  1. <?php
  2. if(isset($_GET['page'])){
  3. $page = ereg_replace(&#092;"://\",\"#\",$_GET['page']);
  4. }else{
  5. $page='glowna';
  6. }
  7. ?>
Mozna jeszcze wszystkie includowane pliki przechowywac w jakims jednym katalogu i przed wywolaniem takiego pliku zawsze do zmiennej bedzie dolepiona sciezka co zmieni "niechciane linki" . Mozna tez sprawdzic czy includowany plik napewno pochodzi z naszej domeny basename()" title="Zobacz w manualu PHP" target="_manual
  1. <?php
  2. if(file_exists('skrypty/'.$page.'.php')){
  3. include ('skrypty/'.basename($page.'.php'));
  4. }else{
  5. include ('skrypty/glowna.php');
  6. }
  7. ?>
Po takiej filtracji ja bym sie czul zupelnie spokojnie.

@Speedy czasem musimy cos zostawic w ciasteczku aby rozpoznac danego uzytkownika. Np podczas stosowania autologinu do panelu admina - i tu niestety jest niebezpieczenstwo, na ktore ja nie znam jeszcze dobrego zabezpieczenia.


--------------------
Książki informatyczneKsiążki biznesowe
Warsztat: notepad hardcore
Go to the top of the page
+Quote Post
matid
post 8.05.2005, 17:06:28
Post #7





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

Ostrzeżenie: (0%)
-----


Cytat(yavaho @ 2005-05-08 16:03:31)
@Speedy czasem musimy cos zostawic w ciasteczku aby rozpoznac danego uzytkownika. Np podczas stosowania autologinu do panelu admina - i tu niestety jest niebezpieczenstwo, na ktore ja nie znam jeszcze dobrego zabezpieczenia.

A nie wystarczy czasem skorzystać z funkcji session_set_cookie_params" title="Zobacz w manualu PHP" target="_manual ?
Go to the top of the page
+Quote Post
sobstel
post 8.05.2005, 17:27:21
Post #8





Grupa: Zarejestrowani
Postów: 853
Pomógł: 25
Dołączył: 27.08.2003
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Cytat(matid @ 2005-05-08 17:06:28)
Cytat(yavaho @ 2005-05-08 16:03:31)
@Speedy czasem musimy cos zostawic w ciasteczku aby rozpoznac danego uzytkownika. Np podczas stosowania autologinu do panelu admina - i tu niestety jest niebezpieczenstwo, na ktore ja nie znam jeszcze dobrego zabezpieczenia.

A nie wystarczy czasem skorzystać z funkcji session_set_cookie_params" title="Zobacz w manualu PHP" target="_manual ?

Efekt działania tej funkcji widoczny jest tylko do końca działania skryptu.


--------------------
"If debugging is the process of removing bugs, then programming must be the process of putting them in..."
sobstel.org
Go to the top of the page
+Quote Post
Ociu
post 8.05.2005, 18:21:25
Post #9





Grupa: Moderatorzy
Postów: 1 566
Pomógł: 37
Dołączył: 14.05.2003
Skąd: Kraków




sprawdzanie $_GET'ów etc. :
  1. <?php
  2. if(is_int($_GET['id']))
  3. ?>


Wave: lepiej używać foreach.
Go to the top of the page
+Quote Post
vala
post 14.05.2005, 18:52:01
Post #10





Grupa: Zarejestrowani
Postów: 123
Pomógł: 0
Dołączył: 12.01.2005

Ostrzeżenie: (0%)
-----


a nie lepiej zrobic prosty switch ?
ustalimy sobie wtedy wszystkie dostepne przypadki i lux

o cos takiego :
  1. <?php
  2.  
  3.  
  4. if(isset($_GET['id']))
  5. {
  6. switch($_GET['id'])
  7. {
  8.  case &#092;"newsy\":
  9.  case &#092;"smieci\": $ref=$_GET['id'];break;
  10.  
  11.  default: $ref=&#092;"newsy\";
  12.  
  13.  }
  14.  
  15. include(&#092;"katalog/\".$ref.\".php\");
  16.  
  17. }
  18.  
  19.  
  20. ?>


Ten post edytował vala 14.05.2005, 18:55:07


--------------------
Warsztat: Easy PHP 1.7:Apache 1.3.27|PHP 4.3.3|PHPMYADMIn 2.5.3|MYSQL 4.0.15
Go to the top of the page
+Quote Post
AxZx
post 21.05.2005, 12:24:56
Post #11





Grupa: Zarejestrowani
Postów: 1 385
Pomógł: 55
Dołączył: 1.03.2005
Skąd: śląsk

Ostrzeżenie: (0%)
-----


Cytat(vala @ 2005-05-14 17:52:01)
a nie lepiej zrobic prosty switch ?
ustalimy sobie wtedy wszystkie dostepne przypadki i lux

o cos takiego :
  1. <?php
  2.  
  3.  
  4. if(isset($_GET['id']))
  5. {
  6. switch($_GET['id'])
  7. {
  8.  case &#092;"newsy\":
  9.  case &#092;"smieci\": $ref=$_GET['id'];break;
  10.  
  11.  default: $ref=&#092;"newsy\";
  12.  
  13.  }
  14.  
  15. include(&#092;"katalog/\".$ref.\".php\");
  16.  
  17. }
  18.  
  19.  
  20. ?>

@Vala - mozna to zrobic tak, wtedy nie trzeba dawac if(isset(....

  1. <?php
  2.  
  3.  
  4.  
  5. switch(@$_GET['id'])
  6. {
  7.  case &#092;"newsy\":
  8.  case &#092;"smieci\": $ref=$_GET['id'];break;
  9.  
  10.  default: $ref=&#092;"newsy\";
  11.  
  12.  }
  13.  
  14. include(&#092;"katalog/\".$ref.\".php\");
  15.  
  16.  
  17.  
  18.  
  19.  
  20. ?>


--------------------
aplikacje internetowe | Symfony
Go to the top of the page
+Quote Post
sobstel
post 21.05.2005, 13:19:52
Post #12





Grupa: Zarejestrowani
Postów: 853
Pomógł: 25
Dołączył: 27.08.2003
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Cytat(AxZx @ 2005-05-21 12:24:56)
@Vala - mozna to zrobic tak, wtedy nie trzeba dawac if(isset(.

trzeba jesli nie chcemy aby pojawial sie nam blad typu E_NOTICE kiedy id nie bedzie w adresie (najczesciej jest to strona glowna). ewentualnie mozna wczesniej umiescic sprawdzenie if (!isset($_GET['id']) $ref="newsy";


--------------------
"If debugging is the process of removing bugs, then programming must be the process of putting them in..."
sobstel.org
Go to the top of the page
+Quote Post
Lars
post 1.07.2005, 08:45:41
Post #13





Grupa: Zarejestrowani
Postów: 279
Pomógł: 15
Dołączył: 29.04.2005
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


ja mam prosty skrypt:
  1. <?php
  2. if(isset($_GET['mod'])) {
  3. $mod=$_GET['mod'];
  4. } else {
  5. $mod=&#092;"news\";
  6. }
  7.  
  8. if(isset($_GET['act'])) {
  9. $act=$_GET['act'];
  10. } else {
  11. $act=&#092;"list\";
  12. }
  13.  
  14. $file=$mod.'/'.$act.'.php';
  15.  
  16. if(!file_exists($file)) {
  17. die();
  18. } else {
  19. include &#092;"$file\";
  20. }
  21. ?>


czy file_exists zabezpiecza includowanie z innego serwera??


--------------------
(\.../) This is Bunny. Copy and paste bunny into
(O.o) your signature to help him gain world domination.
(> <) Zanim zapytasz | Też się przyda | Pomogłem ci? Kliknij "Pomógł"
Go to the top of the page
+Quote Post
sobstel
post 1.07.2005, 09:25:20
Post #14





Grupa: Zarejestrowani
Postów: 853
Pomógł: 25
Dołączył: 27.08.2003
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Cytat(Lars @ 2005-07-01 08:45:41)
czy file_exists zabezpiecza includowanie z innego serwera??

tak, ale "Od wersji 5.0.0 php ta funkcja może być użyta także z niektórymi wrapperami URL."


--------------------
"If debugging is the process of removing bugs, then programming must be the process of putting them in..."
sobstel.org
Go to the top of the page
+Quote Post
yavaho
post 1.07.2005, 09:42:14
Post #15





Grupa: Zarejestrowani
Postów: 449
Pomógł: 0
Dołączył: 26.05.2004
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


Cytat
czy file_exists zabezpiecza includowanie z innego serwera??
Tak, ale tylko w przypadku gdy prawdziwa nazwa includowanego pliku lub sciezka do niego bedzie nieco inna niz ta przekazywana w zmiennej.

W tym przypadku wszystkie includowane pliki musza znajdowac sie w odpowiednim katalogu.
  1. <?php
  2. if(!file_exists('katalog/'.$file.'.php')) {
  3. die();
  4. } else {
  5. include('katalog/'.$file.'.php');
  6. }
  7. ?>

W tym przypadku wszystkie includowane pliki musza miec specyficzny jednakowy poczatek nazwy pliku.
  1. <?php
  2. if(!file_exists('inc_'.$file.'.php')) {
  3. die();
  4. } else {
  5. include('inc_'.$file.'.php');
  6. }
  7. ?>

I jezeli w zmiennej przekaze ktos sciezke do innego serwera to taki plik nie zostanie znaleziony.


--------------------
Książki informatyczneKsiążki biznesowe
Warsztat: notepad hardcore
Go to the top of the page
+Quote Post
gu35t
post 1.07.2005, 11:18:56
Post #16





Grupa: Zarejestrowani
Postów: 57
Pomógł: 0
Dołączył: 15.05.2005

Ostrzeżenie: (0%)
-----


pamietejcie o zonku jaki moze zrobic haxior znakiem pustym:
czyli mam taki np kodzik:
  1. <?php
  2. if(....){
  3. include './skrypty/' . $_GET['plik'] . '.php';
  4. }
  5. ?>

haxior moze wpisac cos takiego
index.php?plik=../../../../../../../etc/passwd%00
czyli:
include ./skrypty/../../../../../../../etc/passwd%00.php no i sie nam pieknie otwarl plik
dobra wiadomosc: znak pusty(\0 == %00) juz na malo jakim serwerze dziala ale czasami znajde. winksmiley.jpg
to znalalem w przeciagu 2 min na google:
http://www.nfz-krakow.pl/index.php?plik=ko..../../etc/passwd
http://www-users.mat.uni.torun.pl/~ghost/i..../../etc/passwd


--------------------
env: Linux Slackware 10.1 [Kernel 2.6.5], PHP 4.3.9, Apache 1.3.33.
Go to the top of the page
+Quote Post
sobstel
post 1.07.2005, 11:22:21
Post #17





Grupa: Zarejestrowani
Postów: 853
Pomógł: 25
Dołączył: 27.08.2003
Skąd: Katowice

Ostrzeżenie: (0%)
-----


1. kolega pytal tylko czy mozna otworzyc w ten sposob zewnetrzne pliki tongue.gif
2. mysle ze uzycie file_exists() i basename() jest dobrym sposobem na dolaczanie plikow, ale jak jest ich stosunkowo niewiele zawsze najlepiej zrobic switcha
3. co do zanku pustego to dziala tam gdzie jest wylaczone automatyczne magic_quotes i ktos nie zabezpieczyl tego samemu


--------------------
"If debugging is the process of removing bugs, then programming must be the process of putting them in..."
sobstel.org
Go to the top of the page
+Quote Post
Lars
post 3.07.2005, 19:52:24
Post #18





Grupa: Zarejestrowani
Postów: 279
Pomógł: 15
Dołączył: 29.04.2005
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


co do: http://www-users.mat.uni.torun.pl/~ghost/i..../../etc/passwd

to można to zabezpieczyć:

  1. <?php
  2. ....przed includem
  3.  
  4. $_GET['plik']=str_replace(&#092;"/\", \"#\", $_GET['plik']);
  5.  
  6. include $_GET['plik'];
  7.  
  8. dalej....
  9. ?>


prosty przykład filtrowania danych happy.gif


--------------------
(\.../) This is Bunny. Copy and paste bunny into
(O.o) your signature to help him gain world domination.
(> <) Zanim zapytasz | Też się przyda | Pomogłem ci? Kliknij "Pomógł"
Go to the top of the page
+Quote Post
sobstel
post 3.07.2005, 20:00:01
Post #19





Grupa: Zarejestrowani
Postów: 853
Pomógł: 25
Dołączył: 27.08.2003
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Cytat(Lars @ 2005-07-03 19:52:24)
co do: http://www-users.mat.uni.torun.pl/~ghost/i..../../etc/passwd

to można to zabezpieczyć:

  1. <?php
  2. ....przed includem
  3.  
  4. $_GET['plik']=str_replace(&#092;"/\", \"#\", $_GET['plik']);
  5.  
  6. include $_GET['plik'];
  7.  
  8. dalej....
  9. ?>


prosty przykład filtrowania danych happy.gif

ja mimo wszystko upieralbym sie przy basename" title="Zobacz w manualu PHP" target="_manual()


--------------------
"If debugging is the process of removing bugs, then programming must be the process of putting them in..."
sobstel.org
Go to the top of the page
+Quote Post
Vengeance
post 7.07.2005, 19:55:39
Post #20





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

Ostrzeżenie: (0%)
-----


@bregovic:

Twój sposób
  1. <?php
  2.  
  3. $tablica[1] = 'jakisplik1';
  4. $tablica[2] = 'jakisplik2';
  5. $tablica[3] = 'jakisplik3';
  6. $tablica[4] = 'jakisplik4';
  7.  
  8. include $tablica[$_GET['costam']];
  9.  
  10. ?>


Też nie jest bezpieczny... dajmy na to wywołam URL:
/skrypt.php?tablica[foobar]=haxiorskiPlik&costam=foobar

Oczywiscie zagrozenie wynika glownie wtedy gdy mamy dostep do zrodel... choc czasem da sie takze zgadnac nazwy zmiennych


--------------------
Go to the top of the page
+Quote Post

16 Stron V   1 2 3 > » 
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 20.10.2019 - 20:36