Xác thực biểu mẫu PHP
Phần này và các chương tiếp theo trình bày cách sử dụng PHP để xác thực dữ liệu biểu mẫu.
Xác thực biểu mẫu PHP
Hãy nghĩ đến sự AN TOÀN khi xử lý các biểu mẫu PHP!
Các trang này sẽ chỉ ra cách xử lý các biểu mẫu PHP có lưu ý đến tính bảo mật. Việc xác nhận đúng cách dữ liệu biểu mẫu là điều quan trọng để bảo vệ biểu mẫu của bạn khỏi tin tặc và những kẻ gửi thư rác!
Biểu mẫu HTML mà chúng ta sẽ làm việc trong các chương này, chứa các trường đầu vào khác nhau: trường văn bản bắt buộc và tùy chọn, nút radio và nút gửi:
Các quy tắc xác thực cho biểu mẫu trên như sau:
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 |
Trước tiên, chúng ta sẽ xem xét mã HTML thuần túy cho biểu mẫu:
Trường văn bản
Các trường tên, email và trang web là các yếu tố nhập văn bản và trường nhận xét là một vùng văn bản. Mã HTML trông như thế này:
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>
Các nút radio
Các trường giới tính là các nút radio và mã HTML trông giống 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
Phần tử biểu mẫu
Mã HTML của biểu mẫu trông giống 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à gì?
$ _SERVER ["PHP_SELF"] là một biến siêu toàn cục trả về tên tệp của tập lệnh hiện đang thực thi.
Vì vậy, $ _SERVER ["PHP_SELF"] sẽ gửi dữ liệu biểu mẫu đã gửi đến chính trang đó, thay vì chuyển sang 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à 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à> bằng & lt; và & gt ;. Điều này ngăn những kẻ tấn công khai thác mã bằng cách chèn mã HTML hoặc mã Javascript (Các cuộc tấn công Cross-site Scripting) vào các biểu mẫu.
Lưu ý lớn về bảo mật biểu mẫu PHP
Biến $ _SERVER ["PHP_SELF"] có thể bị tin tặc sử dụng!
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 (/) rồi thực thi một số lệnh Cross Site Scripting (XSS).
Cross-site scripting (XSS) là một loại lỗ hổng bảo mật máy tính thường thấy trong các ứng dụng Web. XSS cho phép kẻ tấn công đưa tập lệnh phía máy khách vào các trang Web được người dùng khác xem.
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", thì đoạn mã trên sẽ được dịch thành:
<form method="post" action="test_form.php">
Càng xa càng 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, mã trên sẽ được dịch thành:
<form method="post" action="test_form.php/"><script>alert('hacked')</script>
Mã này thêm một thẻ script và một lệnh cảnh báo. Và khi tải trang, mã JavaScript sẽ được thực thi (người dùng sẽ thấy một hộp cảnh báo). Đây chỉ là một ví dụ đơn giản và vô hại về cách khai thác biến PHP_SELF.
Hãy 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 tin tặc có thể chuyển hướng người dùng đến một tệp trên máy chủ khác và tệp đó có thể chứa mã độc hại có thể thay đổi các biến chung hoặc gửi biểu mẫu đến một địa chỉ khác để lưu dữ liệu người dùng chẳng hạn.
Làm thế nào để tránh bị khai thác $ _SERVER ["PHP_SELF"]?
Có thể tránh khai thác $ _SERVER ["PHP_SELF"] bằng cách sử dụng hàm htmlspecialchars ().
Mã biểu mẫu sẽ giống 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 kết quả sau:
<form method="post" action="test_form.php/"><script>alert('hacked')</script>">
Nỗ lực khai thác không thành công và không có tác hại nào được thực hiện!
Xác thực dữ liệu biểu mẫu với PHP
Điều đầu tiên chúng ta sẽ làm là chuyể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 trong trường văn bản:
<script> location.href ('http://www.hacked.com') </script>
- điều này sẽ không được thực thi, vì nó sẽ được lưu dưới dạng mã thoát HTML, như thế này:
& lt; script & gt; location.href ('http://www.hacked.com') & lt; / script & gt;
Mã hiện an toàn để được hiển thị trên một trang hoặc bên trong e-mail.
Chúng tôi cũng sẽ thực hiện hai việc nữa khi người dùng gửi biểu mẫu:
- Loại bỏ các ký tự không cần thiết (thêm khoảng trắng, tab, dòng mới) khỏi dữ liệu đầu vào của người dùng (với hàm trim () PHP)
- Xóa dấu gạch chéo ngược (\) khỏi dữ liệu đầu vào của người dùng (với hàm dấu gạch chéo ngược () trong PHP)
Bước tiếp theo là tạo một hàm sẽ thực hiện tất cả việc kiểm tra cho chúng ta (điều này thuận tiện hơn nhiều so với việc viết đi viết lại cùng một đoạn mã).
Chúng tôi sẽ đặt tên cho hàm 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 giống như sau:
Thí 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 tôi kiểm tra xem biểu mẫu đã được gửi bằng cách sử dụng $ _SERVER ["REQUEST_METHOD"] hay chưa. Nếu REQUEST_METHOD là POST, thì biểu mẫu đã được gửi - và nó phải được xác thực. Nếu nó chưa được gửi, hãy bỏ qua xác thực 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 đầu vào là tùy chọn. Tập lệnh hoạt động tốt ngay cả khi người dùng không nhập bất kỳ dữ liệu nào.
Bước tiếp theo là yêu cầu các trường nhập và tạo thông báo lỗi nếu cần.