PHP:ارزیابی فرم‌ها در PHP

از ویکی کد
پرش به ناوبری پرش به جستجو
میانبر:
الگو:اصلاح جدول


این فصل و فصل بعد نحوه استفاده از PHP برای ارزیابی اطلاعات فرم را به شما نشان می‌دهد. [۱]

ارزیابی فرم‌ها در PHP

فرم HTML ای که در این فصل‌ها با آن کار خواهیم کرد شامل مقادیر ورودی متفاوتی است: فیلدهای ورودی متنی اجباری و اختیاری، دکمه‌های radio، و یک دکمه ثبت:

Time2wait.svg ساخت نمونه مثال این بخش در دست اقدام است.


قوانین ارزیابی برای فرم فوق به صورت زیر است:

فیلد قوانین ارزیابی
فیلد نام (Name) اجباری است. می‌بایست شامل حروف و فضاهای خالی باشد.
پست الکترونیکی (E-mail) اجباری است. می‌بایست شامل یک آدرس ایمیل معتبر باشد (با @ و)
وب سایت (website) اختیاری است. در صورت وجود، می‌بایست شامل یک آدرس (url) معتبر باشد.
نظر (comment) اختیاری است. فیلد ورودی چند خطی (از نوع textarea)
جنسیت (gender) اجباری است. می‌بایست یک جنسیت را مشخص کند.

ابتدا ما نگاهی به کد HTML فرم بالا میندازیم:

فیلدهای متنی

فیلدهای نام، نشانی پست الکترونیکی و وب سایت عناصر ورودی متنی هستند، و فیلد نظر یک محدوده متنی (به انگلیسی: Textarea) است. کد HTML آن به صورت زیر است:

1 Name: <input type="text" name="name">
2 E-mail: <input type="text" name="email">
3 Website: <input type="text" name="website">
4 Comment: <textarea name="comment" rows="5" cols="40"></textarea>

دکمه‌های Radio

فیلدهای جنسیت از نوع radio button هستند و کد HTML آن به صورت زیر است:

1 Gender:
2 <input type="radio" name="gender" value="female">Female
3 <input type="radio" name="gender" value="male">Male
4 <input type="radio" name="gender" value="other">Other

عنصر فرم

کد HTML به صورت زیر است:

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

زمانی که اطلاعات فرم ثبت می‌شود، اطلاعات فرم به وسیله method="post" ارسال می‌شود.

بنابراین، $_SERVER["PHP_SELF"] اطلاعات ثبت شده را به خود صفحه به جای ارسال آن به یک صفحه متفاوت، ارسال می‌کند. این روش، موجب می‌شود که کاربر در همان صفحه ای که فرم در آن قرار دارد پیغام خطا دریافت کند.


نکته بزرگ درمورد امنیت فرم‌های PHP

دستور $_SERVER["PHP_SELF"] می‌تواند توسط هکرها استفاده شود!

اگر PHP_SELF در صفحه شما استفاده شده باشد، یک کاربر می‌تواند یک اسلش / اضافه کند و سپس از طریق حمله Cross Site Scripting (XSS) دستوراتی را برای اجرا وارد کند.


فرض بگیرید که ما فرم زیر را در صفحه ای به نام "test_form.php" داریم:

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

حال، اگر یک کاربر آدرس (به انگلیسی: URL) عادی مانند "http://www.example.com/test_form.php" را در قسمت آدرس مرورگر (address bar) وارد کند، کد بالا به صورت زیر درخواهد آمد:

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

بسیار خب، تا این مرحله مشکلی وجود ندارد. اما، فرض بگیرید که یک کاربر آدرس زیر را در قسمت آدرس (به انگلیسی: Address bar) مرورگر خود وارد کند:

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

در این مثال، کد بالا به کد زیر تبدیل می‌شود:

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

این کد یک تگ script و یک دستور alert را اضافه می‌کند؛ و زمانی که صفحه بارگذاری شد، کد جاوا اسکریپت اجرا می‌شود (کاربر یک پیغام هشدار مشاهده خواهد کرد). این تنها یک مثال ساده و بی‌خطر از نحوه استفاده از آسیب‌پذیری مربوط به PHP_SELF است.

توجه داشته باشید که هر گونه کد جاوا اسکریپت را می‌توان درون تگ <script> اضافه کرد! برای مثال یک هکر می‌تواند کاربر را به سمت یک فایل روی یک سرور دیگر هدایت کند، و آن فایل می‌توان شامل کدهای مخربی باشد که می‌تواند متغیرهای سراسری را تغییر دهد یا اطلاعات فرم را به آدرس دیگری ارسال کند تا اطلاعات کاربر را ذخیره کند.

چطور می‌توانیم از آسیب‌پذیری $_SERVER["PHP_SELF"] جلوگیری کنیم؟

می‌توان با استفاده کردن تابع htmlspecialchars() از آسیب‌پذیری $_SERVER["PHP_SELF"] جلوگیری کرد.

کد فرم به صورت زیر خواهد بود:

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

تابع htmlspecialchars() کاراکترهای مخصوص را به علائم HTML تبدیل می‌کند. حال اگر کاربری سعی کند که از آسیب‌پذیری متغیر PHP_SELF استفاده کند، نتیجه‌ای به صورت زیر خواهد داشت:

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

تلاش برای استفاده از این آسیب‌پذیری بی‌فایده است، و هیچ خطری وجود ندارد.

ارزیابی داده‌های فرم با PHP

اولین کاری که ما انجام خواهیم داد این است که تمام متغیرها را از طریق تابع htmlspecialchars() پاس می‌دهیم.

زمانی که ما از تابع htmlspecialchars() استفاده می‌کنیم؛ اگر کاربری سعی کند که داده‌ای مانند زیر را درون یک فیلد ورودی متنی ثبت کند:

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

این کد اجرا نخواهد شد، زیرا که این کد به صورت یک کد HTML به صورت زیر ذخیره خواهد شد:

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

این کد برای نمایش روی صفحه یا درون یک ایمیل امن است.

ما همچنین دو کار دیگر نیز هنگامی که کاربر اطلاعات فرم را ثبت می‌کند انجام خواهیم داد:

  1. از بین بردن کاراکترهای غیر ضروری (فضای خالی اضافی، فضاهای tab، خط جدید) از اطلاعات ورودی کاربر (به وسیله تابع trim() در PHP)
  2. حذف بک اسلش \ از اطلاعات ورودی کاربر (به وسیله تابع stripslashes() در PHP)

قدم بعدی ایجاد یک تابع است که تمامی بررسی را برای ما انجام خواهد داد (که این امر از نوشتن دوباره و دوباره کدهای مشابه بسیار رایج‌تر است).

ما نام این تابع را test_input() می‌گذاریم.

حال، ما می‌توانیم هر متغیر $_POST را به وسیله تابع test_input() بررسی کنیم، و کد اسکریپت به صورت زیر خواهد بود:

مثال

 1 <?php
 2 // define variables and set to empty values
 3 $name = $email = $gender = $comment = $website = "";
 4 
 5 if ($_SERVER["REQUEST_METHOD"] == "POST") {
 6   $name = test_input($_POST["name"]);
 7   $email = test_input($_POST["email"]);
 8   $website = test_input($_POST["website"]);
 9   $comment = test_input($_POST["comment"]);
10   $gender = test_input($_POST["gender"]);
11 }
12 
13 function test_input($data) {
14   $data = trim($data);
15   $data = stripslashes($data);
16   $data = htmlspecialchars($data);
17   return $data;
18 }
19 ?>

توجه داشته باشید که در ابتدای کد اسکریپت، ما متد درخواست اطلاعات فرم را به وسیله $_SERVER["REQUEST_METHOD"] بررسی می‌کنیم. در صورتی که متد درخواست یا REQUEST_METHOD متد POST بود، سپس اطلاعات فرم ثبت خواهد شد و داده‌های آن نیز ارزیابی می‌شوند. اگر فرم ثبت نشود، ارزیابی صورت نمی‌گیرد و یک فرم خالی نمایش داده می‌شود.

اما، در مثال بالا، تمامی فیلدهای ورودی اختیاری هستند. اسکریپت در صورتی که کاربر اطلاعاتی وارد نکند به خوبی کار می‌کند.

قدم بعدی اجباری کردن فیلدهای ورودی و ساخت پیغام خطا در صورت نیاز است.

منابع آموزشی