Kursy i Poradniki IT - Adrian Kowalski
Kurs Programowania PHP dla Początkujących
O lekcji

Ochrona przed SQL Injection SQL Injection to atak, w którym złośliwy kod SQL jest wstrzykiwany do zapytania w celu przejęcia kontroli nad bazą danych. Aby się przed tym chronić, należy stosować zapytania przygotowane. Przykład: Ochrona za pomocą zapytań przygotowanych (PDO)

<?php
$dsn = 'mysql:host=localhost;dbname=mojabaza;charset=utf8mb4';
$username = 'root';
$password = '';

try {
    $pdo = new PDO($dsn, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "SELECT * FROM uzytkownicy WHERE email = :email";
    $stmt = $pdo->prepare($sql);
    $stmt->execute(['email' => '[email protected]"; DROP DATABASE test; --']);
    //DROP DATABSE test; nie zostanie wywołane
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    print_r($results);
} catch (PDOException $e) {
    echo "Błąd: " . $e->getMessage();
}
?>

Dlaczego działa:

  • Parametry są automatycznie escapowane, co uniemożliwia wstrzyknięcie kodu SQL.

Haszowanie haseł – stare metody i nowoczesne podejście

Stare podejście do haszowania (np. md5 i sha1)

W przeszłości często korzystano z funkcji takich jak md5 i sha1 do haszowania haseł. Chociaż były one łatwe w użyciu, ich stosowanie obecnie jest niewystarczająco bezpieczne, ponieważ:

  • Są szybkie, co czyni je podatnymi na ataki brute-force.
  • Nie dodają soli, co umożliwia wykorzystanie gotowych słowników (rainbow tables) do łamania haseł.

Przykład: Haszowanie za pomocą md5

<?php
$haslo = "moje_tajne_haslo";

// Tworzenie hasha
$hash_md5 = md5($haslo);
echo "Hash MD5: $hash_md5<br>";

// Weryfikacja hasła
if ($hash_md5 === md5($haslo)) {
    echo "Hasło poprawne!";
} else {
    echo "Hasło niepoprawne!";
}
?>

Przykład: Haszowanie za pomocą sha1

<?php
$haslo = "moje_tajne_haslo";

// Tworzenie hasha
$hash_sha1 = sha1($haslo);
echo "Hash SHA1: $hash_sha1<br>";

// Weryfikacja hasła
if ($hash_sha1 === sha1($haslo)) {
    echo "Hasło poprawne!";
} else {
    echo "Hasło niepoprawne!";
}
?>

Dlaczego md5 i sha1 są niewystarczające?

  1. Brak soli: Generowane hashe są takie same dla identycznych haseł, co umożliwia ataki oparte na gotowych słownikach (rainbow tables).
  2. Szybkość: Algorytmy te są bardzo szybkie, co ułatwia ataki brute-force.
  3. Przestarzałość: Są uznawane za nieodpowiednie do przechowywania haseł od wielu lat.

Nowoczesne podejście do haszowania (password_hash)

Nowoczesne metody haszowania w PHP (np. password_hash) są zaprojektowane z myślą o bezpieczeństwie. Funkcja ta automatycznie:

  • Dodaje sól (salt).
  • Używa bezpiecznych algorytmów (domyślnie bcrypt).
  • Obsługuje konfigurację złożoności (np. koszt obliczeń).

Przykład: Haszowanie i weryfikacja nowoczesnym podejściem

<?php
$haslo = "moje_tajne_haslo";

// Tworzenie hasza
$hashedPassword = password_hash($haslo, PASSWORD_DEFAULT);
echo "Zahasłowane hasło (password_hash): $hashedPassword<br>";

// Weryfikacja hasła
if (password_verify($haslo, $hashedPassword)) {
    echo "Hasło poprawne!";
} else {
    echo "Hasło niepoprawne!";
}
?>

Porównanie MD5/SHA1 i password_hash

Cechy MD5 / SHA1 password_hash
Bezpieczeństwo Niskie – brak soli, podatność na ataki brute-force i rainbow tables Wysokie – automatyczna sól, obsługa bezpiecznych algorytmów
Złożoność implementacji Prosta, ale wymaga ręcznego zarządzania solą Bardzo prosta – automatyzacja
Szybkość Bardzo szybkie, co jest wadą Wolniejsze, co zwiększa bezpieczeństwo

Rekomendacja

  • Nigdy nie używaj md5 lub sha1 do przechowywania haseł.
  • Używaj password_hash do haszowania i password_verify do weryfikacji. Algorytm bcrypt (domyślny w PASSWORD_DEFAULT) lub Argon2 są obecnie standardem bezpieczeństwa.