C, PHP, VB, .NET

Дневникът на Филип Петров


* Подслушването на трафик и сесиите

Публикувано на 15 ноември 2008 в раздел ОСУП.

Проблемът "човек в средата" се появява, когато някой подслушва трафика между вас и сървъра. На практика досега не съществува техника, чрез която да откривате по безупречен начин, че някой подслушва вашата връзка. Затова когато разработваме сигурен софтуер трябва по условие да приемем, че нашия трафик е подслушван. Тук не става дума за фиксиране, а по-скоро за открадване на сесии (session hijacking).

Засега най-ефективният начин за защита е използването на криптография. В света на Интернет приложенията вече най-широко се употребява протокола за комуникация HTTPS, чрез който се пренася HTTP трафик през SSL (Secure Socket Layer).

Всички разгледани дотук техники за защита на потребителска сесия са напълно безполезни, ако използваме некриптиран канал за комуникация. В най-лошият случай, когато не криптираме нищо, то атакуващият дори няма да има нужда да прониква в сесията - той ще може да подслуша канала и да добие нужната информация от самите вас. Може да се приеме, че във всички случаи, когато session id се предава некриптирано, е възможен session hijacking (открадване на сесия).

Особено често срещана практика при повечето сайтове в Интернет е основната страница да се вижда през некриптиран канал, а SSL да се използва само и единствено на местата, където се предават конфиденциални данни. За съжаление в почти всички от тях потребителската сесия се стартира или използва извън криптирания канал. При атаката "човек по средата" това може да бъде пагубно!

Ето още един доста често срещан пример - много уеб сайтове (например безплатните пощи) използват SSL за криптиране на целият си уебсайт, но в много случаи те предоставят възможност и за достъп през некриптиран канал, за клиенти, които не поддържат или по някаква странна причина не желаят да използват SSL. Такива сървъри са напълно уязвими, защото атакуващият, придобил или фиксирал session id, може да се автентикира през некриптирания канал, а сървъра няма да има адекватна възможност да го различи (както това би могло да стане чрез публичния ключ на SSL сертификата на клиента).

Тъй като SSL е стандарт, който е навлязъл отдавна и е използван доста широко, то бихме дали следните съвети:
1. Никога не стартирайте сесия без криптирането ѝ чрез SSL или друг тип криптография. Никога не изпращайте session id некриптирано.
2. Ако имате възможност - криптирайте абсолютно целия трафик. Потребители, чийто браузъри не поддържат SSL се срещат изключително рядко в днешни дни.
3. Накарайте приложението си да следи стриктно дали канала е криптиран.

Ако използвате уеб сървър Apache, то можете да накарате насилствено всичкия HTTP трафик да бъде пренасочен към криптиран канал, независимо дали приложението следи за това или не. За целта просто създайте .htaccess файл със следното съдържание:

	RewriteEngine On
	RewriteCond %{HTTPS} off
	RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

Така клиентите ще бъдат автоматично пренасочвани към SSL криптиран канал за целият уеб сайт. Въпреки, че подобни техники са възможни за почти всички сървъри, като програмисти бихме препоръчали да следите дали канала е криптиран и през самото приложение. Ето какво бихме добавили в скрипта, разгледан в предишните няколко статии:

<?php
	if ($_SERVER['HTTPS'] != "on") {
		$url = "https://";
		$url .= $_SERVER['SERVER_NAME'];
		$url .= $_SERVER['REQUEST_URI'];
		header("Location: $url");
		return;
	}
	else{
		session_start();
		session_regenerate_id(true);
	}
?>
<html>
<head>
	<title>WorldBank.dom session page</title>
</head>
<body>
<?php
	if(isset($_SESSION['ip'])){
		if($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']){
		echo 'You entered a session fixed by another IP!';
		session_destroy();
		return;
		}
	}
	else{
		$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
	}

	$maxSessionTime = 10 * 60;
	$timeout = 5 * 60;
	$curtime = (int)time();
	if(! isset($_SESSION['initial_time'])){
		$_SESSION['initial_time'] = (int)time();
	}
	if($curtime-$_SESSION['initial_time'] > $maxSessionTime){
		echo 'Maximum session time exceeded';
		session_destroy();
		return;
	}

	if (isset($_SESSION['last_active'])){
		if ($curtime-$_SESSION['last_active'] > $timeout){
			echo 'Session timeout';
			session_destroy();
			return;
		}
	}
	$_SESSION['last_active'] = $curtime;

	echo 'session id is: ';
	echo session_id();
	echo '<br>';
	if (!isset($_SESSION['counter'])){
		$_SESSION['counter'] = 0;
	}
	else{
		$_SESSION['counter']++;
	}
	echo 'counter: ';
	echo $_SESSION['counter'];
?>
</body></html>

Забележете, че е абсолютно задължително тази проверка да се прави преди стартирането на сесията. Ако стартираме сесията преди да сме пренасочили трафика, то цялото начинание може да се окаже безполезно.

Задача: Използвате ли услугите на сайтове, в които се изисква конфиденциална информация? Проверете дали автентикирайки се на тези сайтове сте адекватно защитени чрез криптография.

Задача: Защитена ли е най-използваната услуга за безплатна поща в България (abv.bg) срещу session hijacking?

 



Добави коментар

Адресът на електронната поща няма да се публикува


*