By GokiSoft.Com| 15:30 21/06/2020|
Tài Liệu PHP

PHP Form Validation

Bài này và các bài tiếp theo sẽ sử dụng PHP để xác thực dữ liệu biểu mẫu (form validation).


PHP Form Validation

Bạn cần quan tâm đến vấn đề bảo mật khi xử lý PHP form!

Xác thực hợp lệ dữ liệu biểu mẫu là rất quan trọng để bảo vệ biểu mẫu của bạn khỏi tin tặc (hackers) và kẻ gửi thư rác (spammers)!

Biểu mẫu HTML mà chúng ta sẽ xử lý trong các bài này chứa các trường input khác nhau: các trường input bắt buộc (required) và tùy chọn, radio button và submit button:


Các validation rules cho form bên trên như sau:

TrườngValidation Rules
NameRequired. + Chỉ chứa chữ cái và khoảng trắng
E-mailRequired. + Phải chứa email hợp lệ (có @ và.)
WebsiteKhông bắt buộc. Nếu có, nó phải chứa URL hợp lệ
CommentKhông bắt buộc. Trường nhập nhiều dòng (textarea)
GenderRequired. Phải chọn một

Text Fields - Các trường input type="text"

Các trường name, email, và website đều có type="text", và trường comment là textarea. Code HTML sẽ như sau:

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à các radio button và code HTML sẽ như sau:

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

The Form Element (Thẻ form)

Code HTML cho thẻ form sẽ như sau:

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

Khi biểu mẫu được gửi, dữ liệu biểu mẫu được gửi với method="post".

Biến $_SERVER["PHP_SELF"] là biến gì?

Biến $_SERVER["PHP_SELF"] là biến super global trả về tên tệp của tập lệnh hiện đang thực thi.

Vì vậy, biến $_SERVER["PHP_SELF"] gửi dữ liệu biểu mẫu đến chính trang đó, thay vì đế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 biểu mẫu.

Hàm htmlspecialchars() là hàm gì?

Hàm htmlspecialchars() chuyển đổi các ký tự đặc biệt thành các thực thể HTML. Điều này có nghĩa là nó sẽ thay thế các ký tự HTML như < và > thành &lt; và &gt;. Điều này ngăn kẻ tấn công khai thác bằng cách chích code HTML hoặc Javascript (Cross-site Scripting attacks) trong các biểu mẫu.


Lưu ý về bảo mật biểu mẫu PHP

Biến $_SERVER["PHP_SELF"] có thể được sử dụng bởi hackers!

Nếu PHP_SELF được sử dụng trong trang của bạn thì người dùng có thể nhập dấu gạch chéo (/) và sau đó một số lệnh Cross Site Scripting (XSS) để thực thi.

Cross-site-scripting (XSS) là một loại lỗ hổng bảo mật máy tính thường được tìm thấy trong các ứng dụng Web. XSS cho phép kẻ tấn công chích tập lệnh phía máy khách vào trang Web được xem bởi người dùng khác.

Giả sử chúng ta có biểu mẫu sau trong một trang có tên "test_form.php":

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

Bây giờ, nếu người dùng nhập URL bình thường vào thanh địa chỉ như "http://www.example.com/test_form.php", đoạn code trên sẽ trở thành:

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

Mọi thứ vẫn tốt.

Tuy nhiên, hãy xem xét rằng người dùng nhập URL sau vào thanh địa chỉ:

http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E

Trong trường hợp này, đoạn code trên sẽ thành:

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

Code này thêm thẻ script và lệnh alert. Và khi tải trang, code JavaScript sẽ được thực thi (người dùng sẽ thấy một hộp alert). Đây chỉ là một ví dụ đơn giản và vô hại về cách biến PHP_SELF có thể được khai thác.

Lưu ý rằng bất kỳ mã JavaScript nào cũng có thể được thêm vào bên trong thẻ <script>! Một hacker có thể redirect người dùng đến một tệp trên máy chủ khác mà tệp đó chứa mã độc có thể thay đổi các biến toàn cục hoặc gửi biểu mẫu đến địa chỉ khác để lưu dữ liệu người dùng.


Làm cách nào để tránh khai thác $ _SERVER ["PHP_SELF"]?

$_SERVER["PHP_SELF"] có thể tránh được bằng cách sử dụng hàm htmlspecialchars().

Code nên viết như sau:

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

Hàm htmlspecialchars() chuyển đổi các ký tự đặc biệt thành các thực thể HTML. Bây giờ nếu người dùng cố gắng khai thác biến PHP_SELF, nó sẽ dẫn đến đầu ra sau:

<form method="post" action="test_form.php/&quot;&gt;&lt;script&gt;alert('hacked')&lt;/script&gt;">

Nỗ lực khai thác thất bại, và sẽ không có tác hại nào!


Validate biểu mẫu với PHP

Điều đầu tiên chúng ta sẽ làm là truyền tất cả các biến thông qua hàm htmlspecialchars() của PHP.

Khi chúng ta sử dụng hàm htmlspecialchars(); sau đó nếu người dùng cố gắng gửi nội dung sau:

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

- điều này sẽ không được thực thi, bởi vì nó sẽ được lưu dưới dạng mã HTML như sau:

&lt;script&gt;location.href('http://www.hacked.com')&lt;/script&gt;

Code hiện giờ an toàn để được hiển thị trên một trang hoặc bên trong e-mail.

Chúng ta cần làm thêm hai điều nữa khi người dùng gửi biểu mẫu:

  1. Strip (loại bỏ) các ký tự không cần thiết (extra space, tab, newline) khỏi input data (với phương thức trim() của PHP)
  2. Loại bỏ dấu xổ ngược (\) khỏi input data (với phương thức stripslashes())

Bước tiếp theo là tạo một hàm sẽ thực hiện việc kiểm tra (thuận tiện hơn nhiều so với việc viết cùng một đoạn code nhiều lần).

Chúng ta sẽ đặt tên hàm là test_input().

Bây giờ, chúng ta có thể kiểm tra từng biến $ _POST bằng hàm test_input() và tập lệnh trông như sau:

Ví dụ

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

Lưu ý rằng khi bắt đầu tập lệnh, chúng ta kiểm tra xem biểu mẫu đã được gửi bằng $ _SERVER ["REQUEST_METHOD"] nào. Nếu REQUEST_METHOD là POST, thì biểu mẫu đã được gửi - và nó phải được validate. Nếu nó chưa được gửi, bỏ qua validate và hiển thị một biểu mẫu trống.

Tuy nhiên, trong ví dụ trên, tất cả các trường input đều là tùy chọn (không required). Tập lệnh vẫn sẽ hoạt động ngay cả khi người dùng không nhập bất kỳ ký tự nào vào các trường.

Bước tiếp theo là tạo các trường required input và tạo thông báo nếu cần.