PDA

View Full Version : آموزش: ایجاد TOKEN برای فرم ها و امنیت آن !



siavashsay
شنبه 14 بهمن 1391, 00:11 صبح
دوستان میدونم این تاپیک شاید برای بعضی ها تکرار باشه اما برای خیلی ها هم نه !
توی این تاپیک قصد دارم به صورت خیلی ساده ایجاد TOKEN KEY رو آموزش بدم !
--
موارد استفاده :
- جلوگیری از حملات CSRF
- جلوگیری از ارسال مجدد مقادیر POST در زمان Refresh صفحه !
و ...
---
نحوه استفاده :
===
در ابتدا یک فرم خیلی ساده رو براتون میذارم که یک فیلد داره و بعد از Submit مقدار اون فیلد چاپ میشه !

<?php
session_start();
if(isset($_POST['submit'],$_POST['text'],$_SESSION['token_key'],$_POST['token_key'])
&& $_SESSION['token_key']==$_POST['token_key'])
{
echo $_POST['text'];
}
$token_key=md5(time());
$_SESSION['token_key']=$token_key;
?>
<form id="form1" name="form1" method="post" action="">
<p>
<label for="text"></label>
<input type="text" name="text" id="text" />
</p>
<p>
<input type="submit" name="submit" id="submit" value="Submit" />
<input name="token_key" type="hidden" id="token_key" value="<?php echo $token_key;?>" />
</p>
</form>
خوب !
در ابتدا قبل از توضیح بهتره که یک بار فرم رو اجرا - فیلد رو پر کنید و submit رو بزنید!
میبینید که مقدار فیلد چاپ میشه !
حالا صفحه رو Refresh کنید !
میبینید که دیگه خبری از چاپ شدن فیلد نیست !
====
توضیح :
====
در ابتدا ما باید برای فرم مورد نظر یک Hidden Field درست کنیم و مقدار اون رو token_key ( البته اختیاری هست ) بگذاریم !
بعد باید یک کد رندم درست کنیم که مقدار اون رو در token_key بریزیم !

$token_key=md5(time());
البته بنده اینجا از یک md5 ساده استفاده کردم ! اما شما میتونید یک کد پیچیده تر هم درست کنید که حدس زدن اون سخت باشه !
این کد رندم با اجرای هربار صفحه تولید میشه !
دقت کنید که تولید کد رندم و مقدار دهی اون رو در آخرین خط کد php خودتون بنویسید ! نه در داخل if و یا هر چیز دیگه ای !
حالا باید در موقع submit شدن فرم این مقدار رو چک کنیم که ببینیم درست هست یا نه !
اما موضوع اینجاست که چطوری و با چی اون رو چک کنیم ؟!
اینجاس که میگیم با مقدار یک متغیر SESSION

$_SESSION['token_key']
بله !
در ابتدا ما 2 تا متغیر درست میکنیم !
1- یک متغیر POST که همون Hidden Field هست
2- یک متغیر SESSION
و بعد مقدار کد رندم رو توی اونها میریزیم !
دلیل ایجاد این 2 تا هم اینه که Session ها در موقع تولید باقی میمونن تا زمانی که شما اونها رو از بین ببرید یا مقدار جدیدی بهشون بدید ! برای همین در اینجا در زمان اجرای صفحه ما مقدار Session رو مجدد عوض میکنیم و در هنگام Refresh مجدد صفحه مقدار اون Session عوض شده اما مقدار اون Hidden Field که درست کردیم نه !
مقدار اون Hidden Field موقعی عوض میشه که کاربر به صورت دستی فرم رو Submit کرده باشه نه اینکه صفحه رو Refresh کنه !
علت اینکه صفحه در زمان Submit خروجی داره اما در زمان Refresh نه همین هست !
چون در زمان Submit صفحه مقادیر Session و Hidden Field رو یکسان میکنه اما در زمان Refresh مقدار Session عوض میشه اما مقدار Hidden Filed خیر !
برای همین در زمان Submit فرم چک میکنیم که اگر این 2 تا برابر بودند عملیات اجرا و در غیر اینصورت خطا :)
در این کد :

if(isset($_POST['submit'],$_POST['text'],$_SESSION['token_key'],$_POST['token_key'])
&& $_SESSION['token_key']==$_POST['token_key'])
{
خیلی طولانی شد اما خواستم توضیحی بدم که دوستان متوجه بشن !
چون خودم سر این موضوع خیلی دردسر کشیدم!
امیدوارم موثر بوده باشه !
موفق باشید

$ M 3 H R D A D $
شنبه 14 بهمن 1391, 01:14 صبح
جالب بود توکن و که دیدم گفتم شاید همون کد امنیتی باشه
خوب فرم دوباره رفرش نشه ! مثلا خرید یک محصول یا حذف داده
نمیدونم درست متوجه شدم یا نه میشه بگی کجا کاربرد داره؟

h00manb
شنبه 14 بهمن 1391, 06:24 صبح
سلام
اگر دونفر تقریبا همزمان فرم را باز کنند سشن اولی توسط دومی تغییر میکنه و اولی هیچ وقت نمیتوانه فرم را ثبت کنه
درسته؟

eshpilen
شنبه 14 بهمن 1391, 08:35 صبح
$token_key=md5(time());
توکن شما بیش از حد ضعیفه.
زمان تقریبی درخواست رو هکر میتونه بدست بیاره.
بعد میتونه چند آزمون و خطا بکنه، که احتمالش زیاده یکی از اونا جواب بده.
یعنی میتونه چندین درخواست رو بفرسته و با زمان تقریبی درخواست مثبت منفی چند ثانیه، هش رو محاسبه و ارسال کنه.

siavashsay
شنبه 14 بهمن 1391, 11:05 صبح
خوب فرم دوباره رفرش نشه ! مثلا خرید یک محصول یا حذف داده
نمیدونم درست متوجه شدم یا نه میشه بگی کجا کاربرد داره؟ این کار حذف کردن داده ها نیست ! مقادیر POST در حافظه صفحه میمونن ! اما بحث اینه که اون token اجازه refresh رو نمیده ! یعنی اینجوری به زبون ساده میگه که :
در صورتی عملیات رو درست انجام بده که کاربر ( واقعی ) اون فرم رو Submit کرده باشه !
و اینکارو هم با اضافه کردن یک کد امنیتی انجام میده !
دقیقا مثل همون Catpcha اما Catpcha به صورت دستی از کاربر میخواد که کد رو وارد کنه اما token یه مقدار این کارو friendly کرده و اتومات اینکارو خودش انجام میده !
بهتره از token برای تمامی فرم های مهم سایت استفاده شه ! مخصوصا فرم هایی که با دیتابیس رابطه مستقیم دارند !
برای مثال : Login - Register - Buy Forms - Order Forms - Send Email Forms
اگر به سایتهای معروف برید ( البته جدیدا در همه سایتها رعایت میشه ) و با Firebug کد فرم اون صفحه رو ببینید متوجه میشید که یک Hidden Field داره که اکثرا هم به نام token - token key و یا از همین قبیل اسامی هست !

اگر دونفر تقریبا همزمان فرم را باز کنند سشن اولی توسط دومی تغییر میکنه و اولی هیچ وقت نمیتوانه فرم را ثبت کنه
نمیدونم منظورتون از 2 نفر چی هست !
اگر منطورتون 2 نفر از 2 تا کامپیوتر جدا هست باید بگم خیر ! چون Session ها برای هر کاربر و کلاینت و هر سیستم به صورت جدا فراخوانی میشن !
اما اگر منظورتون این هست که 2 نفر بروی یک کامپیوتر این کارو انجام بدن باید بگم بهتر بود میگفتید که یک نفر اون صفحه رو 2 بار مثلا توی 2 تا Tab باز کنه !
در اینجا باید بگم آخرین Tab ی که باز میشه حاوی اطلاعات درست هست !

توکن شما بیش از حد ضعیفه.eshpilen جان میدونم !
من همون اول گفتم نمیخوام پیچیده باشه و حتی توضیح هم دادم که بچه ها میتونن از یک الگوریتم بهتر استفاده کنن ! در هر صورت مرسی :)

colors
شنبه 14 بهمن 1391, 11:14 صبح
سلام
اگر دونفر تقریبا همزمان فرم را باز کنند سشن اولی توسط دومی تغییر میکنه و اولی هیچ وقت نمیتوانه فرم را ثبت کنه
درسته؟

نه دوست عزیز ربطی نداره، برای هر کدام از کاربران سشن متفاوتی ساخته میشه و فقط برای اون شخص قابل دسترسه

Jason.Bourne
پنج شنبه 09 خرداد 1392, 23:51 عصر
نه دوست عزیز ربطی نداره، برای هر کدام از کاربران سشن متفاوتی ساخته میشه و فقط برای اون شخص قابل دسترسه


برای اینکه کاربر بتواند از روی یک کامپیوتر 2 صفحه مانند به هم را باز کنم باید چکار کرد (مثلا در 2 تا تب یک صفحه را باز کند)؟

ayub_coder
جمعه 10 خرداد 1392, 00:20 صبح
کاش قبلش یه توضیحی میدادی که اصلا توکن چیه! طرز کارش چطوریه . بعد میرفتی سراغ کد.

aref taker
چهارشنبه 27 خرداد 1394, 21:03 عصر
دوستان الان رمز نگاری md5 قدیمی شده و کاربرد نداره؟؟ اگه این طوره چرا خود این انجمن از md5 استفاده کرده (واسه لاگین شدن)؟

fatima-php
پنج شنبه 28 خرداد 1394, 01:06 صبح
میگم چرا تاپیک زیرخاکی رو بالا میارین؟ تاپیک جدا بزنین بهتره. MD5 هم کاملاً از دور خارج نشده. فقط بهتره توی موارد خیلی حساس ازش استفاده نشه چون جایگزینهای خیلی بهتری براش اومده. اما بعضی جاها که خیلی حساسیت وجود نداره مثل توکن و... مشکلی نداره ازش استفاده بشه. این انجمن هم واسه لاگین شدن از MD5 استفاده نمیکنه بلکه فقط توکن رو با MD5 میسازه که تازه اونم اگه اشتباه نکنم، چندبار رمزگذاری میشه و Salt و Pepper قاطیش میکنه.

vahid03
سه شنبه 04 خرداد 1400, 00:07 صبح
سلام میدونم تاپیک قدیمیه ولی در مورد امنیت این روش سوالی دارم من این روشو دارم استفاده میکنم در فرم هام از نظر امنیتی مشکلی نداره ؟ اگه جایگزین بهتر از این هم هست لطفا بگید.