Bezpieczeństwo Danych w PHP

INF.03.7 (3) — Zabezpieczanie aplikacji serwerowej

Zasada Nie ufaj danym użytkownika!

Każda dana przesłana przez użytkownika (przez formularz, URL czy plik) musi być traktowana jako potencjalny kod atakującego. Bezpieczeństwo danych w PHP polega na dwóch kluczowych etapach:

  • 1. Filtrowanie/Czyszczenie (Input Filtering): Upewnienie się, że dane spełniają oczekiwany format (np. liczba jest liczbą).
  • 2. Ekranowanie/Escapowanie (Output Escaping): Neutralizowanie danych przed ich wstawieniem do bazy danych (ochrona SQL Injection) lub przed wyświetleniem w HTML (ochrona XSS).

SQL Ochrona przed SQL Injection

SQL Injection (Wstrzyknięcie SQL) to atak polegający na wstawieniu złośliwego kodu SQL do pola formularza, co może doprowadzić do pominięcia logowania lub usunięcia całej bazy danych.

BŁĘDNY KOD (NIGDY TEGO NIE RÓB!)

<?php
    $login = $_POST['login'];
    // Atakujący może wpisać ' OR 1=1 --
    $sql = "SELECT * FROM users WHERE login = '$login'"; // ZŁE!
    $pdo->query($sql); // Wszystkie wiersze zwrócone!
?>

WŁAŚCIWY KOD: Przygotowane Zapytania (PDO Prepared Statements)

Przygotowane Zapytania oddzielają zapytanie SQL od danych. Serwer bazy danych traktuje dane jako czysty tekst, a nie jako część polecenia SQL.

<?php
    $login = $_POST['login'];
    // 1. Używamy placeholderów (?)
    $sql = "SELECT * FROM users WHERE login = ?";
    $stmt = $pdo->prepare($sql);
    // 2. Dane przekazujemy oddzielnie w tablicy
    // Jeśli atakujący wpisze złośliwy kod, zostanie on potraktowany jak zwykły login
    $stmt->execute([$login]);
?>

XSS Ochrona przed Cross-Site Scripting

Atak XSS polega na wstrzyknięciu złośliwego kodu JavaScript (np. <script>alert('Hacked')</script>) do treści, która jest później wyświetlana innym użytkownikom. Chronimy się, czyszcząc dane przed wyświetleniem w HTML.

Funkcja `htmlspecialchars()` (Ekranowanie Wyjścia)

Ta funkcja zamienia specjalne znaki HTML (jak <, >, ") na ich bezpieczne encje (&lt;, &gt;, &quot;). Przeglądarka wyświetli wtedy tekst, a nie wykona kodu JS.

BŁĘDNY KOD (Ryzyko XSS!)

<p>Wpis użytkownika: <?php echo $_POST['komentarz']; ?></p>

WŁAŚCIWY KOD (Bezpieczne wyświetlanie)

<p>Wpis użytkownika: <?php echo htmlspecialchars($_POST['komentarz']); ?></p>

// Jeśli atakujący wpisał: <script>alert('XSS')</script>
// PHP wyświetli: <p>Wpis użytkownika: &lt;script&gt;alert('XSS')&lt;/script&gt;</p>
// Co jest bezpieczne.

Czyszczenie Filtrowanie Danych Wejściowych (Filter & Validate)

Zanim dane trafią do bazy lub logiki, należy je zweryfikować, czy są w oczekiwanym formacie. Używamy do tego rodziny funkcji `filter_var()`.

1. Walidacja (Sprawdzanie Poprawności)

Sprawdza, czy dane są zgodne z oczekiwanym wzorcem (np. czy to poprawny adres e-mail).

<?php
    $email = $_POST['email'];
    
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        die("Błąd: Niepoprawny format adresu e-mail.");
    }
    echo "Adres e-mail jest poprawny.";
?>

2. Czyszczenie (Sanityzacja)

Usuwa niepożądane znaki z danych (np. usuwa wszystkie tagi HTML).

<?php
    $niebezpieczny_string = "<h1>Tytuł</h1> Zwykły tekst.";
    
    // Usuwa wszystkie tagi HTML
    $czysty_string = filter_var($niebezpieczny_string, FILTER_SANITIZE_STRING);
    echo $czysty_string; // Wyświetli: Tytuł Zwykły tekst.
?>

Ćwiczenie Zadania Praktyczne

Zadanie 1: Zabezpieczenie danych (XSS i SQL)

Napisz skrypt odbierający dane z formularza z polem `tytul`.

Zadanie 2: Walidacja Liczb i URL (Ponadpodstawowe)

Załóż, że oczekujesz pola wiek (`wiek`) i link (`strona`).

Materiały Narzędzia i Linki

Materiały: Bezpieczeństwo Danych w PHP · Opracowanie na podstawie wymagań INF.03 | Autor: Tomasz Puchała (toloki.pl)