Bài này sẽ hướng dẫn bạn cách xác thực Form - Validate Form trong PHP.
Trong bài này, chúng ta sẽ validate form có dạng như sau:
Các quy tắc để xác thực cho form trên như sau:
Field | Validation Rules |
---|---|
Name | Bắt buộc. Chỉ chứa ký tự chữ và dấu cách. |
Bắt buộc. Một email hợp lệ chứa ký tự @ và dấu chấm (.) | |
Website | Tùy chọn. Nếu được nhập, URL phải hợp lệ. |
Comment | Tùy chọn. Chó phép nhập nhiều dòng (textarea) |
Gender | Bắt buộc. Phải chọn 1 tùy chọn |
File comment.php
<!DOCTYPE HTML> <html> <head> <style> .error {color: #FF0000;} </style> </head> <body> <?php const REQUIRED_MSG = "is required"; // định nghĩa các biến và set giá trị mặc định là blank $nameErr = $emailErr = $genderErr = $websiteErr = ""; $name = $email = $gender = $comment = $website = ""; // xác thực form bằng PHP if ($_SERVER["REQUEST_METHOD"] == "POST") { if (empty($_POST["name"])) { $nameErr = "Name " . REQUIRED_MSG; } else { $name = test_input($_POST["name"]); if (!preg_match("/^[a-zA-Z ]*$/",$name)) { $nameErr = "Only letters and white space allowed"; } } if (empty($_POST["email"])) { $emailErr = "Email " . REQUIRED_MSG; } else { if (!preg_match("/^[a-zA-Z][\\w-]+@([\\w]+\\.[\\w]+ |[\\w]+\\.[\\w]{2,}\\.[\\w]{2,})$/", $email)) { $emailErr = "Invalid email format"; } } if (empty($_POST["website"])) { $website = ""; } else { if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]* [-a-z0-9+&@#\/%=~_|]/i", $website)) { $websiteErr = "Invalid URL"; } } if (empty($_POST["comment"])) { $comment = ""; } else { $comment = test_input($_POST["comment"]); } if (empty($_POST["gender"])) { $genderErr = "Gender " . REQUIRED_MSG; } else { $gender = test_input($_POST["gender"]); } } function test_input($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return $data; } ?> <h2>Ví dụ Validate Form trong PHP</h2> <p><span class="error">* required field</span></p> <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> <table> <tr> <td>Name:</td> <td><input type="text" name="name"> <span class="error">* <?php echo $nameErr;?></span> </td> </tr> <tr> <td>E-mail:</td> <td><input type="text" name="email"> <span class="error">* <?php echo $emailErr;?></span> </td> </tr> <tr> <td>Website:</td> <td><input type="text" name="website"> <span class="error"><?php echo $websiteErr;?></span> </td> </tr> <tr> <td>Comment:</td> <td><textarea name="comment" rows="5" cols="40"></textarea></td> </tr> <tr> <td>Gender:</td> <td> <input type="radio" name="gender" value="female">Female <input type="radio" name="gender" value="male">Male <input type="radio" name="gender" value="other">Other <span class="error">* <?php echo $genderErr;?></span> </td> </tr> <tr> <td></td> <td><input type="submit" name="submit" value="Submit"></td> </tr> </table> </form> <?php echo "<h2>Thông tin bạn đã nhập:</h2>"; echo $name; echo "<br>"; echo $email; echo "<br>"; echo $website; echo "<br>"; echo $comment; echo "<br>"; echo $gender; ?> </body> </html>
Nội dung chính
Các phần tử trong ví dụ
Thẻ Form
Thẻ Form trong ví dụ của chúng ta như sau:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Khi click button [Submit], dữ liệu form được gửi với method="post".
Biến $_SERVER["PHP_SELF"] là gì?
$_SERVER["PHP_SELF"] là biến siêu toàn cầu trong PHP trả về tên file của hiện tại.
Vì vậy, $_SERVER["PHP_SELF"] sẽ gửi dữ liệu form đến chính nó, thay vì nhảy sang trang khác.
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ư < and > với < và >. Điều này ngăn cản kẻ tấn công khai thác lỗ hổng bằng cách tiêm mã HTML hoặc Javascript (Cross-site Scripting attacks) vào form.
Big Note về bảo mật PHP Form
Biến $ _SERVER ["PHP_SELF"] có thể được 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 một 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èn tập lệnh phía máy khách vào các trang Web mà người dùng khác xem.
Giả sử chúng ta có dạng sau trong một trang có tên là "test_form.php":
form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">
Bây giờ, nếu người dùng nhập URL thông thường vào thanh địa chỉ như "http://www.example.com/test_form.php", mã trên sẽ được dịch sang:
<form method="post" action="test_form.php">
Tuy nhiên, nếu 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 sang:
<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 hiện (người dùng sẽ thấy một hộp cảnh báo). Đây là một ví dụ vô hại về khai thác lỗ hổng của biến PHP_SELF.
Lưu ý: 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ể 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 toàn cầu hoặc gửi form tới một địa chỉ khác để lưu dữ liệu người dùng.
Làm thế nào để tránh $_SERVER ["PHP_SELF"] bị Khai thác?
Có thể tránh được $_SERVER ["PHP_SELF"] bị khai thác bằng cách sử dụng hàm htmlspecialchars().
Ví dụ:
<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 bị thất bại!