Form Validation trong PHP

Mai Bùi

Bài học này và những bài học kế tiếp sẽ hướng dẫn cách sử dụng form Validation.

Form Validation

Bài học này và các bài học tiếp theo sẽ hướng dẫn cách xử lý form PHP một cách an toàn để tránh khỏi những hacker và spammer. Form HTML mà ta sử dụng trong bài này chứa nhiều loại trường input: bắt buộc, tùy chọn (có thể để trống hoặc không), radio button, nút submit.

Ví dụ Form PHP Validation

Những quy tắc đối với form trên:

TÊN TRƯỜNG QUY TẮC
Tên Bắt buộc + Chỉ chứa các chữ cái và khoảng trắng
E-mail Bắt buộc + Đúng địa chỉ email(chứa @.)
Website Không bắt buộc. Nếu có, phải là một đường dẫn hợp lệ
Bình luận Không bắt buộc. Được phép nhập nhiều dòng(textarea)
Giới tính Bắt buộc. Chỉ được chọn một

Trước tiên, ta sẽ xem code HTML đơn giản cho form:

Text Field

Ten, email, website nhập vào phần tử dạng text, comment dạng textarea. Code của HTML sẽ như sau:

Tên: <input type="text" name="ten"><br>
E-mail: <input type="text" name="email"><br>
Website: <input type="text" name="website"><br>
Bình luận: <textarea name="binh_luan" rows="5" cols="40"></textarea>

Chạy Code

Radio buttons

Trường gender thuộc radio button, code HTML sẽ như thế này:

Giới tính:
<input type="radio" name="gioi_tinh" value="female">Nữ
<input type="radio" name="gioi_tinh" value="male">Nam
<input type="radio" name="gioi_tinh" value="other">Khác

Chạy Code

Phần Tử của Form

Code HTML sẽ như sau:

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

Khi form được submit, dữ liệu sẽ được gửi bằng phương thức POST.

$_SERVER["PHP_SELF"] là gì?

$_SERVER["PHP_SELF"] là một biến superglobal sẽ trả về tên file của tập lệnh đang được thực thi
Vì vậy, $_SERVER["PHP_SELF"] sẽ gửi dữ liệu đã được submit về tại ngay trang đó thay vì bị chuyển sang trang khác. Với cách này, người dùng sẽ sẽ thấy báo lỗi ở cùng trang với form.

Hàm htmlspecialchars() là gì?

Hàm htmlspecialchars() sẽ chuyển đổi các ký tự đặc biệt thành HTML entities. Điều đó có nghĩa là nó sẽ thay thế các ký tự như <> thành &lt&gt. Điều này ngăn chặn kẻ tấn công khai thác code bằng cách chèn mã HTML hoặc JavaScript.

Lưu Ý về Xử Lý Bảo Mật Form trong PHP**:

$_SERVER["PHP_SELF"] có thể được sử dụng bởi các hacker!

Nếu PHP_SELF được sử dụng trên website của bạn, và một người dùng có thể sử dụng gạch chéo(/) và một số lệnh Cross Site Scripting(XSS) để thực hiện.

Chú ý: Cross Site Scripting(XSS) là một loại lỗ hổng bảo mật thường tìm thấy ở các ứng dụng web. XSS cho phép hackers chèn các đoạn mã từ máy chúng vào các trang web mà người dùng sử dụng.

Giả sử chúng ta có một form ở trang tên kiemTra_form.php:

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

Bây giờ, khi người dùng nhập vào một URL bình thường vào trình duyệt, ví dụ như http://www.example.com/kiemTra_form.php, đoạn code phía trên sẽ được dịch thành:

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

Mọi chuyện vẫn ổn.

Tuy nhiên, nếu một người dùng khác nhập vào một URL như sau vào trình duyệt:

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

thì đoạn code trên sẽ dịch thành như sau:

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

Đoạn code này sẽ thêm vào một thẻ script và một lệnh cảnh báo. Khi load trang,đoạn mã Javascript sẽ được chạy(người dùng sẽ thấy hiện ô cảnh báo). Đây chỉ là một ví dụ đơn giản và vô hại mô tả cách mà PHP_SELF có thể bị khai thác.

Hãy cẩn trọng với bất kỳ đoạn mã Javascript có thể được thêm vào trong thẻ <script>!

Hacker có thể điều hướng người dùng sang một file trên server khác. File đó có thể chứa mã độc với các biến toàn cục bị sửa đổi hoặc submit form đến một trang khác để lấy dữ liệu người dùng.

Làm Thế Nào Để Tránh $_SERVER["PHP_SELF"] Bị Khai Thác?

Để tránh $_SERVER["PHP_SELF"] bị khai thác ta sử dụng hàm htmlspecialchars().

Code HTML có thể 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 HTML entites. Nếu một người cố ý khai thác PHP_SELF thì kết quả sẽ như sau:

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

Khai thác bị thất bại, không có thiệt hại nào xảy ra!

Validate Form Data Trong PHP

Điều đầu tiên ta phải làm là chuyển đổi tất cả các biến thông qua hàm htmlspecialchars().
Khi sử dụng hàm htmlspecialchars(), khi người dùng cố ý submit một text field:

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

Đoạn code trên sẽ không thi hành được vì nó đã được bảo vệ bởi code HTML escaped, và kết quả sẽ trả về như sau:

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

Code bây giờ sẽ an toàn để hiển thị trên trang web hoặc bên trong email.

Chúng ta cũng phải thực hiện thêm 2 việc khi người dùng nhập dữ liệu vào form:

  1. Loại bỏ các ký tự không cần thiết(khoảng trắng 2 đầu,tab, dòng mới) từ dữ liệu nhập vào(sử dụng hàm trim() trong PHP).
  2. Loại bỏ các dấu gạch chéo(\) từ dữ liệu nhập vào(sử dụng hàm stripslashes() trong PHP).

Bước tiếp theo là tạo một hàm sẽ thực hiện việc kiểm tra dữ liệu nhập vào(thuận tiện hơn là viết các dòng code kiểm tra lặp đi lặp lại.

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

Bây giờ, chúng ta có thể kiểm tra mỗi $_POST với hàm kiemTra_input(). Đoạn code có thể như sau:

Ví dụ:

<?php
// định nghĩa các biến và gán các giá trị rỗng
$ten = $email = $gioi_tinh = $binh_luan = $website = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
  $ten = kiemTra_input($_POST["ten"]);
  $email = kiemTra_input($_POST["email"]);
  $website = kiemTra_input($_POST["website"]);
  $binh_luan = kiemTra_input($_POST["binh_luan"]);
  $gioi_tinh = kiemTra_input($_POST["gioi_tinh"]);
}

function kiemTra_input($data) {
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
}
?>

Chạy Code

Chú ý rằng khi bắt đầu, ta cần kiểm tra phương thức gửi dữ liệu bằng cách sử dụng $_SERVER["REQUEST_METHOD"]. Nếu REQUEST_METHODPOST, sau đó tiến hành việc gửi dữ liệu – nếu như nó hợp lệ. Nếu dữ liệu không được gửi đi, bỏ qua việc xác thực và hiển thị form trống.

Tuy nhiên, trong ví dụ trên, tất cả các input đều tùy chọn. Các dòng lệnh vẫn hoạt động tốt kể cả khi người dùng không gửi bất kỳ dữ liệu nào.

Bước tiếp theo là tạo những trường input bắt buộc và tạo tin nhắn báo lỗi nếu cần.

Thêm Phản Hồi