Bezpieczeństwo stron WWW – SQL Injection (cześć #1 – walidacja danych)

Posted: Luty 19th, 2012 | Author: | Filed under: Bezpieczeństwo WWW, PHP | Tags: , | No Comments »

Co to jest SQL Injection?

Definicja z Wikipedi:

SQL Injection (z ang., dosłownie zastrzyk SQL) – luka w zabezpieczeniach aplikacji internetowych polegająca na nieodpowiednim filtrowaniu lub niedostatecznym typowaniu i późniejszym wykonaniu danych przesyłanych w postaci zapytań SQL do bazy danych. Podatne są na niego systemy złożone z warstwy programistycznej (przykładowo skrypt w PHP, ASP, JSP itp.) dynamicznie generującej zapytania do bazy danych (MySQL, PostgreSQL itp.). Wynika on zwykle z braku doświadczenia lub wyobraźni programisty.

Wynika z tego, że każda aplikacja korzystająca z bazy danych jest narażona na ten wektor ataku. Z jednej strony dość łatwo chronić się przed tym, z drugiej kilku mocnych graczy i tak poległo ( m.in. strona mysql.com → MySQL.com zhackowane… ). Co w takim razie można zrobić, żeby spać spokojnie?

Zabezpieczenie aplikacji

Najważniejsza zasada to:

 NIGDY NIE UFAJ DANYM PODAWANYM PRZEZ UŻYTKOWNIKA!

Pisanie bezpiecznej aplikacji to przede wszystkim mnóstwo mało ekscytującego kodu. Kodu, który będzie sprawdzał czy wszystkie dane pochodzące od użytkownika są tym czego się spodziewamy. Na początek zajmijmy się filtrowaniem danych.

Filtrowanie i  walidacja danych

Do tego zadania najlepiej nadają się wyrażenia regularne. Taki sposób filtrowania nazywa się białą listą. Dlaczego białą listą? Ponieważ filtrujemy dane na podstawie jakiegoś z góry ustalonego szablonu lub zakresu, np.:

<?php

$email_address = 'jan.kowalski@poczta.pl';

if (preg_match("/^[[:alnum:]][a-z0-9_.-]*@[a-z0-9.-]+\.[a-z]{2,4}$/i", $email_address)) {
   return true;
}

?>

lub:

<?php

switch( $_POST['color'] ) {
   case 'red':
   case 'blue':
   case 'yellow':
      return true;
   default: return false;
}

?>

Teraz przykład czarnej listy:

<?php

$colors = array(  'black', 'white', 'orange' );

if( !in_array( $_POST['color'], $colors ) ) {
   return true;
} else {
   return false;
}

?>

Jak widać różnica między białą a czarną listą jest dość istotna. Biała sprawdza czy wartość jest taka, jaka się spodziewamy. Natomiast czarna lista cechuje się sprawdzaniem czy dana nie jest wartością z jakiegoś zdefiniowanego zakresu. Zaleca się stosowanie białej listy ze względu na fakt, że w przypadku czarnej listy zawsze istnieje możliwość pominięcia jakiejś wartości. Można oczywiście mimo to stosować z takim samym efektem czarną listę, ale w pewnym momencie może się okazać, że ta lista będzie naprawdę długa ;-) A to już nie będzie wyglądało elegancko i stanie się mało czytelne.

Oprócz wyrażeń regularnych w PHP od wersji 5.2 mamy wbudowaną funkcję filter_var() z rozszerzenia Filter. Są tam zawarte najpopularniejsze filtry tj.:

  1. FILTER_VALIDATE_EMAIL - sprawdzanie adresu email
  2. FILTER_VALIDATE_PI - sprawdzanie adresu IP
  3. FILTER_VALIDATE_URL - sprawdzanie adresu URL

i wiele wiele innych ( do pełnej listy odsyłam tu, a do opisu tu. Oprócz tego przykład działania: tu).

I na koniec tej części krótka historyjka :)

 


Wyrównanie elementu blokowego (div) do środka w pionie i poziomie

Posted: Wrzesień 17th, 2011 | Author: | Filed under: CSS, XHTML & HTML | Tags: , , | No Comments »

Dzisiaj pokażę pewną sztuczkę CSS do wyrównania elementu blokowego (div’a) do środka w pionie o poziomie. Zacznijmy od HTML’a:

<html>
	<head>
	<body>
Jakiś przykładowy tekst
</body> </html>

I teraz najważniejsza cześć, czyli stylowanie.

#box {
width: 100px;
height: 100px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -50px;
margin-top: -50px;
}

 
Krótkie wyjaśnienie: Najpierw definiujemy wysokość i szerokość div’a. Następnie ustawiamy pozycję na absolute i ustawiamy po 50% na left i top. W ten sposób lewy górny róg jest dokładnie na środku ekranu. Teraz wyrównujemy całego diva względem tego punktu, czyli przesuwamy o połowę długości i szerokości w przeciwną stronę.
W ten sposób otrzymujemy wyrownany box w pionie i poziomie do środka. Nie ma na to wpływu rozmiar przeglądarki, a pozycja jest stale utrzymywane nawet po zmianie tego rozmiaru.
 


Long polling – czyli dynamiczna reakcja na zmianę

Posted: Wrzesień 10th, 2011 | Author: | Filed under: PHP | Tags: , , | No Comments »

Long polling jest to rozwiązanie służące do niemalże natychmiastowej reakcji na zmianę w dowolnym źródle (np. plik tekstowy, baza danych itd), które można zastosować w każdym języku programowania. Ja, jako że to jest mój „główny” język, pokażę jak to zrobić w PHP. Ale zanim do tego przejdę, może zacznę od przedstawienia przykładu, , który pokaże o co tak napradę tutaj chodzi:


index.php

<html>
	<head>
		<title>long_polling
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.3.min.js">
<script type="text/javascript">
  // 
			var time = null;

			jQuery(document).ready(function() {
				check();
			});
			function check() {
			    $.ajax({
			        type: 'GET',
			        url:  'check.php?time='+time,
			        async: true,
			        cache: false,

			        success: function( data ) {
			            var json = eval('(' + data + ')');
			            time = json['time'];

						$('#status').text( json['text_from_file'] );
			            setTimeout('check()', 100);
			        },

			        error: function( XMLHttpRequest, textStatus, errorThrown) {
			            setTimeout('check()', 100);
			        }
			    });
			}


</head>
	<body>
	</body>
</html>

 

check.php

$file = 'test.txt';
<?php
$lastTime = isset( $_GET['time'] ) ? $_GET['time'] : 0;
$currentTime = filemtime( $file );

while( $lastTime == $currentTime ) {
	usleep( 1000 );
	clearstatcache();
	$currentTime = filemtime( $file );
}

$response = array();
$response['text_from_file'] = file_get_contents( $file );
$response['time'] = $currentTime;

echo json_encode( $response );
?>

Parę słów wyjaśnienia o co tutaj biega. Mamy 3 pliki

  1. index.php – plik, w którym skrypt startuje i jest pokazywany wynik
  2. check.php – skrypt, który analizuje datę/czas zmiany pliku i na tej podstawie pobiera jego zawartość
  3. test.txt – plik, z którego pobieramy zawartość
Definiujemy w pliku index.php funkcję check() – jest to funkcja z ajaxowym wywołaniem skryptu php. Do skryptu przekazujemy parametr GET, który jest ostatnim czasem zapisu pliku (służy do porównania). W skrypcie (check.php) najpierw pobieramy czas zmiany pliku (funkcja filemtime()) i następnie w pętli while sprawdzamy czy nie zaszła żadna zmiana. Jeśli tak, to przesyłamy tablicę json (funckja odpowiedzialna: json_encode()) a w wartwie widoku wyświetlamy rezultalt.
Jak widać technika bardzo prosta, ale jednocześnie bardzo przydatna.

 

Cały przykład można pobrać tutaj.