آموزش PHP : اعتبارسنجی فرم ها
در این بخش و بخش بعدی مجموعه آموزش برنامه نویسی به زبان PHP قصد داریم در رابطه با اعتبارسنجی فرم ها و اطمینان از صحت اطلاعات ارسالی صحبت کنیم. از شما دعوت میکنیم که در ادامه با مسترکد همراه شوید.
اعتبارسنجی فرم ها در PHP
همانطور که پیش تر هم روی این نکته تاکید کردیم، در ساختن فرم های PHP یکی از مهم ترین نکاتی که میبایست همواره مورد توجه قرار دهید، مبحث امنیت است. در این بخش و بخش بعدی سعی در شرح نکاتی مفید جهت حفظ امنیت فرم ها در PHP و جلوگیری از سوء استفاده هکر ها از آنها خواهیم پرداخت. فرمی که در این بخش به آن خواهیم پرداخت، فرمی است که در تصویر زیر مشاهده میکنید :
پیش از ادامه این بخش از آموزش، مجددا تاکید میکنیم که اگر با مبحث طراحی فرم HTML آشنا نیستید ابتدا آموزش استفاده از تگ form در HTML را مطالعه نموده و سپس ادامه این آموزش را به همراه ما دنبال کنید.
برای فرم بالا قوانین اعتبارسنجی زیر را در نظر گرفته ایم :
فیلد | قانون اعتبارسنجی |
Name | الزامی. فقط میتواند شامل کارکتر و فاصله باشد |
الزامی. فقط میتواند یک آدرس ایمیل معتبر شامل @ و . داشته باشد | |
Website | اختیاری. در صورت ارائه باید شامل یک URL معتبر باشد |
Comment | اختیاری. امکان ارائه متن چند خطی |
Gender | الزامی. باید یک گزینه انتخاب شود |
در ادامه به کد HTML فرم بالا نگاهی می اندازیم :
فیلد های متنی
فیلد های Name, Email و Website همگی ورودی های متنی یا text هستند و فیلد Comment، از نوع ناحیه نوشتاری یا textarea است. کد اچ تی ام ال این بخش مشابه زیر خواهد بود :
1 2 3 4 | 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> |
دکمه های رادیویی
فیلد های جنسیت یا Gender از نوع دکمه رادیویی یا Radio Button هستند. کد این بخش مشابه زیر خواهد بود :
1 2 3 | Gender: <input type="radio" name="gender" value="female">Female <input type="radio" name="gender" value="male">Male |
عنصر فرم
عنصر form را برای فرم بالا به شکل زیر تعریف کرده ایم :
1 | <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> |
همانطور که مشاهده میکنید، در این فرم، در زمان ارسال، جهت ارسال اطلاعات از متد post استفاده میشود.
متغیر $_SERVER["PHP_SELF"]
چیست؟
متغیر $_SERVER["PHP_SELF"]
یک متغیر سوپرگلوبال است که نام فایل اسکریپت فعلی در حال اجرا را باز میگرداند
بنابراین اطلاعات فرم بجای اینکه به صفحه دیگری ارسال شود به همان صفحه فعلی ارسال خواهد شد. به این شکل کاربر پیام های خطای احتمالی را در همان صفحه فرم دریافت خواهد کرد.
تابع htmlspecialchars()
چیست؟
این تابع کارکتر های خاص را به همتای اچ تی ام ال آنها تبدیل میکند. مثلا اگر کاربر در اطلاعات فرم از کارکتر های خاصی مثل < یا > استفاده کند، بجای ارسال این کارکتر ها به سرور، مجموعه کارکتر های < و > به سرور ارسال خواهند شد. این مسئله امکان تزریق کد های HTML و جاوااسکریپت توسط هکر ها جهت سوء استفاده از کد شما را از افزاد سودجو سلب خواهد کرد.
نکته مهم در رابطه با امنیت فرم ها در PHP
متغیر $_SERVER["PHP_SELF"]
متغیری است که میتواند توسط هکر ها مورد سوء استفاده قرار بگیرد. در این حالت هکر میتواند به آدرس صفحه یک اسلش اضافه کرده و کد Cross Site Scripting یا XSS را جهت اجرا به سایت شما تزریق کند.
فرض کنید که فرم زیر را در صفحه ای با نام test_from.php قرار داده باشیم :
1 | <form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>"> |
حالا اگر کاربر یک آدرس عادی مانند http://www.example.com/test_form.php را در نوار آدرس وارد کند، کد به شکل زیر برایش به نمایش در خواهد آمد :
1 | <form method="post" action="test_form.php"> |
تا اینجا مشکلی وجود ندارد اما فرض کنید که کاربر از آدرسی مانند زیر استفاده کند :
1 | http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E |
در این حالت آدرس بالا به شکل زیر ترجمه میشود :
1 | <form method="post" action="test_form.php/"><script>alert('hacked')</script> |
کد بالا یک تگ اسکریپت و یک alert به صفحه اضافه میکند. وقتی که صفحه بارگذاری شود، کد اسکریپت اجرا شده و کاربر یک باکس هشدار مشاهده میکند. کد بالا یک نمونه بسیار ساده و بی آزار از انواع سوء استفاده هایی است که میتوان از PHP_SELF انجام داد.
در اینجا باید توجه داشته باشید که که هر نوع کد جاوااسکریپتی میتواند در تگ <script> قرار بگیرد. بنابراین یک هکر میتواند کاربر را به فایل دیگری در سرور هدایت کند که حاوی کد های مخرب بوده و میتواند وضعیت متغیر های سراسری را تغییر داده یا حتی اطلاعات کاربر را به آدرس دیگری ارسال نموده و در آنجا ذخیره کند. (یا بسیاری عملیات مخرب دیگر را انجام دهد)
جلوگیری از سوء استفاده از $_SERVER["PHP_SELF"]
برای جلوگیری از سوء استفاده از سوپرگلوبال PHP_SELF میتوانید از تابع htmlspecialchars استفاده کنید. در این حالت کد فرم به شکل زیر تغییر خواهد کرد :
1 | <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> |
به این شکل اگر کاربر سعی کند PHP_SELF را مورد سوء استفاده قرار دهد، تگ فرم به شکل زیر در خواهد آمد :
1 | <form method="post" action="test_form.php/"><script>alert('hacked')</script>"> |
به این شکل تلاش وی جهت سوء استفاده به در بسته برخورد خواهد کرد و هیچ اتفاق بدی در کد شما نخواهد افتاد!
اعتبارسنجی اطلاعات فرم با استفاده از PHP
حالا که به شرح موارد لازم پرداختیم، اجازه بدهید به همراه هم، مراحل اعتبارسنجی فرم را به ترتیب مرور کنیم.
اولین کاری که انجام میدهیم انتقال همه متغیر ها به تابع htmlspecialchars در PHP است. در این حالت اگر کاربر سعی کند محتوایی مشابه <script>location.href(‘http://www.somewebsite.com’)</script> را از طریق یکی از فیلد های متنی فرم به اسکریپت ما ارسال کند، این کد اجرا نخواهد شد و به عنوان کد HTML اسکیپ شده (escape) مشابه زیر ذخیره خواهد شد :
<script>location.href(‘http://www.somewebsite.com’)</script>
نمایش کد بالا در یک صفحه یا در محتوای ایمیل کاملا امن خواهد بود.
در اینجا باید دو کار مهم دیگر نیز روی اطلاعات فرم انجام دهیم :
- کارکتر های غیر ضروری مانند اسپیس های اضافه، تب و خط جدید را از ورودی کاربر حذف کنیم. (با استفاده از تابع trim در PHP)
- بک اسلش (\) ها را با استفاده از تابع stripslashes در php از ورودی کاربر حذف کنیم.
بنابراین مرحله بعدی ساختن تابعی است که بررسی های لازم را برای ما انجام دهد و از تطابق اطلاعات ورودی با آنچه مورد نظر ماست اطمینان حاصل کند. نوشتن یک تابع برای انجام این موارد، ما را از تکرار کد بی نیاز کرده و انجام عملیات بالا را برایمان ساده تر خواهد کرد. در اینجا تابعی که برای این کار طراحی خواهیم کرد را test_input()
مینامیم. با استفاده از این تابع چک میکنیم که متغیر های ارسال شده در $_POST
با قوانین مورد نظر ما مطابقت داشته باشند. به کد زیر توجه کنید :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php // متغیر ها را تعریف کرده و آنها را معادل مقادیر خالی قرار میدهیم $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; } ?> |
همانطور که در کد بالا مشاهده میکنید، در ابتدای اسکریپت در خط ششم ابتدا بررسی کرده ایم که فرم با $_SERVER["REQUEST_METHOD"]
ارسال شده باشد. در اینجا اگر REQUEST_METHOD معادل POST باشد، پس فرم توسط کاربر ارسال شده است و اطلاعات آن نیازمند اعتبارسنجی است. اگر شرط اشتباه باشد بنابراین فرمی توسط کاربر ارسال نشده است. در این حالت از مرحله بررسی عبور کرده و فرم خالی را نمایش خواهیم داد.
توجه داشته باشید که در کد بالا، فعلا فیلد ها اجباری نیستند و حتی در صورتی که کاربر فیلدی را خالی گذاشته باشد نیز اسکریپت به درستی کار میکند. در مراحل بعد باید فیلد های ورودی را اجباری کرده و در صورت نیاز به کاربر پیام خطا نمایش دهیم.
مطالعه بخش بعدی : فیلد های ضروری فرم در PHP