PDA

View Full Version : یک روش ساده برای جلوگیری از XSRF



eshpilen
یک شنبه 24 دی 1391, 09:56 صبح
خب ما اینو ابتدای هر صفحه میذاریم (میتونه توی یک فایل باشه که در تمام صفحات اینکلود میشه):


if(!isset($_COOKIE['reg8log_antixsrf_token'])) {
require_once $index_dir.'include/func/func_random.php';
$antixsrf_token=random_string(22);
setcookie('reg8log_antixsrf_token', $antixsrf_token, 0, '/', null, $https, true);
$_COOKIE['reg8log_antixsrf_token']=$antixsrf_token;
}
else $_COOKIE['reg8log_antixsrf_token']=htmlspecialchars($_COOKIE['reg8log_antixsrf_token'], ENT_QUOTES, 'UTF-8');

توضیح اینکه تابع random_string یک تابع رندوم امن هست (سورسش توی فایل دیگری هست که اینکلود شده) و ما در اینجا با استفاده ازش یک رشتهء رندوم با طول 22 کاراکتر متشکل از حروف بزرگ و کوچک و اعداد تولید کردیم.

اوه راستی متغییر https هم اگر کانکشن ارتباط از نوع HTTPS/SSL باشه مقدار true داره، وگرنه false.
حالا این جزییاتش بحث جداگانه هست و به کلیت روش و موضوع ما ربط مستقیم نداره؛ پس بخاطر کوتاهتر و ساده تر شدن این مطلب آموزشی اونا رو دیگه وارد نکردم.

بعدش مثلا برای محافظت از فرمها (POST) در برابر XSRF باید اون reg8log_antixsrf_token رو در یک hidden input به فرم اضافه کنیم به این شکل:

echo '<input type="hidden" name="antixsrf_token" value="';
echo $_COOKIE['reg8log_antixsrf_token'];
echo '">';
برای محافظت از لینک ها (GET) هم به این شکل (بعنوان نمونه):

<a href="logout.php?antixsrf_token=<?php echo $_COOKIE['reg8log_antixsrf_token']; ?>">Log out</a>
بعدش تازه کد آشکارسازی XSRF مونده:

if(!empty($_POST)) {
if(!isset($_COOKIE['reg8log_antixsrf_token'], $_POST['antixsrf_token']) or $_COOKIE['reg8log_antixsrf_token']!==$_POST['antixsrf_token']) {
$failure_msg="<h3>XSRF prevention mechanism triggered!</h3>";
$no_specialchars=true;
require $index_dir.'include/page/page_failure.php';
exit;
}
}
else if(!isset($_COOKIE['reg8log_antixsrf_token'], $_GET['antixsrf_token']) or $_COOKIE['reg8log_antixsrf_token']!==$_GET['antixsrf_token']) {
$failure_msg="<h3>XSRF prevention mechanism triggered!</h3>";
$no_specialchars=true;
require $index_dir.'include/page/page_failure.php';
exit;
}
مثلا این قطعه کد رو توی یک فایل جداگانه به اسم code_prevent_xsrf.php میذاریم.

خب حالا وقتی فرمی سابمیت شده که باید در برابر XSRF محافظت بشه باید به این شکل عمل کنیم:


if(!empty($_POST)) require 'include/code_prevent_xsrf.php';
یعنی کد بالا رو مثلا در ابتدای صفحه ای که فرم بهش سابمیت میشه (action فرم) قرار میدیم.

برای لینکها هم که مشخصه.
مثلا من در صفحهء logout.php خودم در همون اوایلش (قبل از اینکه عملی مربوط به لاگ آوت کردن انجام بشه) این رو گذاشتم:

require 'include/code_prevent_xsrf.php';

اینا رو از پروژهء سیستم رجیستر و لاگین خودم کپی کردم. البته بعضی از جزییات مربوط به اون پروژه رو حذف کردم که ساده تر بشه.

حالا تازه این روشی که من با استفاده از کوکی پیاده کردم احتمالا ساده ترین روش جلوگیری از CSRF است (طبیعتا امنیتش هم درحد حداقل ضروریه). با این حال مشاهده میکنید که چند مرحله داره. واقعا امنیت یه چیز ساده ای نیست که بخوایم همش رو با دوتا توضیح و دو خط کد برای هر سطح سوادی آموزش بدیم. مثل اینکه ریاضیات پیشرفته رو نمیشه طوری توضیح داد که واسه یه بچه دبستانی قابل فهم بشه!! میشه؟ نه میشه جون تو؟
یعنی کسی که از این کدها و توضیحات نتونه متوجه بشه حکایت همون دانش آموز دبستانیه که حالا حالاها باید درس بخونه و یاد بگیره تا تازه پایهء لازم رو بدست بیاره واسه خوندن مقاطع بالاتر. استاده که نمیاد و اگر هم بخواد اصلا نمیتونه ریاضیات دبیرستان و دانشگاه رو در سطح دانش آموز دبستانی توضیح بده و اونم یاد بگیره! میشه؟
برای هرچیزی حداقلی از یه راهی و یه زمانی رو باید طی کنه بالاخره.

eshpilen
یک شنبه 24 دی 1391, 10:32 صبح
حالا همونطور که گفتم این یک روش بسیار ساده و حداقلیه که بنده بخاطر سرعت و راحتی توسعهء پروژم و اینکه نمیخواستم روی یک بخش محدودش خیلی معطل بشم از این روش استفاده کردم؛ خیلی ها ممکنه اعتقاد داشته باشن که این روش بیش از حد ضعیفه. منم توی فکرش بودم که شاید باید این روش رو با یک روش پیشرفته تر جایگزین کنم. مثلا یک روشی که توکن رو توی سشن ذخیره کنه، و مثلا توکن ها هم میتونن تاریخ انقضا داشته باشن، و هر فرم و صفحه ای یک توکن مختص به خودش داشته باشه؛ ولی خب اینا بنظر من یخورده زیادی پیچ در پیچ الکی میان! باید بیشتر تحلیل و تفکر کنم. هنوز منبعی نخوندم که سناریوهای ضعف روشهای ساده تر و میزان احتمال بروز اونا رو توضیح داده باشن.
اینی که من گذاشتم برای جلوگیری از XSRF هست در حد پایه و حداقل که بنظر من کفایت میکرده.
البته حداقل یک مزیت برای روش دیگری که در اون توکن در سشن ذخیره میشه سراغ دارم، ولی مزیتش برای XSRF نیست، بلکه برای جلوگیری از روبات هاست.
ببینید وقتی شما توکن رو در سشن ذخیره کنید، روباتی که میاد توی سایت و میخواد لینک یا فرمی رو بفرسته، اول نیاز داره تا اون صفحه یا فرم شما رو از سایت مثل یک مرورگر دریافت کنه تا یک توکن معتبر بدست بیاره تا بتونه بعد فرم یا لینک رو با اون توکن ارسال کنه، که احتمالا حداقل بعضی از روباتها این قابلیت رو ندارن؛ ضمنا این کار هزینهء کار روبات ها رو بالا میبره و سرعت کارش رو کم میکنه، چون به ازای هر ارسال موفق مجبورن دو عملیات دریافت و ارسال داشته باشن، و نه فقط یکی (ارسال).
اما بهرحال واقعیتش اینه که این قضیه به CSRF ربطی نداره و روبات یک قضیهء جداگانه هست برای خودش. واسه همین من روش خودم رو کافی دیدم برای هدف خودم که جلوگیری از XSRF بود. واسه روبات هم خب جاهایی که مهم بوده مکانیزمهای دیگری دارم مثل کپچا و محدودیت تعداد و غیره.
روش من که توکن رو در کوکی ذخیره میکنه این امکان رو به کلاینت میده که خودش هر توکنی رو که خواست ست کنه؛ این از نظر XSRF خطری نداره، چون ما با این سیستم میخوایم از کلاینت در برابر دیگران محافظت کنیم، و این حملهء مستقیمی به سایت نیست که کلاینت بتونه با جعل این توکن ازش سوء استفاده ای بکنه. ولی مثلا یک روبات اگر باشه، میتونه توکن رو خودش ست کنه و دیگه نیازی نداشته باشه مثلا برای سابمیت کردن هر بار فرم یک بار هم اون فرم رو از خود سایت دریافت کنه تا توکن معتبر بدست بیاره.
افتاد؟ :لبخند:
حالا من توضیح میدم باز میگن یه صفحه الکی نوشتی. خب عزیزم با این همه توضیح متوجه نمیشی، دیگه چکار کنم برات؟ پشتک وارو بزنم؟!
در امنیت باید اینقدر آماده باشی که از یه اشاره سرنخ رو بگیری و تا تهش رو بکشی بیرون!

colors
یک شنبه 24 دی 1391, 10:50 صبح
واقعا امنیت یه چیز ساده ای نیست که بخوایم همش رو با دوتا توضیح و دو خط کد برای هر سطح سوادی آموزش بدیم. مثل اینکه ریاضیات پیشرفته رو نمیشه طوری توضیح داد که واسه یه بچه دبستانی قابل فهم بشه!! میشه؟ نه میشه جون تو؟
باشه بابا زیاد عصبانی نشو، چیزی نشده که، شده؟ نه نشده...

rezaonline.net
دوشنبه 25 دی 1391, 07:59 صبح
XSRF احتمالاً نام دیگه CSRF باشه ، درسته ؟

روش ساده تر هم اینه یوزرایجنت و آی پی کاربر رو بصورت هش اضافه کنی به فرم ها بعنوان token .
دیگه رندم رو فکر نکنم نیازی باشه ، به نظرت نیاز هست ؟

eshpilen
دوشنبه 25 دی 1391, 08:56 صبح
XSRF احتمالاً نام دیگه CSRF باشه ، درسته ؟
بله. بخاطر همین دو مدل رو نوشتم که مشخص بشه.


روش ساده تر هم اینه یوزرایجنت و آی پی کاربر رو بصورت هش اضافه کنی به فرم ها بعنوان token .
دیگه رندم رو فکر نکنم نیازی باشه ، به نظرت نیاز هست ؟این روش اشتباه است.
چون اصولا در حملهء CSRF قربانی به سایت هکر مراجعه میکنه، بعد هکر در کد HTML/JS ای که به مرورگر قربانی میفرسته کدهای لازم برای CSRF رو درج میکنه.
خب حالا وقتی قربانی میره سایت هکر، طبیعتا User agent و IP اون رو هم هکر میتونه به سادگی بدست بیاره و در کدهای CSRF وارد کنه.

rezaonline.net
دوشنبه 25 دی 1391, 15:18 عصر
ببخشید یادم رفت
دقیقا این

sha1($_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$_SERVER['SERVER_SOFTWARE']);

colors
دوشنبه 25 دی 1391, 16:03 عصر
ببخشید یادم رفت
دقیقا این

sha1($_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$_SERVER['SERVER_SOFTWARE']);
رضا حرفی که جناب eshpilen زدن، برای این موارد هم صدق میکنه دیگه!

خب حالا وقتی قربانی میره سایت هکر، طبیعتا User agent و IP اون رو هم هکر میتونه به سادگی بدست بیاره و در کدهای CSRF وارد کنه.

rezaonline.net
دوشنبه 25 دی 1391, 20:09 عصر
من میخوام csrf وابسته به کوکی نباشه تا از این
چون اصولا در حملهء CSRF قربانی به سایت هکر مراجعه میکنه، بعد هکر در کد HTML/JS ای که به مرورگر قربانی میفرسته کدهای لازم برای CSRF رو درج میکنه.
جلوگیری بشه !
پس باید پارامترها شامل اطلاعاتی مختص خود کاربر باشه + اطلاعاتی از خود سرور !
الان هکر
$_SERVER['SERVER_SOFTWARE'] نمیتونه به راحتی به دست بیاره اما شدنیه ، میشه یه سالت هم بهش اضافه کرد که برای هر وبسایت متفاوت باشه .

eshpilen
سه شنبه 26 دی 1391, 08:54 صبح
من میخوام csrf وابسته به کوکی نباشه تا از این
جلوگیری بشه !
یعنی چی؟!


پس باید پارامترها شامل اطلاعاتی مختص خود کاربر باشه + اطلاعاتی از خود سرور !
الان هکر
$_SERVER['SERVER_SOFTWARE'] نمیتونه به راحتی به دست بیاره اما شدنیه ، میشه یه سالت هم بهش اضافه کرد که برای هر وبسایت متفاوت باشه .
ایدهء سالت بد نیست انگار مخت کار میکنه :متفکر:
ولی بازم امنیتش کافی نیست بنظر بنده.
چون مثلا ممکنه IP هکر هم همون IP کاربر باشه، و میتونه بقیهء اطلاعات رو هم مثل کاربر ست کنه، یک درخواست به سرور هدف بده و ببینه هش تولید شده چیه، بعد این هش رو در حملهء CSRF به کاربر مورد نظر استفاده کنه.
حالا من به این فکر افتادم که شاید از این ایده های شما برای امن تر کردن سیستم خودم استفاده کنم. یعنی یجوری هر دو روش رو بصورت همزمان بکار ببرم. هم رشتهء رندوم، و هم IP که با یک سالت مختص سرور هش کنیم.
البته روش بنده هم از نظر تئوریک کاملا امنه، ولی اگر در مرورگر باگی باشه که به هکر اجازهء خوندن کوکی های سایت من رو بده (تاجاییکه میدونم از اینطور باگها تاحالا کم نبوده)، اونوقت میتونه توکن من رو هم بدست بیاره، و در این زمان روش و رشتهء امنیتی دوم که وابسته به IP کاربر و سالت سرور هست ممکنه بتونه جلوی حمله رو بگیره. البته IP کاربر رو که هکر میتونه بدست بیاره، ولی چون سالت سرور رو نداره نمیتونه هش مربوطه رو خودش مستقلا محاسبه کنه.
نیاز چندانی به دخالت دادن یوزرایجنت و اینها هم نیست؛ چون اینها رو هکر میتونه جعل کنه. تنها چیزی که نمیتونه جعل کنه IP ای است که ما از ‎$_SERVER['REMOTE_ADDR']‎ میگیریم. ولی اینم گفتم که نباید به تنهایی روش حساب کرد، چون در موارد متعددی یک IP میتونه توسط چند نفر یا عدهء زیادی بصورت همزمان/اشتراکی یا در زمانهای مختلف استفاده بشه.

Mohsen.
سه شنبه 26 دی 1391, 10:03 صبح
خیلی ببخشید.
من که این مطالبو خوندم هیچی سردرنیاوردم.
مطلب یا منبعی نیست در مورد امنیت PHP. و انواع خطرات مثل همین XSRF و چیزهای دیگه توضیح داده باشه که اصلا چی هستند؟

eshpilen
سه شنبه 26 دی 1391, 11:25 صبح
خیلی ببخشید.
من که این مطالبو خوندم هیچی سردرنیاوردم.
مطلب یا منبعی نیست در مورد امنیت PHP.

باید بسی سالها مطالعه همی کردن و هر سرنخی را به جد و جهد دنبال کردن تا به سرچشمهء دانایی همی رسیدن :لبخند:

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

در پایان باید بگم: کار هر کس نیست خرمن کوفتن ... گاو نر میخواهد و مرد کهن!

باید اول سعی کنی خودت هم مرد کهن بشی و هم گاو نر :قهقهه:

مشکل منبع نیست. فقط هم یک منبع جامع و کافی من شخصا ندیدم و گمان نمیکنم باشه.

مشکل آدمشه. آدمش از همه چیز مشکل تره. زور زیادی میخواد!


و انواع خطرات مثل همین XSRF و چیزهای دیگه توضیح داده باشه که اصلا چی هستند؟فرض کن شما یه سایتی داری (example.com) که کاربران توش عضو هستن.
فرض کن آدرسی که کاربران سایت شما با مراجعه بهش لاگ آوت میکنن اینه:

http://www.example.com/logout.php
فرض کن من (هکر) یه سایت دارم (hacker.com).
حالا من توی کد HTML صفحهء اول سایتم یک تگ تصویر میذارم به این شکل:

<img style="display: none" src="http://www.example.com/logout.php">
خب حالا کاربران سایت تو که وارد سایت من بشن، از سایت جنابعالی لاگ آوت میشن! به همین سادگی.
چون مرورگر اونها برای دریافت دیتای تصویر مربوط به این تگ img، یک درخواست به آدرس صفحهء لاگ آوت شما ارسال میکنه؛ در این درخواست کلیهء کوکی های (شامل کوکی سشن) سایت شما هم ارسال میشن. طبیعتا صفحهء لاگ آوت شما در پاسخ این درخواست، فرمان لاگ آوت شدن از سایت شما رو به مرورگر کاربر ارسال میکنه (دستور پاک کردن کوکی های احراز هویت سایت شما) و هر عملیاتی دیگری هم که در پشت صحنه (سمت سرور) لازم باشه (مثلا Destroy کردن سشن اون کاربر) رو هم بصورت طبیعی مثل درخواستهای دیگر انجام میده.

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

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

Mohsen.
سه شنبه 26 دی 1391, 11:34 صبح
خیلی ممنون از توضیحاتت. خودم هم اصلا دنبال منابع فارسی نیستم.
اما در مورده این حمله XSRF خب وقتی مثلا یک کاربر در سایت من لاگین میکنه من میام آی دی خودش رو در سشن اون ذخیره میکنم. و برای هر کاری هم که بخواد بکنه ابتدا میبینم سشن اون کاربر ثبت شده است یا نه.
اینجوری حل نمیشه؟

eshpilen
سه شنبه 26 دی 1391, 12:24 عصر
اینجوری حل نمیشه؟
نه اینطوری حل نمیشه.
اون درخواست CSRF که ارسال میشه در سمت سرور شما تفاوت واضحی با دریافتهای عادی نمیبینی درش (مثل اینکه کاربر خودش مستقیما اون آدرس رو در نوار آدرس مرورگر وارد کرده باشه). کوکی سشن کاربر هم مثل کوکی های دیگر همراه اون درخواست ارسال میشه و بنابراین شما یک سشن معتبر کاربر رو در سمت سرور مشاهده میکنید.
البته از روی HTTP_REFERER میشه متوجه تفاوت شد، ولی اینم باز بهترین راه اصولی نیست (دلیل اصلیش اینکه در HTTPS این هدر اصلا وجود نداره). راه بهترش همون توکن امنیتی برای تک تک فرم ها و لینک های مهمه.

engmmrj
سه شنبه 26 دی 1391, 12:44 عصر
من از این استفاده میکنم. این روش خوبه؟

<?php
session_start();
$rand=md5(rand(3242,324));
$token=$_SESSION['token']=$rand;
?>
<input type="hidden" value="<?php echo $token;?>" name="token" />
بعد تو صفحه بعد برسی می کنم

if($_SESSION['token']!=$_POST['token'])
{
exit;
}
به زودی برای هر session یه زمان انقضا میزارم
چطور ه؟خوبه؟روش امنی هست

eshpilen
سه شنبه 26 دی 1391, 12:53 عصر
من از این استفاده میکنم. این روش خوبه؟

<?php
session_start();
$rand=md5(rand(3242,324));
$token=$_SESSION['token']=$rand;
?>
<input type="hidden" value="<?php echo $token;?>" name="token" />
بعد تو صفحه بعد برسی می کنم

if($_SESSION['token']!=$_POST['token'])
{
exit;
}
به زودی برای هر session یه زمان انقضا میزارم
چطور ه؟خوبه؟روش امنی هست
کلیت یکی از روشهای متداول همینه.
ولی رشتهء رندومت ضعیفه.
یه رشتهء رندوم باید باشه که تعداد حالتهاش خیلی بیشتر باشه.
اگر بخوایم کاملا اصولی کار کنیم و به هیچ وجه روزهء شک دار نگیریم، من میگم یک رشتهء رندوم با طول 22 متشکل از حروف بزرگ و کوچک و اعداد که با یک تابع رندوم امنیتی تولید شده باشه. تابع رندوم امنیتی که میگم مثلا این: http://www.hamidreza-mz.tk/?p=649
البته احتمالا خیلی ضعیف تر از این هم کفایت بکنه، ولی بنده شخصا بعنوان یک کارشناس هیچوقت نمیام یک روشی رو که اثبات امنیتش کاملا روشن و محکم نیست تایید کنم. ترجیح میدم از امنیت درحد کامل و بدون شک و شبهه استفاده کنم.

زمان انقضا برای سشن هم فکر نمیکنم زیاد ربطی داشته باشه و مهم باشه در این مورد!
چرا یعنی چقدر؟

siavashsay
سه شنبه 26 دی 1391, 13:22 عصر
حالا دوستان هر کدوم راه خودشون رو برای ایجاد کد CSRF گفتن !
به هر حال بنده از این کد استفاده میکنم :


$ip=$_SERVER['REMOTE_ADDR'];
$software=$_SERVER['SERVER_SOFTWARE'];
$uagent=$_SERVER['HTTP_USER_AGENT'];
$rand=microtime();
$salt="mySaltValueKey";
$mix=$ip.$software.$uagent.$rand.$salt;
$token_key=sha1(md5($mix));

colors
سه شنبه 26 دی 1391, 13:34 عصر
من میگم یک رشتهء رندوم با طول 22 متشکل از حروف بزرگ و کوچک و اعداد که با یک تابع رندوم امنیتی تولید شده باشه.
راستی این قضیه 22 کاراکترت چیه که حتما هم تاکید میکنی 22 تا باشه. مثلا 55 چطوره؟

engmmrj
سه شنبه 26 دی 1391, 13:42 عصر
. تابع رندوم امنیتی که میگم مثلا این: http://www.hamidreza-mz.tk/?p=649
فک نکنم کسی بتونه اینو رمز نگاری کنه :گیج:
از کدوم تایع استفاده کنم؟
این تابع خوبه

andom_string(22, '123ABC');
؟

engmmrj
سه شنبه 26 دی 1391, 14:17 عصر
یه سوال درمورد htmlpurifier
کد زیر برای پاک سازی xss ها خوبه؟

include(dirname(__FILE__).'/htmlpurifier-4.4.0/HTMLPurifier.auto.php');

$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.TidyLevel', 'heavy');
$config->set('Core.Encoding', 'UTF-8');
$config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
$config->set('HTML.TargetBlank', true);
$config->set('HTML.Attr.Name.UseCDATA', true);
$config->set('HTML.Allowed', 'h1[class], h2[class], h3[class], img[class|alt|src], a[class|href|title|target|rel], p[class], div[class], span[class], br, hr, blockquote[class], ul[class], ol[class], li[class], table[class], tr[class], th[class], td[class]');
$config->set('Attr.AllowedClasses', array('c', 'j', 'l', 'r', 'pd9', 'mr9', 'r9', 'brdr', 'grn', 'ltr'));
$config->set('AutoFormat.RemoveEmpty', true);
$config->set('AutoFormat.Linkify', true);
$config->set('AutoFormat.RemoveSpansWithoutAttributes', true);
$config->set('Attr.DefaultImageAlt', '[image]');

$def = $config->getHTMLDefinition(true);
$def->addAttribute('a', 'target', 'Enum#_blank');
$def->addAttribute('a', 'rel', 'Enum#nofollow');

$purifier = new HTMLPurifier($config);

$yourText = $purifier->purify($yourText);

engmmrj
سه شنبه 26 دی 1391, 14:19 عصر
یا این

<?php



header("Content-type: text/plain; charset=utf-8");



$contents="<script>alert(1);</script><img src='t.jpg' onload='alert(2);'><form></form>";



require_once 'htmlpurifier-4.3.0/library/HTMLPurifier.auto.php';



$config = HTMLPurifier_Config::createDefault();

$config->set('Core.Encoding', 'UTF-8');

$config->set('HTML.Doctype', 'HTML 4.01 Transitional');

$purifier = new HTMLPurifier($config);



echo $purifier->purify($contents);



?>

eshpilen
سه شنبه 26 دی 1391, 15:02 عصر
راستی این قضیه 22 کاراکترت چیه که حتما هم تاکید میکنی 22 تا باشه. مثلا 55 چطوره؟
بخاطر اینکه در علم رمزنگاری مدرن، حداقل طول کلید امن برای رمزنگاری 128 بیت است.
یعنی این استاندارده.
چنین کلیدی 2 به توان 128 حالت داره.
حالا شما با ماشین حساب ویندوز/لینوکس بزن ببین یک رشتهء رندوم متشکل از حروف بزرگ و کوچک و اعداد (مجموعا 62 کاراکتر ممکن برای هر مکان) برای اینکه تعداد حالتهای ممکنش از 2 به توان 128 کمتر نباشه باید چند کاراکتر طول داشته باشه (تعداد حالتهای ممکن برابر 62 به توان طولش میشه).
البته با طول 22 کاراکتر ما مقداری بیش از 2 به توان 128 حالت خواهیم داشت، ولی چون با طول 21 کاراکتر از 2 به توان 128 کمتر میشد من مقدار بیشتر از بین اینها رو انتخاب کردم که خیالم راحت راحت باشه.

حالا البته این 2 به توان 128 خیلی قویه. یعنی مقدار امنیتش اونقدری هست که مثلا با کل ابررایانه های روی کرهء زمین هم نمیشه تا 20 سال آینده اون رو Brute-force کرد.
و البته که در بیشتر کاربردهای وب ما به چنین حدی از امنیت نیازی نداریم. چون اولا تمام سازمانهای امنیتی دنیا دنبال حمله به سایت ما از این طریق نیستن، دوما در وب معمولا تست آفلاین کلیدها ممکن نیست و محدودیت تعداد تست آنلاین در واحد زمان برای هکر وجود داره که نسبت به تست آفلاین خیلی محدودش میکنه.
یعنی مثلا شما میتونی یک کلید رمزنگاری رو بصورت آفلاین با نرخ حتی حدود 1 میلیارد یا بیشتر تست کلید بر ثانیه Brute-force کنی با استفاده از قدرت پردازشی یک کارت گرافیک مدرن، ولی در وب و از طریق اینترنت حتی درمورد قویترین سرورها هم نمیشه به چنین اعدادی حتی نزدیک شد، چون محدودیت پردازش سرور و ظرفیت و تاخیر ارتباط از طریق اینترنت و پارامترهای دیگر دخیل هستن و به شدت تاثیر میذارن.
ولی باوجود اینها بازم من ترجیح میدم از استانداردهای مستحکم علم رمزنگاری استفاده کنم و حتی یک دهم درصد هم اگر باشه روزهء شک دار نگیرم. چون شک و تردید همیشه خیلی جاها هست (حتی در همین پیشفرضهای ما)؛ پس بهتره تا میتونیم کمش کنیم! این برای آینده هم بهتره. چون نمیشه همه چیز رو در آینده پیشبینی و تضمین کرد. بعدم این کار هزینهء آنچنانی نداره که ازش اجتناب کنیم.

مثل اینکه شما یه اتومبیل داشته باشی که بخوای فقط داخل شهر ازش استفاده کنی، ولی میتونی دو نوعش رو انتخاب کنی، یک نوعی که با سرعت 200 کیلومتر بر ساعت هم اگر باهاش بخوری به دیوار بتونی چیزیش نمیشه، و یک نوع دیگری که با این سرعت بخوره به دیوار له میشه!! قیمت هردوش هم تقریبا یکیه. مصرف سوخت هردوش هم تقریبا یکیه. هزینهء نگهداری و تعمیر هردوش هم تقریبا یکیه. شما باشی کدومش رو انتخاب میکنی؟

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

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

Mohsen.
سه شنبه 26 دی 1391, 16:29 عصر
این روش فکر کنم جواب میده.
در صفحه submit فرم ابتدا با REMOTE_ADDR و SERVER_SOFTWARE و HTTP_USER_AGENT و یک Salt و با استفاده از تابع Crypt کد امنیتی درست میکنی و در یکی از فیلدهای کاربر ذخیره میکنی.
بعد هرجا خواستی دوباره این ها رو میگیری و با تابع Crypt با مقدار داخل فیلد مقایسه میکنی اگه درست بود که یعنی مشکل نداره.
اینجا (http://aparnet.ir/206-%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D9%87%D8%B4hash-%DA%A9%D8%B1%D8%AF%D9%86-%D9%BE%D8%B3%D9%88%D8%B1%D8%AF-%D8%AF%D8%B1-php)در مورد hash کردن پسورد توضیح داده با این روش عمل کرده.

کار میکنه؟

eshpilen
چهارشنبه 27 دی 1391, 08:39 صبح
این روش فکر کنم جواب میده.
در صفحه submit فرم ابتدا با REMOTE_ADDR و SERVER_SOFTWARE و HTTP_USER_AGENT و یک Salt و با استفاده از تابع Crypt کد امنیتی درست میکنی و در یکی از فیلدهای کاربر ذخیره میکنی.
بعد هرجا خواستی دوباره این ها رو میگیری و با تابع Crypt با مقدار داخل فیلد مقایسه میکنی اگه درست بود که یعنی مشکل نداره.
اینجا (http://aparnet.ir/206-%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D9%87%D8%B4hash-%DA%A9%D8%B1%D8%AF%D9%86-%D9%BE%D8%B3%D9%88%D8%B1%D8%AF-%D8%AF%D8%B1-php)در مورد hash کردن پسورد توضیح داده با این روش عمل کرده.

کار میکنه؟
قبلا درمورد این روش گفتم.
از نظر اصولیش بقدر کافی امن نیست.
ولی میتونید برای افزایش امنیت در ترکیب/همزمان با روشهای دیگر مثل توکن رندوم استفاده کنید. منظور از توکن رندوم مثل همین روشی که در این تاپیک درج کردم. البته میشه توکن رندوم رو بجای کوکی در سشن هم ذخیره کرد.

eshpilen
چهارشنبه 27 دی 1391, 09:41 صبح
یه سوال درمورد htmlpurifier
کد زیر برای پاک سازی xss ها خوبه؟
...
یا این

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

yeksib
شنبه 07 بهمن 1391, 01:10 صبح
مثلا بیای session کاربر رو هش کنی و بعدش یک آدرس اینطوری بسازی میشه جلوش روگرفت؟
قبل از حذف کردن متغیر p رو با session کاربر مقایسه کنی بعد اجازه حذف بهش بدی!
چون هکر نمیدونه چی توی p ریختیم


http://localhost/my.php?delete=26&p=0cb336f3660d068d71e6bd654d7ebdd8364dbd2d

eshpilen
دوشنبه 28 اسفند 1391, 19:22 عصر
من برای اطمینان، روشی رو که در این تاپیک مطرح کردم در security.stackexchange.com هم مطرح کردم: http://security.stackexchange.com/questions/32761/storing-anti-csrf-token-in-cookie
همونطور که گفتم روشش خیلی مجهز نیست، ولی بعنوان حداقل فکر میکنم کافیه (با توجه به اینکه حفرهء مهمی براش پیدا نشد).
حالا شما اگر حوصله داشتید و براتون صرف میکرد میتونید از روشهای مفصل تری هم استفاده کنید (ولی بنظر من ممکنه در این روشها مقداری افراط هم باشه).
بهرحال باید توجه داشت که سطح امنیت در تمام قسمتها و سیستمهای مختلف برنامه باید متعادل باشه؛ نه اینکه مثلا یجاش آخرین روش حرفه ای دنیا استفاده شده باشه و جای دیگش ضعف و نقص بزرگی داشته باشه. معمولا برنامه ها از اینطور ضعف و نقصها بیشتر رنج میبرن و آسیب پذیر هستن تا اینکه مثلا نگران فوق حرفه ای نبودن سیستم ضد CSRF باشیم.

Veteran
دوشنبه 28 اسفند 1391, 23:28 عصر
:لبخند:
سوال !
اصلا این باگی که شما ازش صحبت میکنین مربوط به چیه !
یک مثال اگر بزنین ممنون میشم

eshpilen
سه شنبه 29 اسفند 1391, 04:35 صبح
در پست شماره 11 (http://barnamenevis.org/showthread.php?378844-%DB%8C%DA%A9-%D8%B1%D9%88%D8%B4-%D8%B3%D8%A7%D8%AF%D9%87-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AC%D9%84%D9%88%DA%AF%DB%8C%D8%B1%DB%8C-%D8%A7%D8%B2-XSRF&p=1677206&viewfull=1#post1677206) توضیح دادم.