PHP – Niebezpieczne Sesje.

PHP – Niebezpieczne sesje

SEssion - PHP Protokół HTTP jest protokołem bezstanowym. Oznacza to, że serwer WWW rozpatruje każde żądanie niezależnie od innych, nie szukając żadnych powiązań w stylu wysyłania ich przez tego samego internautę. Utrudnia to teoretycznie tworzenie wszelkich systemów autoryzacji, które wymagają śledzenia poczynań użytkownika na naszej stronie i przenoszenia jego danych autoryzacyjnych między kolejnymi żądaniami.

Sesje są rozwiązaniem problemu bezstanowości protokołu HTTP, w którym żądania nie są ze sobą powiązane. Umożliwiają one identyfikacje żądań poszczególnych użytkowników za pomocą przekazania identyfikatora sesji. Jest on dołączany do każdej odpowiedzi serwera jako „ciastko”, ukryte pole w kodzie strony lub jako dodatkowy parametr adresu URL.

Fizycznie są to pliki tekstowe zawierające dane przypisane do konkretnych użytkowników.

Niebezpieczeństwo sesji.

  • Atak session fixation
Najprościej mówiąc w sesji przechowywane są dane dotyczące konkretnego użytkownika. Mogą to być informacje o wybranej wersji językowej czy szablonie strony, mogą to być również wrażliwe dane takie jak loginy, hasła, dane osobowe.
Kluczowym elementem w działaniu mechanizmu sesji jest jej identyfikator. To dzięki niemu użytkownik ma dostęp do swojego pliku sesji. Z nim też wiąże się spory problem. Uzyskanie czyjegoś identyfikatora umożliwia dostęp do danych zapisanych w sesji. Z racji trzymania identyfikatora po stronie użytkownika istnieje możliwość jego kradzieży, a przez to podszycie się pod jego właściciela. Dwie najbardziej popularne metody, a zarazem najprostsze do wykorzystania oraz zabezpieczenia to XSS oraz przekazanie adresu URL wraz ze zmienną sesyjną.
Aby zabezpieczyć się przez atakiem session fixation należy dokonać dwie czynności. Pierwszą z nich jest dopilnowanie, aby identyfikator sesji zawsze przekazywany był w ciasteczku, a nie jako element adresu.
Jeśli nie mamy możliwości edycji pliku php.ini powyższą zmianę możemy dokonać za pośrednictwem pliku .htaccess umieszczając w nim dwie linijki:

php_value session.use_only_cookies 1
php_value session.use_trans_sid 0

Drugim zabezpieczeniem jest wygenerowanie nowego identyfikatora sesji z każdym wykonaniem skryptu – zmniejsza to możliwość podszycia się pod użytkownika gdy nastąpi kradzież identyfikatora. Służy do tego funkcja

session_regenerate_id( );

Przykład skryptu w PHP

<?php

session_start();
$old_id = session_id(); // 1234
if (empty($_SESSION&#91;‘is_valid’&#93;))

{
session_regenerate_id();
$new_id = session_id(); //losowo np., 93a7289e775b9acdf8092380cc5b6e26
$_SESSION&#91;‘is_valid’&#93; = TRUE;

}&#91;/sourcecode&#93;
<ul>
	<li>
<h5><span style="color:#3366ff;">Atak session poisoning</span></h5>
</li>
</ul>
<p align="justify">Skutecznie przeprowadzony atak session poisoning skutkuje możliwością modyfikacji danych znajdujących się w sesji agresora. Może on tego dokonać dwojako.</p>

<ul>
	<li>Pierwszym sposobem jest wykorzystanie błędu braku filtrowania danych płynących od użytkownika, które są umieszczane w sesji.</li>
</ul>
<div>
<ul>
	<li>Do wykonania drugiego sposobu wymagana jest możliwość wgrania plików w ramach tego samego konta co atakowany system. Posiadając taką możliwość możemy na serwerze umieścić plik, którego zadaniem będzie wyświetlenie aktualnych wartości sesji oraz umożliwienie ich modyfikacji.</li>
</ul>
</div>
Poniżej fragment napisany w PHP umożliwiający manipulację zmiennymi sesyjnymi.



<?php
session_start( );

echo '<pre>';

print_r( $_SESSION);

echo '</pre>';

if( $_GET['user'] )

$_SESSION[$_GET['user']] = $_GET['login'];

?>
  • Atak session injection

Posiadając konto u jednego z providerów internetowych dzielimy zasoby serwera z innymi użytkownikami. W skład tych zasobów wchodzą między innymi pliki. O ile dostępu do plików na naszym koncie chronią poprawnie ustawione uprawnienia dostępu, o tyle sytuacja taka nie zawsze ma miejsce jeśli chodzi o katalog z plikami sesji. Niepoprawnie skonfigurowany serwer może dać nam możliwość nie tylko podglądu ale i modyfikacji plików sesji.Pliki te nie są szyfrowane.

Poniżej fragment skryptu PHP umożliwiający listowanie oraz podgląd plików sesji.


<?php
if( $_GET&#91;'ses_plik'&#93; )

{
$plik = ini_get( 'session.save_path' ) . '/' . $_GET&#91;'ses_plik'&#93; );
die( file_get_contents( $ses_plik );
}

foreach ( glob( ini_get( 'session.save_path' ) . '/*' ) as $ses_plik )
{
echo $ses_plik . 'size ' . filesize( $ses_plik ) . '<br />';
}

?>

Sposobem na zabezpieczenie się przed podglądem pliku sesji jest zmiana katalogu, w którym będą one przechowywane. Możemy tego dokonać korzystając z funkcji

session_save_path( );

Należy pamiętań, aby katalog z plikami sesji nie był publicznie dostępny dlatego powinien znajdować się powyżej katalogu public_html

  • Atak session riding

Celem ataku session riding jest wykonanie złośliwego kodu z uprawnieniami zalogowanego użytkownika. Może to doprowadzić do kradzieży danych użytkownika, zamówienie przez niego jakiegoś produktu, lub w przypadku wykonania kodu przez administratora „dostęp” do panelu administratora.

Zabezpieczenie przed CSRF( skrót – bo taki ten atak posiada) może wydawać się trudne lecz istnieje kilka sposobów by tego dokonać. Dwa najciekawsze opierają się na tokenach, czyli losowo wygenerowanych ciągach znaków.

  • Zasada działania pierwszego sposobu opiera się na umieszczeniu dodatkowe pola w każdym znaczącym formularzu. W polu tym będzie znajdował się wygenerowany token, który po wysłaniu formularza będzie sprawdzany z tokenem zapisanym np. w sesji.
  • Drugi sposób jest „bardziej skomplikowany”, a wraz z tym lepszy. Polega on na stworzeniu „tablicy routingu”. Mianowicie chodzi o tabelkę w bazie danych która będzie zawierała w sobie zestawienie tokenów oraz prawdziwych adresów. Token powinien być generowany inny dla każdego użytkownika. Dzięki temu napastnik nie będzie w stanie wywołać akcji z uprawnieniami zalogowanego użytkownika.

http://www.przyklad.com/?element=jakis&element=inny&akcja=zrob

Po zmianie wyglądów adresów po użyciu „tablicy routingu”

http://www.przyklad.com/?token=djPana76ashHSB

Implementacja własny mechanizm obsługi sesji.

Sposobem na zabezpieczenie się przed problemami związanymi z natywną obsługą sesji jest stworzenie własnego systemu obsługi sesji. Największy nacisk powinien w niej zostać położony na sposób przechowywania danych oraz zarządzania identyfikatorem sesji.

Najbezpieczniejszym miejscem na przechowywania danych jest baza danych. Aby uzyskać do niej dostęp należy znać dane umożliwiające logowania lub wykonać atak typu SQL Injection. Ze względu na swoją naturę możemy pominąć pierwszy sposób. Drugi atak może zostać przeprowadzony tylko w przypadku błędnie napisanego kodu. Można więc zauważyć, że poprawnie napisany system oraz własny mechanizm sesji daje nam całkowite bezpieczeństwo.

Sposób generowania identyfikatora zależy już tylko od inwencji twórców systemu zabezpieczeń tworzonej aplikacji. Można się do tego posłużyć funkcjami generującymi losowe znaki oraz funkcjami hashującymi. Co ważne po każdym wygenerowaniu ID trzeba się upewnić, że jest ono unikalne i nie zostało już wcześniej przydzielone innemu użytkownikowi.

Wygenerowany identyfikator powinniśmy umieścić w cookies oraz dodać dodatkowe zabezpieczenie uniemożliwiające przeprowadzenie ataku session fixation.

W PHP istnieje możliwość napisania własnych funkcji zarządzania sesją pod natywną obsługę sesji. Służy do tego funkcja session_set_save_handler Oznacza to tyle, że odwołując się do superglobalnej tablicy sesji ($_SESSION) odwołujemy się niejawnie do naszych funkcji. Oprócz tego, że sposób ten jest wygodny jest również bezpieczny na zmiany w kodzie oraz w sposobie przechowywania danych.


<?php

session_set_save_handler(“m_open”,”m_close”,”m_read”,”m_write”,”m_destroy”,“m_gc”);

?>

Wymienione w nawiasie –“m_open”,”m_close”,”m_read”,”m_write”,”m_destroy”,“m_gc”) to nic innego jak nazwy własnych ( funkcji napisanych w php )

Poniżej przykład funkcji użytkownika.

function m_open($save_path, $session_name){
$r = mysql_connect() or die(“komunikat błędu”);
mysql_select_db($save_path, $r) or die(”"komunikat błędu);
return define(‘__ses_db’, $r);
}
function m_close() {
return mysql_close(__ses_db);
}
Źródło:
  1. Ilia Alshanetsky – „Php|architect’s Guide to Security” -Marco Tabini & Associates, Inc. 2006
  2. php.net – http://pl2.php.net/manual/pl/ref.session.php
  3. Blog – iBlog – Ilia Alshanetsky
  4. Securing PHP Applications
  5. Blog – http://www.askapache.com/
  6. Neil Daswani, Christoph Kern – „Foundations of Security: What Every Programmer Needs to Know” – Apress 2007 – http://www.apress.com

Skomentuj

Please log in using one of these methods to post your comment:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

%d bloggers like this: