PHP – Validation

Bài này sẽ trình bày cách dùng PHP để validate dữ liệu form.

PHP Form Validation

Xử lý validation PHP forms là quan trọng để bảo vệ form của bạn khỏi tin tặc và kẻ gửi spam!

Form trong bài này chứa các trường input: Với text fields (required và optional), radio buttons, và submit button

Yêu cầu cho các trường input như sau:

  • Name : Required. + chỉ chứa chữ cái và khoản trắng.
  • E-mail : Required. + Một email hợp lệ (chứa @ và .)
  • Website : Optional. Nếu có thì phải là URL hợp lệ
  • Comment : Optional. (textarea)
  • Gender Required. Phải chọn một

Text Fields

Các trường name, email, và website là text input. Trường comment là textarea.

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>

Radio Buttons

Trường gender là radio buttons.

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

Thẻ Form với code như sau:

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

Khi nút submit được nhấn, dữ liệu sẽ được gửi với method=”post”

$_SERVER[“PHP_SELF”] là biến super global trả về tên file của script thực thi.

$_SERVER[“PHP_SELF”] sẽ gửi dữ liệu form đến chính nó. Thay vì gửi đến một trang khác. Bằng cách này, người dùng sẽ nhận được thông báo lỗi trên cùng một trang với form.

htmlspecialchars() function sẽ chuyển ký tự đặc biệt thành các thực thể HTML (HTML entities), Điều này có nghĩa là nó sẽ thay thế các ký tự HTML như < và > bằng < và >. Điều này giúp ngăn chặn kẻ tấn công khai thác mã bằng cách thêm HTML hoặc Javascript (Cross-site Scripting attacks) vào form.

Chú ý

Biến $_SERVER[“PHP_SELF”] có thể bị khai thác bở hackers.

Nếu PHP_SELF được dùng, người dùng có thể nhập dấu (/) và sau đó là lệnh Cross Site Scripting (XSS) để thực thi.

Cross-site scripting (XSS) là lỗ hổng bảo mật thường được tìm thấy trên ứng dụng web. XSS cho phép kẻ tấn công chèn client-side script đến trang web được xem bởi người dùng khác.

Giả sử chúng ta có đoạn code sau:

<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">

Bây giờ nếu vào URL “http://www.example.com/test_form.php”, code trên sẽ trả về:

<form method="post" action="test_form.php">

Tuy nhiên, nếu 1 người dùng khác vào URL sau http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert(‘hacked’)%3C/script%3E.

Trường hợp này, code sẽ được chuyển thành như sau:

<form method="post" action="test_form.php/"><script>alert('hacked')</script>

Code trên đã thêm 1 thẻ script với 1 alert. Và khi load trang, code JavaScript sẽ được thực thi và alert được bật lên. Đây là 1 ví dụ đơn giản và vô hại cho thấy PHP_SELF có thể bị khai thác như thế nào.

Lưu ý là bất kỳ mã JavaScript cũng có thể được thêm vào, hacker có thể redirect đến 1 file trên server khác hay lấy cắp thông tin người dùng.

Tránh bị khai thác $_SERVER[“PHP_SELF”]

Có thể dùng htmlspecialchars() để tránh bị khai thác biến $_SERVER[“PHP_SELF”].

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

Hàm htmlspecialchars() sẽ chuyển ký tự đặt biệt thành HTML entities. Lúc này, kết quả khi người dùng cố khai thác biến PHP_SELF:

<form method="post" action="test_form.php/"><script>alert('hacked')</script>">

Validate Form Data With PHP

Điều đầu tiên chúng ta chuyển tất cả các biến bằng hàm htmlspecialchars() của PHP.

Khi dùng hàm htmlspecialchars(), nếu user cố gắng submit một text field:

<script>location.href('http://www.hacked.com')</script>

Nó sẽ không thực thi vì nó được lưu dưới dạng thực thể của nó

<script>location.href('http://www.hacked.com')</script>

Vì thế đoạn mã này được hiển thị an toàn trên trang web hay trong 1 email.

Chúng ta cần làm thêm 2 việc nữa:

  • Loại bỏ ký tự không cần thiết (khoản trắng 2 đầu, tab, hay 1 hàng rỗng mới) từ dữ liệu input với hàm trim().
  • Loại bỏ đấu (\) bằng hàm stripslashes().

Để làm những việc đó, chúng ta nên tạo 1 function để tránh lặp lại code. Ví dụ function test_input() như bên dưới:

<?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;
}
?>

Đầu tiên, chúng ta kiểm tra form đã được gửi chưa bằng $_SERVER[“REQUEST_METHOD”]. Nếu REQUEST_METHOD bằng POST thì form đã được gửi, nếu chưa, bỏ qua bước validated và hiển thị form.

Bài tiếp theo, chúng ta sẽ làm các input fields required và tạo messages thông báo nếu cần.