[PHP] include($x) - czyli jak stracić stronę i reputację

Języki, których efekty są wykonywane po stronie serwera. PHP, ASP czy CGI w połączeniu z bazami danych SQL dają niezwykłe możliwości budowy i zarządzania stron WWW. Tu zadajemy pytania oraz demonstrujemy kod, z którym mamy problem.
porneL
Nowy
Nowy
Posty: 161
Rejestracja: sob lis 27, 2004 7:50 pm
Lokalizacja: Londyn
Kontakt:

[PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: porneL »

Po sieci krązy robak, który przejmuje serwery wszystkim niedouczonym phpowaczom, którzy beztrosko użyli:
[php]
include($strona);
[/php]
Więcej info: http://www.infoworld.com/article/04/12/ ... php_1.html

Przy okazji przypomne:
index.php?strona=bla
nie jest ani prostym, ani dobrym rozwiązaniem.

Wszystko z zewnątrz (każda zmienna, cookie) należy paranoicznie weryfikować (zweryfikowanymi procedurami weryfikującymi :)).

np. tak:
[php]
if (!in_array($strona,array('index','pieski','kotki'))) {die('404');}
[/php]
Grzegorz Winiarski
Nowy
Nowy
Posty: 147
Rejestracja: pt lut 27, 2004 10:36 pm
Lokalizacja: Kraków

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: Grzegorz Winiarski »

Mozna jeszcze tak zabezbieczac "includy"
[php]<?php
@include "./".$strona;
?>[/php]
porneL
Nowy
Nowy
Posty: 161
Rejestracja: sob lis 27, 2004 7:50 pm
Lokalizacja: Londyn
Kontakt:

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: porneL »

Na tym sztuczka właśnie polega: Nie można!!. To jest błąd o którym mowa!
wixor
Przelotem
Przelotem
Posty: 336
Rejestracja: śr gru 31, 2003 10:18 pm
Lokalizacja: Wrocław

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: wixor »

To daje takie jaja:
[php]<?php
$strona="../../../../etc/shadow";
@include "./".$strona ==> @include "./../../../../etc/shadow" ==> @include "/etc/shadow" ==> JESTEŚ ZWOLNIONY!
?>[/php]
the_foe
Przelotem
Przelotem
Posty: 295
Rejestracja: pt sty 31, 2003 12:53 pm
Lokalizacja: Wałbrzych
Kontakt:

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: the_foe »

wystarczy [manual]include[/manual] wpisywac w konstrukcje [manual]switch[/manual] [manual]case[/manual] i [manual]break[/manual] wzglednie zrezygnowac z poszczegolnych includow i wywolywac podstrony z funkcji.
rastman
Nowy
Nowy
Posty: 30
Rejestracja: wt sty 04, 2005 12:21 am

wyjasnienie

Post autor: rastman »

dopiero zaczynam przygodę z php i nie bardzo rozumiem jakiego rodzaju zagrożenie tu powstaje?
czego powinienem się obawiać, jesli robię stronkę, w ten sposób, że uzywam include(nazwa skryptu php, ale nie w postaci zmiennej tylko ciągu) w zależności od przekazanej zmiennej GET?
porneL
Nowy
Nowy
Posty: 161
Rejestracja: sob lis 27, 2004 7:50 pm
Lokalizacja: Londyn
Kontakt:

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: porneL »

Zagrożenie polega na tym, że include() czyta dowolny plik, jaki się mu każe. Nie ogranicza się do twoich plików php, a chętnie wczyta też plik z hasłami.

Wszelkie dane (zmienne) z zewnątrz nie muszą być takie, jakich oczekujesz. Mogą być wrednie spreparowane, aby wyrządzały szkody.

Nawet jak dokleisz coś z przodu ścieżki, to można to obejść dodająć odpowiednią ilość "../".
Doklejanie na końcu .php nic nie pomaga. Znakiem NUL (%00) atakujący może sobie uciąć ścieżkę wcześniej.

To samo się tyczy require, readfile, fopen, file i całej masy innych funkcji czytających pliki.

Jeśli już sprawdzasz poprawność danych, to dokładnie sprawdzaj, czy dana jest taka i tylko taka jak ma być. Porównaj z listą możliwych, rzutuj na liczbę, wytnij niealfanumeryczne znaki, etc.
Częstym błędem jest tylko blokowanie znanych autorowi groźnych przypadków (zalozenie: znasz bezpieczne, ale nie znasz wszystkich niebezpiecznych).

Za każdym razem jak używasz $_GET, $_POST pomyśl jaki może być najgorszy przypadek, który by zmienił działanie twojego skryptu.
rastman
Nowy
Nowy
Posty: 30
Rejestracja: wt sty 04, 2005 12:21 am

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: rastman »

ale skoro u mnie wygląda to tak, że

Kod: Zaznacz cały

if(isset($_GET['x'])) include "include1.php";
else include"include2.php";
to czy warto jeszcze sprawdzać czy $_GET['x'] zawiera się w zakresie dostępnych wartości?z tym nie byłoby kłopotu. zastanawiam się tylko czy sprawdzenie wartości np. 5 zmiennych zbytnio nie obciąży serwera?
porneL
Nowy
Nowy
Posty: 161
Rejestracja: sob lis 27, 2004 7:50 pm
Lokalizacja: Londyn
Kontakt:

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: porneL »

Powyższy kod nie ma zmiennej w include, czyli ww. niebezpieczeństwa nie ma.

Sprawdzasz tylko obecność 'x'. Jeśli to tak ma być, to ok.

Sprawdzenie nawet 1000 zmiennych nie powinno wzruszyć serwera.
rastman
Nowy
Nowy
Posty: 30
Rejestracja: wt sty 04, 2005 12:21 am

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: rastman »

Powyższy kod nie ma zmiennej w include, czyli ww. niebezpieczeństwa nie ma.

Sprawdzasz tylko obecność 'x'. Jeśli to tak ma być, to ok.

Sprawdzenie nawet 1000 zmiennych nie powinno wzruszyć serwera.
pierwsza część odpowiedzi mnie ucieszyła, ale co do tych zmiennych to sprawdzenie nawet 5 moze trochę zająć, ponieważ zakres właściwych wartości zawiera się w bazie danych, a połączenie z serwerkiem bazodanowym i uzyskanie odpowiedzi jest chyba bardziej czasochłonne niz samo sprawdzanie w php.
porneL
Nowy
Nowy
Posty: 161
Rejestracja: sob lis 27, 2004 7:50 pm
Lokalizacja: Londyn
Kontakt:

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: porneL »

Więc to już jest część konkretnego problemu. 5 zapytań bym się nie bał. 50 to gorzej.

Jeśli już przy SQL jesteśmy, to tak samo jest niebezpieczny jak include() :)

Kod: Zaznacz cały

mysql_query("SELECT * FROM users WHERE login='$login' and haslo='$haslo'");
Zaloguje każdego na hasło:
' OR 1 --
lub login:
wybranylogin' --

Coprawda PHP ma standardowo właczone magic quotes, które przed tym atakiem chroni początkujących webmasterów, ale czasem może być wyłączone, twórca mający dość \" w tekście zacznie nadużywać stripslashes() albo spreparowany login można podrzucić inną drogą.

Natomiast już nic nie uchroni w takim przypadku:

Kod: Zaznacz cały

mysql_query("SELECT * FROM foo WHERE id=$id");
(zauważ brak cudzysłowiu wokół $id).

Twórcy stron zakładają, że $id to liczba. Hackerzy wolą gdy $id to:
1 OR 1
i wszystkie dane są na tależu.
Nowsze wersje MySQL obsługują też subqueries, więc dzięki takiemu byle $id atakujący dostaje możliwość przeglądania sobie całej bazy.
rastman
Nowy
Nowy
Posty: 30
Rejestracja: wt sty 04, 2005 12:21 am

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: rastman »

więc jak się bezpiecznie zalogować w php+mysql?
porneL
Nowy
Nowy
Posty: 161
Rejestracja: sob lis 27, 2004 7:50 pm
Lokalizacja: Londyn
Kontakt:

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: porneL »

Jeśli PHP5, to można użyć mysqli.

Można też coś w tym stylu:
[php]
/* pozbyć się slashy na samym początku i operować na czystych danych */
$login = get_magic_quotes_gpc()?stripslashes($_POST['login']):$_POST['login'];
$haslo = get_magic_quotes_gpc()?stripslashes($_POST['haslo']):$_POST['haslo'];

/* przy samym query *zawsze* dodawać slashe. */
mysql_query('select * from users where login="'.addslashes($login).'" and passmd5="'.md5($haslo).'"');
[/php]

No i nie trzyma się gołych haseł w bazie. Jak się je zakoduje przez md5, to nawet gdy ktoś wykradnie całą bazę, to nie pozna haseł.


Natomiast jak jakaś zmienna ma być liczbą, to tak można to zagwarantować:
[php]$id = (int)$id;[/php]
rastman
Nowy
Nowy
Posty: 30
Rejestracja: wt sty 04, 2005 12:21 am

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: rastman »

w takim razie mam jeszcze 2 pytanka związane z bezpieczeństwem.
1) Jak zabezpieczyć sie przed oglądaniem podkatalogów na serwerze. ja wstawiłem do każdego katalogu index.php z przekiwerowaniem do strony głównej w javascript
2) czy jesli mam stronę w takiej postaci: nagłówek i stopka statyczne, a menu i treść generują się na podstawie przekazywanych zmiennych i zapytań sql, to czy rozsądnie jest korzystać z jednego połączenia z mysql otwieranego w nagłóówku, a zamykanego w stopce?
porneL
Nowy
Nowy
Posty: 161
Rejestracja: sob lis 27, 2004 7:50 pm
Lokalizacja: Londyn
Kontakt:

Re: [PHP] include($x) - czyli jak stracić stronę i reputację

Post autor: porneL »

1. jak index.php, to po co Javascript? pogooglaj o "header("Location..."

Zamiast index.php możesz użyć pliku .htaccess o treści
Order deny,allow
Deny from all
Wyższym poziomem wtajemniczenia jest używanie mod_rewrite dla wszystkich ścieżek. Wtedy układ plików na serwerze nie ma nic wspólnego ze ścieżkami widocznymi w sieci.

2. Przy lokalnym serwerze praktycznie nie ma znaczeina czy używasz mysql_connect, czy mysql_pconnect. PHP sam zajmuje się zamykaniem połączenia, więc nic robić nie musisz.
ODPOWIEDZ