Walidacja formularzy PHP
Ten i następne rozdziały pokazują, jak używać PHP do sprawdzania poprawności danych formularzy.
Walidacja formularzy PHP
Pomyśl o BEZPIECZEŃSTWIE podczas przetwarzania formularzy PHP!
Te strony pokażą, jak przetwarzać formularze PHP z myślą o bezpieczeństwie. Właściwa weryfikacja danych formularza jest ważna, aby chronić formularz przed hakerami i spamerami!
Formularz HTML, nad którym będziemy pracować w tych rozdziałach, zawiera różne pola wejściowe: wymagane i opcjonalne pola tekstowe, przyciski opcji i przycisk przesyłania:
Zasady walidacji dla powyższego formularza są następujące:
Field | Validation Rules |
---|---|
Name | Required. + Must only contain letters and whitespace |
Required. + Must contain a valid email address (with @ and .) | |
Website | Optional. If present, it must contain a valid URL |
Comment | Optional. Multi-line input field (textarea) |
Gender | Required. Must select one |
Najpierw przyjrzymy się prostemu kodowi HTML formularza:
Pola tekstowe
Pola nazwy, adresu e-mail i witryny internetowej to elementy wprowadzania tekstu, a pole komentarza to obszar tekstowy. Kod HTML wygląda tak:
Name: <input type="text" name="name">
E-mail: <input type="text" name="email">
Website: <input type="text" name="website">
Comment: <textarea name="comment" rows="5" cols="40"></textarea>
Przyciski radiowe
Pola płci to przyciski radiowe, a kod HTML wygląda tak:
Gender:
<input type="radio" name="gender"
value="female">Female
<input type="radio" name="gender" value="male">Male
<input type="radio" name="gender" value="other">Other
Element formy
Kod HTML formularza wygląda tak:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Po przesłaniu formularza dane formularza są przesyłane z method="post".
Co to jest zmienna $_SERVER["PHP_SELF"]?
$_SERVER["PHP_SELF"] jest super globalną zmienną, która zwraca nazwę pliku aktualnie wykonywanego skryptu.
Tak więc $_SERVER["PHP_SELF"] wysyła przesłane dane formularza do samej strony, zamiast przeskakiwać na inną stronę. W ten sposób użytkownik otrzyma komunikaty o błędach na tej samej stronie, co formularz.
Co to jest funkcja htmlspecialchars()?
Funkcja htmlspecialchars() konwertuje znaki specjalne na jednostki HTML. Oznacza to, że zastąpi znaki HTML, takie jak < i >, na < i >. Zapobiega to wykorzystywaniu kodu przez atakujących poprzez wstrzykiwanie kodu HTML lub JavaScript (ataki Cross-site Scripting) do formularzy.
Wielka uwaga na temat bezpieczeństwa formularzy PHP
Zmienna $_SERVER["PHP_SELF"] może być używana przez hakerów!
Jeśli PHP_SELF jest używany na twojej stronie, użytkownik może wprowadzić ukośnik (/), a następnie kilka poleceń Cross Site Scripting (XSS) do wykonania.
Cross-site scripting (XSS) to rodzaj luki w zabezpieczeniach komputera, która zwykle występuje w aplikacjach sieci Web. XSS umożliwia atakującym wstrzyknięcie skryptu po stronie klienta do stron WWW przeglądanych przez innych użytkowników.
Załóżmy, że na stronie o nazwie "test_form.php" mamy następujący formularz:
<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">
Teraz, jeśli użytkownik wprowadzi normalny adres URL w pasku adresu, np. „http://www.example.com/test_form.php”, powyższy kod zostanie przetłumaczony na:
<form method="post" action="test_form.php">
Jak na razie dobrze.
Pamiętaj jednak, że użytkownik wpisuje następujący adres URL w pasku adresu:
http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E
W takim przypadku powyższy kod zostanie przetłumaczony na:
<form method="post" action="test_form.php/"><script>alert('hacked')</script>
Ten kod dodaje tag skryptu i polecenie alertu. A kiedy strona się załaduje, zostanie wykonany kod JavaScript (użytkownik zobaczy okno alertu). To tylko prosty i nieszkodliwy przykład, jak można wykorzystać zmienną PHP_SELF.
Pamiętaj, że każdy kod JavaScript może być dodany wewnątrz tagu <script>! Haker może przekierować użytkownika do pliku na innym serwerze, a ten plik może zawierać złośliwy kod, który może zmienić zmienne globalne lub przesłać formularz na inny adres, aby na przykład zapisać dane użytkownika.
Jak uniknąć exploitów $_SERVER["PHP_SELF"]?
Exploitów $_SERVER["PHP_SELF"] można uniknąć, korzystając z funkcji htmlspecialchars().
Kod formularza powinien wyglądać tak:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Funkcja htmlspecialchars() konwertuje znaki specjalne na jednostki HTML. Teraz, jeśli użytkownik spróbuje wykorzystać zmienną PHP_SELF, otrzyma następujące dane wyjściowe:
<form method="post" action="test_form.php/"><script>alert('hacked')</script>">
Próba wykorzystania kończy się niepowodzeniem i nie dzieje się nic złego!
Sprawdź poprawność danych formularza za pomocą PHP
Pierwszą rzeczą, jaką zrobimy, jest przekazanie wszystkich zmiennych przez funkcję htmlspecialchars() PHP.
Kiedy używamy funkcji htmlspecialchars(); wtedy, jeśli użytkownik spróbuje przesłać następujące informacje w polu tekstowym:
<script>lokalizacja.href('http://www.hacked.com')</script>
- to nie zostałoby wykonane, ponieważ zostałoby zapisane jako kod HTML, taki jak ten:
<script>location.href('http://www.hacked.com')</script>
Kod można teraz bezpiecznie wyświetlać na stronie lub w wiadomości e-mail.
Gdy użytkownik prześle formularz, zrobimy jeszcze dwie rzeczy:
- Usuń niepotrzebne znaki (dodatkowe spacje, tabulator, znak nowej linii) z danych wejściowych użytkownika (za pomocą funkcji PHP trim())
- Usuń odwrotne ukośniki (\) z danych wejściowych użytkownika (za pomocą funkcji PHP stripslashes())
Następnym krokiem jest stworzenie funkcji, która wykona za nas wszystkie czynności sprawdzające (co jest znacznie wygodniejsze niż pisanie tego samego kodu w kółko).
Nazwiemy funkcję test_input().
Teraz możemy sprawdzić każdą zmienną $_POST funkcją test_input(), a skrypt wygląda tak:
Przykład
<?php
// define variables and set to empty values
$name = $email = $gender = $comment = $website = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = test_input($_POST["name"]);
$email = test_input($_POST["email"]);
$website = test_input($_POST["website"]);
$comment = test_input($_POST["comment"]);
$gender = test_input($_POST["gender"]);
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
Zauważ, że na początku skryptu sprawdzamy, czy formularz został przesłany za pomocą $_SERVER["REQUEST_METHOD"]. Jeśli REQUEST_METHOD to POST, formularz został przesłany i powinien zostać zweryfikowany. Jeśli nie został przesłany, pomiń weryfikację i wyświetl pusty formularz.
Jednak w powyższym przykładzie wszystkie pola wejściowe są opcjonalne. Skrypt działa dobrze, nawet jeśli użytkownik nie wprowadza żadnych danych.
Następnym krokiem jest określenie wymaganych pól wejściowych i utworzenie komunikatów o błędach, jeśli to konieczne.