در این بیاموز و همچنین بیاموز بعدی، نحوه ی اعتبارسنجی داده های فرم با استفاده از PHP آموزش داده خواهد شد.


اعتبارسنجی فرم در PHP

Wiki

Note

زمان پردازش فرم های PHP، به امنیت بیاندیشید!

در این بیاموز نحوه ی پردازش فرم های PHP بصورتی که حداقل موارد امنیتی که در ذهن دارید حفظ شود، نشان داده خواهد شد. اعتبار سنجی مناسب اطلاعات فرم، بمنظور جلوگیری از حمله هکرها دارای اهمیت است.

فرم HTMLی که در این بیاموز روی آن کار خواهیم کرد شامل فیلدهای مختلفی است: فیلدهای متنی الزامی و اختیاری، radio button و یک دکمه submit:

در جدول زیر قوانین اعتبارسنجی ذکر شده است:

فیلد قوانین اعتبارسنجی
نام الزامی است. فقط باید شامل حروف الفبا و خط فاصله باشد.
ایمیل الزامی است. باید شامل فرمت صحیح ایمیل باشد (همراه با علامت @ و .)
وب سایت اختیاری است. اگر پر شد، باید شامل فرمت صحیح URL باشد.
توضیحات اختیاری است. می تواند شامل چند خط متن باشد (textarea)
جنسیت الزامی است. یکی از دو مورد باید انتخاب شود.

اجازه دهید تا در ابتدا نگاهی به کد HTMLفرم بیاندازیم.


فیلدهای متنی

Wiki

برای فیلدهای متنی "نام"، "ایمیل" و "وب سایت" از عنصر متنی <input> و برای فیلد "توضیحات" از عنصر <textarea> استفاه می کنیم:

نام: <input type="text" name="name">
ایمیل: <input type="text" name="email">
وب سایت: <input type="text" name="website">
توضیحات: <textarea name="comment" rows="5" cols="40"></textarea>

فیلد "جنسیت"

Wiki

برای فیلد "جنسیت" از Radio Button استفاده می کنیم: (عنصر <input> از نوع radio)

جنسیت:
<input type="radio" name="gender" value="female">Female
<input type="radio" name="gender" value="male">Male

عنصر <form>

Wiki

کد HTML فرم شبیه زیر است:

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

زمانی که روی دکمه submit کلیک می شود، اطلاعات با متد "post" به سرور ارسال می شود.

Note متغییر SERVER_$
متغییر SERVER_$ یکی از متغییرهای عمومی از پیش تعریف شده است (آرایه). "PHP_SELF" نام فایلِ اسکریبت جاری را برمی گرداند.

بنابراین زمانی که کاربر روی دکمه submit کلیک می کند، بجای اینکه داده ها به یک فایل متفاوت دیگر ارسال شود به خودش ارسال خواهد شد. در این روش، کاربر خطاها را در همان صفحه ای که فرم وجود دارد مشاهده خواهد کرد.

Note تابع ()htmlspecialchars
با استفاده از تابع ()htmlspecialchars، می توان کاراکترهای خاص را به HTML entity تبدیل نمود. منظور این است که کاراکترهایی مثل علامت کوچکتر(<) و بزرگتر(>) در پارامتر ورودی را به ;lt$ و ;gt$ تبدیل می کند. با این کار از حمله ی هکرهایی که می خواهند از طریق تزریق HTML یا JavaScript اخلال ایجاد کنند، جلوگیری می شود.

یک تذکر مهم درباره امنیت فرم PHP

Wiki

PHP_SELF می تواند توسط هکرها مورد استفاده قرار گیرد.

یک هکر می تواند در آدرس بار مرورگرش بعد از آدرس فایل، یک اسلش (/) قرار دهد و سپس دستورات XSS را برای اجرا تایپ کند.

Note

XSS یا Cross-site scripting
XSS یک نوع قابلیت آسیب پذیری امنیت کامپوتر است. معمولاً در برنامه های کاربردی web بکار می رود. XSS، هکرها را قادر می سازد تا صفحات وب را از طریق تزریق اسکریبت سمت client هک کنند.

دلیل به وجود آمدن این آسیب پذیری عدم اعتبارسنجی ورودی‌های کاربر می‏ باشد، و مهاجم می تواند با تزریق اسکریپت‌های مخرب در سایت از این آسیب پذیری سو استفاده کند.

فرض کنید، فرم زیر را در یک فایل بنام "test_form.php" داریم:

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

حالا اگر یک کاربر در آدرس بار مرورگرش "http://www.example.com/test_form.php" را وارد کند، کد بالا بصورت زیر ترجمه خواهد شد:

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

خوب تا اینجا همه چیز خوب است.

اما درنظر بگیرید که کاربری URL زیر را در آدرس بار وارد کند:

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>

دومین URL، باعث اضافه شدن تگ <script> و یک دستور alert در بین کدهای ما شده است. و زمانی که صفحه لود می شود، کد JavaScript اجرا می شود (کاربر یک جعبه پیغام خواهد دید). این فقط یک مثال ساده و بی ضرر است که نحوه هک کردن متغییر PHP_SELF را نشان می دهد.

توجه داشته باشید که هر کد JavaScript دیگری را می توان در تگ <script> قرار داد...! یک هکر می تواند کاربر را به یک فایل دیگر روی سروری دیگر redirect کند، و از طریق آن فایل، اطلاعات کاربر را ذخیره کند.


نحوه مقابله با هک از طریق"PHP_SELF"

Wiki

با استفاده از تابع ()htmlspecialchars، می توان با هک از طریق "PHP_SELF" مقابله نمود.

کد آن شبیه زیر است:

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

تابع ()htmlspecialchars، کاراکترهای خاص را به HTML entity تبدیل می کند. حالا اگر کاربر بخواهد از متغییر "PHP_SELF" سوء استفاده کند، با نتیجه زیر روبرو خواهد شد:

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

و از این طریق هیچ آسیبی وارد نخواهد شد...!


اعتبارسنجی داده های فرم با PHP

Wiki

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

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

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

در اینصورت اسکریپت بالا اجرا نخواهد شد، چونکه کاراکترهای خاص در متن بالا به HTML entity معادلاشان تبدیل شده اند:

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

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

همچنین ما دو کار دیگر را هنگام ارسال داده ها به سرور انجام می دهیم:

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

گام بعدی، ایجاد یک تابع، برای انجام تمام کارهای بالاست (بجای اینکه کدهای مربوط به این قسمت را بارها و بارها بنویسیم، مناسب تر است که از یک تابع استفاده کنیم)

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

حالا ما می توانیم به ازای هر متغییر POST_$ مقدار آنرا با تابع ()test_input چک کنیم و کد آن شبیه زیر است:

مثال (اعتبارسنجی فرم در PHP)

<!DOCTYPE HTML>
<html>
<head>
<style>
  span{min-width: 200px;float: right;}
</style>

</head>
<body style="direction:rtl;">

<?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;
}
?>


<h2>مثال اعتبارسنجی فرم ها در PHP</h2>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<div><span>نام:</span><input type="text" name="name"></div>
<div><span>ایمیل:</span><input type="text" name="email"></div>
<div><span>وب سایت:</span><input type="text" name="website"></div>
<div><span>توضیحات:</span><textarea name="comment" rows="5" cols="40"></textarea>
</div>
<div><span>جنسیت:</span>
<input type="radio" name="gender" value="female">زن
<input type="radio" name="gender" value="male">مرد
</div>
</div><input type="submit" name="submit" value="ارسال اطلاعات"></div>
</form>

<?php
if (isset($name) || isset($email) || isset($gender) || isset($comment) || isset($website))
 {
  echo "<br /><h2>خروجی کدتان</h2>";
  echo "نام :$name";
  echo "<br />";
  echo "ایمیل: $email";
  echo "<br />";
  echo "وب سایت: $website";
  echo "<br />";
  echo "توضیحات: $comment";
  echo "<br />";
  echo "جنسیت: $gender";
 }
?>


</body>
</html>

خروجی کد بالا:

مثال اعتبارسنجی فرم ها در PHP

نام:
ایمیل:
وب سایت:
توضیحات:
جنسیت: زن مرد
 

توجه داشته باشید که در ابتدای اسکریپت، با استفاده از متغییر "REQUEST_METHOD" نحوه ارسال داده های فرم را چک می کنیم. اگر نحوه ی ارسال داده های فرم، از طریق متد "POST" است، اطلاعات فرم پردازش خواهد شد وگرنه با یک صفحه خالی روبرو خواهیم شد. 

توجه: برای بار اول که کاربر درخواست مشاهده فایل مثال بالا را به سرور ارسال می کند، بدلیل اینکه متد پیش فرض برای مشاهده صفحات از نوع get است، بنابراین شرط "$_SERVER["REQUEST_METHOD"] == "POST درست نخواهد بود و دستورات داخل شرط اجرا نخواهد شد. اما بعد از اینکه کاربر اطلاعات فرم را پر کرده و روی دکمه ارسال (submit) کلیک کرد، چون ویژگی method فرم را با مقدار "post"  تنظیم کرده ایم، شرط ذکر شده درست خواهد بود و دستورات داخل آن اجرا خواهد شد.

اما در مثال بالا، تمام فیلدهای ورودی اختیاری است. حتی اگر کاربر هیچ کدام از فیلدها را پر نکند، اسکریپت بالا باز هم کار خواهد کرد.

در بیاموز بعدی برای فیلدهای الزامی، یک پیغام مناسب نمایش خواهیم داد.


برای مشاهده فیلم ها و آموزش های پروژه محور برنامه نویسی PHP کلیک کنید.

READ MORE