تالار گفتمان nCIS.ir

نسخه‌ی کامل: csrf token
شما در حال مشاهده نسخه آرشیو هستید. برای مشاهده نسخه کامل کلیک کنید.
ایا این امنه؟
من laravel رو نگاه کردم فقط از random string استفاده کرده بود.
md5(uniqid(mt_rand(0, mt_getrandmax()), true));
منظورتون چیه که امنه؟ اگر از این لحاظ که آیا به اندازه کافی رندوم هست، بله نسبتا خوبه و برای اکثر کارها جوابگو هستش ولی اگر رندوم واقعی میخواین بگین تا کد eshphilen رو پیدا کنم بهتون بدم یا اگر خودش تاپیک رو دید بده
واقعاً لازم نیست اینقدر حساس باشین. برای اکثر کاربردها mt_rand و unique_id کافیه و حتی زیادی هم هست. همون روش لاراول هم در اکثر سناریوها کفایت میکنه.
(02-07-1394، 11:42 ق.ظ)n0o0b_sina نوشته: [ -> ]ایا این امنه؟
من laravel رو نگاه کردم فقط از random string استفاده کرده بود.
md5(uniqid(mt_rand(0, mt_getrandmax()), true));
اگر برای کاربردهای رمزنگاری حرفه ای بخواد استفاده بشه بقدر کافی امن نیست.
مثلا میخواید با AES-128 رمز کنید و بیاید یک کلید رندوم با این تابع تولید کنید، قطعا از نظر هیچ متخصص رمزنگاری درست و حسابی امن نیست؛ در این شکلی ندارم چون قبلا راجع بهش تحقیق کردم حتی سورس کد PHP رو خوندم و دیدم که uniqid داستانش چیه از چه منابعی برای تولید اعداد تصادفی استفاده میکنه، و در نهایت به نتیجهء روشنی رسیدم.

حالا میمونه بحث بقیهء کاربردها! اونجا خب بحث داره باید فکر کرد محاسبه کرد نکات مختلف رو در نظر گرفت. همین الان من حضور ذهن ندارم با اطمینان نمیتونم بگم برای چه کاربردی امن هست برای چه کاربردی نیست. چرا؟ چون به پارامترها و نکاتی میتونه بستگی داشته باشه که بعضا موردی هم هستن. ولی مثلا شما یه توکن امنیتی برای فرمها میخواید تولید کنید، یا یک کلید برای فعال سازی ایمیل؛ خب برای اینطور کاربردها بنظرم عموما نباید مشکلی داشته باشه. همینطور خیلی از رشته های رندوم دیگر مورد استفاده در برنامه های وب. احتمالا اکثریتشون همین سطح امنیت براشون کفایت کنه.

ولی بنده بعنوان یک آدم مطلع گفتم اصولا چرا باید چند تابع رندوم داشته باشیم با سطوح مختلف امنیت، که بعد آدم بخواد هر مورد فکر کنه بررسی کنه تصمیم بگیره و ریسک خطا و غفلت هم این وسط همیشه ممکنه ولو به میزان کمی وجود داشته باشه. پس اومدم یک تابع رندوم امنیتی درست کردم، و بعد برای تمام رشته های رندومی که لازم دارم و امنیت برنامه به امنیت اونا وابسته است از همون استفاده میکنم. دیگه روزهء شک دار نمیگیرم مغز خودم رو خسته نمیکنم وقت و انرژی اضافی تلف نمیکنم! میگن کار از محکم کاری هم عیب نمیکنه حالا بذار خیلی جاها هم امنیتش بیشتر از حد نیاز باشه، مشکلی پیش نمیاد که! معمولا هم این رشته های رندوم فقط تعداد محدودی و با فواصل زمانی تولید میشن، که در نتیجه حتی اگر تابع رندوم ما از نظر پردازشی سنگین باشه، بعید میدونم در بیشتر برنامه ها و سایت ها مشکل جدی ایجاد کنه. مثلا شما در هر جلسهء کاربر یکی دوتا توکن امنیتی که بیشتر تولید نمیکنید، یا مثلا برای کوکی لاگین و غیره.


اینم نتیجهء کارم: http://hamidreza-mz.tk/?p=649

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

برای کاربردهایی که امنیتی نیستن، میتونید از توابع معمولی مثل mt_rand و uniqid استفاده کنید. فرض مثلا بصورت رندوم یک رنگی یک مکان دشمنی چیزی رو توی یک بازی این چیزی تولید میکنید یا با هر بار رفرش صفحه، تبلیغاتی رو از بین چندین گزینه انتخاب کرده و نمایش میدید، از اینطور چیزها خلاصه، که اهمیت امنیتی ندارن کاربر و هکر نمیخواد ازشون سوء استفده کنه. فکر کنید موردهای بیشتری میشه مثال زد.

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

اما از اون طرف باوجود این حرفا امنیت کلا مقوله ای هست که اغلب دست کم گرفته میشه و تا وقتی گندش درنیامده درموردش بدون دلیل خوشبین هستن و فکر میکنن چون مشکلی دیده هکی رخ نداده نمیشه پس مشکلی وجود نداره و سطح امنیت برنامه کافیه. این بخاطر اینه که امنیت در سطح تست و کاربری عادی برنامه نویسی معمولا نمودی نداره و دیده نمیشه و ضعف ها و حفره ها تا زمانیکه عملا توسط یک هکر مورد سوء استفاده واقع نشدن، دیده نمیشن، چون برخلاف باگهای معمولی خللی در اجرای عادی برنامه ایجاد نمیکنن. برنامه ای که چندین سال کار کرده کسی هکش نکرده، دلیل نمیشه امن باشه! افرادی هستن که سوادش رو دارن توان و امکاناتش رو داره که هک کنن، ولی خب این افراد سراغ برنامه و سایت شما نیامدن مثلا به دلیل اینکه تعدادشون کمه و کارهای مهمتری دارن انگیزه و دلیل ندارن این همه سواد و توان رو صرف کارهای پیش پا افتاده و مبتذل و کم بازده بکنن.

یه وقتی یه مقاله ای خوندم که طرف دقیقا از یک ضعفی در همین توابع رندوم (فکر کنم mt_rand) پی برده بود و استفاده کرده بود و فوری اکسپلویتش رو هم یک نفر نوشته بوده و تست کرده بود توی نت هم گذاشته بود که نمیدونم همزمان اگر روی سایت فلان نرم افزار (مثلا phpbb) باشه و شما توی برنامتون از mt_rand استفاده کرده باشید میامد و ترفندی میزد که با ترکیب ساختار و اطلاعاتی که از اینا به روشی درمیاورد، رشته های رندوم شما رو پیشبینی میکرد. اون طرفی که این ضعف رو از نظر تئوریک شناسایی کرده و شرح داده بود، سواد و توان ذهنی تخصصی بالایی داشت طبیعتا، بعدی هم که اکسپلویت رو بر اساس کار تئوریک طرف اول نوشته بوده سوادش حداقل اینقدر میرسیده که اون توضیحات رو درک کنه و عملا ازشون سوء استفاده کنه، ولی لزوما سواد و تخصص این افراد با هم یکسان نیست. هرکدام در یک سطح و تخصص ها و علاقمندی های خاص خودشون کار میکنن. معمولا همینطوریه از بالا میاد پایین. مثلا دانشمندان تئوریک تئوری های بنیادین رو کشف میکنن، بعد افراد که یه چیزی بین دانشمند و مهندس هستن (یا مهندسان خیلی باهوش و توانا) میان و این تئوری ها رو میخونن درک میکنن و اولین پیاده سازیها رو درست میکنن، بعد از اون هم میبینی که از روی اون پیاده سازیهای اولیه خیلی های دیگه متوجه میشن یاد میگیرن روش ساختن و استفاده رو، یا صرفا clone میکنن و نسخه های تغییر یافته درست میکنن و اینطور کارها که لزوما نیازی به سواد بالایی که اون نخستین افراد داشتن نداره. آخر این زنجیره هم که script kiddie های عزیز نشستن تا لقمه های آماده رو بگیرن  Smile

البته اون ضعف در تابع mt_rand هرچی الان دیگه طبیعتا برطرف شده، ولی موضوع اینه که بروز اینطور ضعف ها در توابع رندومی که برای کاربردهای امنیتی نیستن طبیعتا همیشه احتمالش بیشتره تا توابعی که با آگاهی و سواد و تخصص، برای کاربردهای امنیتی نوشته شدن. طرفی که الگوریتم مورد استفاده در mt_rand رو طراحی کرده، و اونی که پیاده سازیش میکنه، هردو افرادی هستن که لزوما تخصصی در امنیت و رمزنگاری ندارن و این تابع رو هم برای کاربردهای امنیتی درست نکردن، بنابراین هیچ مسئولیت و تضمینی در حال و آینده هم ندارن و هیچ وسواس و هدفی در این ارتباط ندارن که این تابع سطح خاصی از امنیت رو دارا باشه!

ضمنا اصل فقط خود توابع رندوم هستن اینکه چه الگوریتمی دارن و آنتروپی اونا از چه منابعی چطوری تامین میشه؛ در کل یعنی اینکه آیا از نظر تخصیی رسما جزو توابع رندوم امنیتی هستن یا خیر! بقیهء ماجرا و اینکه مثلا بیاید صدتا md5 و sha256 بذارید و پشتک وارو بزنید، تاثیر چندانی در امنیت اصولی بدست آمده نداره! چرا؟ چون در امنیت حرفه ای، تقریبا همیشه باید فرض کرد که دشمن هم از الگوریتم مورد استفادهء شما کاملا اطلاع داره. اگر بنا رو بر فرض پنهان بودن و پنهان ماندن الگوریتم بذارید، میشه «امنیت از طریق تیرگی».
آخرش بعد از این همه مقاله حتما هنوز در ابهام و حیرت موندید که بالاخره چی شد حرف و نتیجهء آخر چیه باید چکار کنید  Big Grin

باید بگم خب بنده بعنوان یک متخصص و علاقمند، نشر دانش کردم مقالهء علمی دادم که عین علم و اصولش در بالاترین سطحی که بلدم میشناسم رو شرح داده روشن کرده.

ولی اول و آخرش گفتم که این بحث ها در این سطح مال 99% آدمها نیست برای 99% برنامه ها هم مطرح نیست. هرچند بنظرم کسی بخاطر استفاده از اونا شما رو سرزنش نمیکنه حداقل! اگر خواستید از اون تابع که بنده گذاشتم میتونید استفاده کنید، ولی برای افراد معمولی همون داستان و تابع مختصر هم کافیه با در نظر گرفتن جوانب مختلف دیگه!
آهان یه نکتهء مهم که یادم رفت بگم!
شما میتونید یه کاری بکنید که امنیت توابع رندوم حتی از نوع ضعیف رو خیلی بالاتر ببره.
اون کار استفاده از یک pepper هست.
pepper یک رشتهء رندومه که با عملیات دیگه ترکیب میشه. این رشتهء رندوم رو معمولا با دست ست میکنن و میتونید توی کد برنامه hardcode اش کنید. هرچند اگر جای امن تری باشه اصولی تره، ولی احتمالا بازم حکایت آدمهای معمولی و برنامه های معمولی هست و اینکه این همه محکم کاری و هزینه واسه درب خونه ای که پنجره هاش براحتی شکسته میشه چندان دلیل معقولی نداره!

مثلا همین کدی که گذاشتید رو من بهش یک pepper اضافه میکنم:

$pepper='kdlpfiia*%^hdjnHH0A@';
md5($pepper.uniqid(mt_rand(0, mt_getrandmax()), true));

الان بنظرتون هکر وقتی مقدار pepper رو نمیدونه، چکار میتونه بکنه بیچاره؟!
البته pepper جای توابع رندوم امنیتی رو نمیگیره، ولی امنیت رو خیلی بالاتر میبره.
در تابع رندوم امنیتی که بنده نوشتم از pepper هم استفاده کردم! یعنی دیگه کم و کسر نداره.
ضمنا pepper در بحث هش پسورد هم به همین شکل و به دلایل مشابهی کاربرد داره و اصلا اسمش رو من از اونجا گرفتم؛ شاید در این کاربرد رندوم بعنوان اسم رسمی درست نباشه بهش بگیم pepper.

ضمنا حتما دقت میفرمایید که اگر pepper رو در هر مورد از نصب برنامه تغییر ندیم، طبیعتا امنیت افزودهء چندانی ایجاد نمیکنه، چون فرض بر اینه که هکر الگوریتم رو میدونه و کد برنامه رو داره. مثلا من در پروژهء رجیستر و لاگین خودم pepper با مقدار اولیه ای که hardcode کردم دارم، ولی از نسخهء اول برنامه دیگه هیچوقت اون رو تغییر ندادم و فکر هم نمیکنم حتی وقتی برنامه رو جایی نصب کنم هم این کار رو براحتی انجام بدم! یخورده تنبلی ایناس دیگه Big Grin
طبیعتا هکر ممکنه حدس بزنه و تست کنه که آیا من در برنامم pepper رو از مقدار پیشفرضی که توی سورس کدهایی که در github در دسترس همه هست تغییر دادم یا نه. البته از اونور چون امنیت تابع رندوم من همینطوریش هم خیلی بالاست، فکر نمیکنم کسی دنبال این فکر هم باشه و اگر هم باشه بازم چندان فرقی نمیکنه و به نتیجه نمیرسه!
البته در بحث هش pepper مهمتر هست که تغییر داده بشه و به یک مقدار جدید ست بشه، چون در هش ما با پسوردهای کاربران سر و کار داریم که آنتروپی کمی دارن، نه رشته های رندوم تولید شده توسط توابع رندوم امنیتی گردن کلفت!
پس این از نظر امنیتی خیلی مفید محسوب میشه که pepper رو موقع نصب برنامه تغییر بدیم، ولی کمتر کسی این کار رو میکنه و حتی خود منم هیچوقت تاحالا این کار رو نکردم! مثلا در نصب وردپرس هم یک چنین رشته های رندومی رو شاید توی فایل کانفیگ دیده باشید که درواقع کم و بیش همین داستانه، ولی بیشتر افراد اصلا نمیدونن اونا چی هستن چه کاربردی دارن، و حتی یکی مثل من که میدونه هم به خودش زحمت ست کردن اونا رو نمیده. البته یک دلیل این بی میلی اینه که با تغییر این رشته ها یکسری پیچیدگی های دیگه معمولا در نگهداری سیستم پیش میاد (مثلا هش پسوردهای کاربران در دیتابیس به این pepper وابسته است که اگر برنامه رو دوباره نصب کنید و pepper رو به همون مقداری که زمان تولید شدن هش ها بوده ست نکنید اونوقت امکان لاگین کاربران از بین میره و همهء پسوردها باید ریست بشن).
بهرحال در درجهء اول این مهمه که pepper از مقدار پیشفرض که در کدهای منبع در دسترس دیگران بوده تغییر داده بشه. در درجهء بعد هم حتی از هر سایت به سایت که نصب میکنید باید pepper رو تغییر بدید.