PDA

View Full Version : سوال: استفاده از preg_replace برای جلوگیری از sql injection مناسبه ؟



mamali-mohammad
جمعه 21 مرداد 1390, 21:56 عصر
سلام
آیا استفاده از preg_replace برای جلوگیری از sql injection مناسبه ؟
ممنون

eshpilen
جمعه 21 مرداد 1390, 22:46 عصر
مگه preg_replace رو برای sql injection درست کردن که میگی خوبه یا نه؟
اصلش این هست که کل کد و الگوریتم شما در این ارتباط چیه.
ضمنا روشهای دیگه ای مثل mysql_real_escape_string مگه چه اشکالی دارن بنظر شما؟
البته خیلی افراد میگن که باید بجای mysql_real_escape_string از روش کوئری های پارامتری استفاده کرد؛ بنده مخالفتی با اونا ندارم. فقط نمیدونم چرا وقتی روش و تابع استاندارد هست همه میخوان از خودشون روش اختراع کنن؟

البته یه زمانی شما میخواید کاراکترها و کلمات مورد نظر حذف بشن بحثش جداست. ولی باید دید چرا؟ یعنی فکر میکنید اگر حذف نکنید امنیت ندارید؟ چرا؟ دقیقا درمورد چه فیلد و داده ای میخواید این کار رو بکنید؟
ضمنا در فیلدهایی که محدودیت های بیشتری دارن بنظرم روشهای اصولی این نیستن که یه بلک لیست درست کنیم و هرچی توی اون بلک لیست بود حذف کنیم. اینطور کاربردها بیشتر نیاز به ولیدیت بر اساس وایت لیست (حتما میدونید که وایت لیست از بلک لیست سختگیرانه تر و امن تره) یا رگولار اکسپرشنی که الگوی دقیق اون فیلد رو مشخص میکنه دارن.
در ضمن بنده فکر میکنم بهرصورت اگر از روش دیگری استفاده میکنید، برای اطمینان و انعطاف در تغییرات آیندهء برنامه، از روشهایی مثل mysql_real_escape_string هم استفاده کنید. چون جالب بنظر نمیرسه که روش مخصوص این کار رو بذارید کنار و فقط از روش خودتون استفاده کنید. فرضا اگر در MySQL نسخهء 7 دو تا کاراکتر دیگه هم خطرناک شدن، تابع mysql_real_escape_string بصورت خودکار آپدیت خواهد بود و اون کاراکترها رو هم Escape میکنه.

mamali-mohammad
جمعه 21 مرداد 1390, 22:56 عصر
استفاده از mysql_real_escape_string کارکترهای نظیر ~!@#$% رو پاک نمی کنه خب
مگه برای sql injection از کارکترهای مثل !%^$* استفاده نمی کنن ؟

amin1softco
جمعه 21 مرداد 1390, 23:36 عصر
$username = trim(mysql_prep($_POST['username']));

ولی mysql_prep یک چیزه دیگه است :لبخند:
ولی خوب هر کسی متد خودشو داره

parselearn
جمعه 21 مرداد 1390, 23:48 عصر
$username = trim(mysql_prep($_POST['username']));

ولی mysql_prep یک چیزه دیگه است :لبخند:
ولی خوب هر کسی متد خودشو داره


Call to undefined function mysql_prep()

???

amin1softco
شنبه 22 مرداد 1390, 00:03 صبح
از mysql_real_escape_string استفاده شده


function mysql_prep( $value ) {
$magic_quotes_active = get_magic_quotes_gpc();
$new_enough_php = function_exists( "mysql_real_escape_string" ); // i.e. PHP >= v4.3.0
if( $new_enough_php ) { // PHP v4.3.0 or higher
// undo any magic quote effects so mysql_real_escape_string can do the work
if( $magic_quotes_active ) { $value = stripslashes( $value ); }
$value = mysql_real_escape_string( $value );
} else { // before PHP v4.3.0
// if magic quotes aren't already on then add slashes manually
if( !$magic_quotes_active ) { $value = addslashes( $value ); }
// if magic quotes are active, then the slashes already exist
}
return $value;
}

Metal Gear Solid
شنبه 22 مرداد 1390, 05:12 صبح
دوستانی که میگن یک لیست سفید ایجاد کنیم بهتر از لیست سیاه هست. یه لطفی بکنن به ما بگن چطور کاراکترهای فارسی رو به لیست سفید اضافه کنیم
من از همون اول هم وقتی برنامه نویسی غیر وب میکردم لیست سفید میساختم اما توی PHP نمیدونم چطور باید کارکترهای فارسی رو به لیست اضافه کرد.
مثلاً لیست سفیدی برای نام های کاربری و کلاً textbox های یک خطی که شامل موارد زیر باشه چطور میشه ایجاد کرد ( مهم نیست با عبارات منظم باشه یا نباشه ) مهم روش شناسایی کاراکترها به مفسره.
لیست سفید : تمامی کاراکترهای الفبای فارسی + تمامی حروف الفبای انگلیسی + اعداد + خط فاصله و _ و حالا هر چی کاراکتر معمول دیگست

حالا استفاده از توابع Ctype رو پیشنهاد میکنن دوستان یا نه؟

eshpilen
شنبه 22 مرداد 1390, 09:03 صبح
استفاده از mysql_real_escape_string کارکترهای نظیر ~!@#$% رو پاک نمی کنه خب
مگه برای sql injection از کارکترهای مثل !%^$* استفاده نمی کنن ؟
sql injection در MySQL با استفاده از این کاراکترها؟ اونم وقتی از mysql_real_escape_string روی ورودیها استفاده کرده باشیم؟
خیر فکر نمیکنم. یعنی در شرایط عادی که جایی چنین چیزی ندیدم و دلیلی هم براش نمیبینم.
اگر بگی دیتابیس های دیگه شاید، چون بنده از سینتاکس اونا خبر ندارم.
بهرصورت همینطوری که نمیشه یه حرفی رو قبول کرد. باید سندی، نمونه کد و مثالی چیزی باشه براش یا نه؟
ضمنا کلا وجود هیچ کاراکتری به تنهایی نمیتونه باعث sql injection بشه اگر شما از روشهای مناسب Escape استفاده کنید. بطور مثال مگه همین پست که شما زدی و توش این کاراکترها هست در دیتابیس این فروم درج نشده؟
پس به چه دلیل شما میگید باید این کاراکترها رو حذف کنیم؟

eshpilen
شنبه 22 مرداد 1390, 12:35 عصر
مثلاً لیست سفیدی برای نام های کاربری و کلاً textbox های یک خطی که شامل موارد زیر باشه چطور میشه ایجاد کرد ( مهم نیست با عبارات منظم باشه یا نباشه ) مهم روش شناسایی کاراکترها به مفسره.
لیست سفید : تمامی کاراکترهای الفبای فارسی + تمامی حروف الفبای انگلیسی + اعداد + خط فاصله و _ و حالا هر چی کاراکتر معمول دیگست

این رو ببین:

<?php

if(isset($_POST['input'])) {
$input=$_POST['input'];
$re="/^([\s\x{0621}-\x{063A}\x{0640}-\x{0691}\x{0698}-\x{06D2}]|[a-zA-Z0-9_-])*$/u";
if(preg_match($re, $input)) echo 'Acceptable.';
else echo 'Not acceptable!';
}

?>

<html>
<body>
<form method="post" action="">
<input type="text" name="input">
<input type="submit" value="submit">
</form>
</body>
</html>
این رگولار اکسپرشن حاوی تمامی کاراکترهای الفبای فارسی + تمامی حروف الفبای انگلیسی + اعداد + خط فاصله و _ و Space میشه. البته درمورد فارسی اعراب رو هم شامل میشه.
ضمنا ما که Credit مردم رو پایمال نمیکنیم، بخش فارسیش رو از این پست (http://barnamenevis.org/showthread.php?279112-%D9%85%D9%82%D8%A7%DB%8C%D8%B3%D9%87%D8%A1-%D8%B9%D9%85%D9%84%DB%8C-ASP.NET-%D9%88-PHP-%D8%A8%D8%A7-%D9%86%D9%85%D9%88%D9%86%D9%87-%DA%A9%D8%AF&p=1234626&viewfull=1#post1234626) کاربر binyaft (http://barnamenevis.org/member.php?106845-binyaft) برداشتم.
نه اینکه فکر کنی خودم نمیتونستم درستش کنم، ولی کار میبرد باید میرفتم رنج یونیکد حروف فارسی رو پیدا میکردم و یخورده کار و داستان داشت. اگر بخوای میشه اعراب رو ازش حذف کرد.
ضمنا حواست باشه این رگولار اکسپرشن رشتهء خالی رو هم قبول میکنه. چک کردن طول رو میشه جداگانه انجام داد و یا همین رگولار اکسپرشن رو یک تغییر کوچولو بدیم کافیه. ولی بنده شخصا فکر میکنم چک کردن طول جداگانه انجام بشه اصولی تره.

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

mamali-mohammad
شنبه 22 مرداد 1390, 13:38 عصر
به طور کلی زمانی که وارد دیتابیس می کنیم از mysql_real_escape_string برای همه فیلدها استفاده کنیم
زمانی هم که فراخوانی می کنیم از کد زیر استفاده کنیم

htmlspecialchars($row['user'], ENT_QUOTES
درسته ؟

eshpilen
شنبه 22 مرداد 1390, 13:59 عصر
به طور کلی زمانی که وارد دیتابیس می کنیم از mysql_real_escape_string برای همه فیلدها استفاده کنیم
زمانی هم که فراخوانی می کنیم از کد زیر استفاده کنیم

htmlspecialchars($row['user'], ENT_QUOTES
درسته ؟
بله درسته.
حالا کسی روشی برای عبور از این فیلتر بلده بگه ما هم بدونیم خب. تست میکنیم میبینیم.

البته بنده نمیگم درمورد همهء فیلدها این کارها کافیه. چون همهء حمله ها که فقط SQL Injection و XSS نیست.
مثلا نباید گذاشت نام کاربری بتونه هرچیزی باشه. یک علتش رو در هم بالاتر گفتم (جعل هویت).
یا مثلا یه فیلد که باید عددی باشه خب باید چک کنید عدد باشه و لاغیر.

ضمنا در جاهای خاص ممکنه روشهای بیشتری مورد نیاز باشن. مثلا htmlspecialchars از XSS در متن صفحه جلوگیری میکنه، ولی وقتی ورودی کاربر در یه جای دیگه مثل آدرس لینک درج میشه میشه راحت دورش زد و بنابراین باید ولیدیشن بیشتری صورت بگیره. ولی چون اونطور کاربردها خیلی کمتر هستن ما همین روش کلی رو گفتیم و حالات خاص رو مطرح نکردیم.
البته بحث در اینجا باید درمورد SQL Injection باشه، ولی ما عملا به چیزهای دیگر هم پرداختیم. بخاطر همین نیاز به توضیح بیشتری نمیبینم.

mamali-mohammad
شنبه 22 مرداد 1390, 15:14 عصر
ممنون
مثلا برای ثبت نام کاربران فقط اجازه بدیم از A-Z و _ و . استفاده کنن
امنیت در session بیشتر هست یا cookie ؟

eshpilen
شنبه 22 مرداد 1390, 18:18 عصر
Cookie میتونه بیشتر باشه. اگر درست طراحی بشه.

Metal Gear Solid
شنبه 22 مرداد 1390, 22:32 عصر
تا جایی که من میدونم استفاده از :

htmlspecialchars($row['user'], ENT_QUOTES
استفاده میکنیم تگ ها رو از بین میبره.
حالا اگه بخوایم یه Textarea رو که حاوی کلی از کدهای HTML هست رو نشون بدیم به صورتی که استایلشون هم نشون داده شه چه باید کرد؟

eshpilen
شنبه 22 مرداد 1390, 23:25 عصر
استفاده میکنیم تگ ها رو از بین میبره.از بین نمیبره. بلکه به روش مناسب خودش Escape میکنه.


حالا اگه بخوایم یه Textarea رو که حاوی کلی از کدهای HTML هست رو نشون بدیم به صورتی که استایلشون هم نشون داده شه چه باید کرد؟ یعنی عین کدهای HTML وارد شده در اون در صفحه درج و اجرا بشن؟
اینطوری اگر این تگها از منبع غیرقابل اعتمادی بیان و برای کاربران دیگه نمایش داده بشن خطر XSS وجود داره و باید دنبال راه حلی براش بگردی. مثلا میتونی تگهای مجاز رو در یک وایت لیست ذخیره کنی و غیر از اونا هرچی بود حذف یا Escape کنی. ولی کلا این کار به این سادگی نیست چون باید خیلی دقت کنی و کوچکترین راه نفوذی نباشه که این در HTML بخاطر قاراشمیش بودن اوضاعش و اینکه در طول سالها کلی وصله و پینه شده کار راحتی نیست احتمالا (تمام افراد وارد و منابع معتبری که دیدم اینطور میگن و خب بنظر بنده هم راست میگن!). از طرف دیگه نمیشه بگی کاربر رو بیش از حد محدود نکنیم و در عین حال در خطر XSS قرار نگیری. مثل اینکه بگی ورودی کاربر رو محدود یا Escape نکنیم و بعد انتظار داشته باشی SQL Inject نشی. مگر اینکه یه الگوریتم مفصل و پیچیده و هوشمند بنویسی که فقط حمله ها رو دفع بکنه، که اینم کار میبره و معلوم نیست بشه بهش اعتماد کرد؛ ضمنا کسی هم باهات روی این همکاری نمیکنه، چون مورد نیاز کمتر کسی هست و کلا منطق و جذابیت خاصی برای بیشتر افراد نداره.
البته اگر خودت کد HTML میذاری یا کدهایی که هر کاربر میذاره فقط برای خودش نمایش داده میشه مشکل چندانی نیست بنظرم؛ چون کسی به خودش حمله نمیکنه!! مثل یک وبلاگ که طرف خودش تمپلیت HTML و جاوااسکریپت و هرچی که بخواد رو واسه سایت خودش میذاره.

Metal Gear Solid
یک شنبه 23 مرداد 1390, 06:44 صبح
ممنون از وقتی که گذاشتی اما من منظورم چیز دیگه ای بود.
شاید اشتباه از من بود. آخه من فکر میکردم استفاده از تابع بالا باعث میشه تگ های HTML به صورت کد شده تبدیل بشن مثلاً تگ < به &gl; فکر کنم یا یک چیزی شبیه به این تبدیل میشه. و من نمیخوام این رو در خروجی نشون بده.
فرض کنید من برای کاربرانم ادیتورهای HTML رو قرار دادم مثل tinyMCE و یا CKEditor و ... . حالا میخوام هنگام نمایش ارسالها و یا هر متنی که با استفاده از اون ادیتور ایجاد شده و توی دیتابیس ذخیره شده، دقیقاً با استایل هاشون نمایش داده شه. نه اینکه تگ ها همه به کاراکترهای نامفهموم برای کاربران تبدیل شن.
منظورم این بود که چطور هم استایل رو نشون بدیم هم خطری وجود نداشته باشه. چون ممکنه ما هنگام real_escape کردن کلی کدهای عجیب غریب رو Escape کرده باشیم که هنگام نمایش معمولی یه سری مضراتی داشته باشن.
من در مورد تابع بالا اطلاع زیادی ندارم و نمیدونم آیا دقیقاً جیزی که من میخوام رو اجرا میکنه یا نه. اگه نه راه دیگه ای هست؟

eshpilen
یک شنبه 23 مرداد 1390, 09:22 صبح
آخه من فکر میکردم استفاده از تابع بالا باعث میشه تگ های HTML به صورت کد شده تبدیل بشن مثلاً تگ < به &gl; فکر کنم یا یک چیزی شبیه به این تبدیل میشه.بله تابع htmlspecialchars همین کار رو میکنه دیگه. ولی این شکل فقط در سورس صفحه دیده میشه و در نمایش مرورگر به کاربر تگها به شکل &gt; دیده نمیشن، بلکه بصورت متن خام بصورتی که تایپ شده بوده دیده میشن. به اینصورت مثلا کاربران میتونن در بخش کامنت سایت کد HTML هم بعنوان نمونه کد درج کنن، یا مثلا اگر از کاراکترهایی مثل علامت کوچکتر و غیره در متن خودشون استفاده کنن (که کاملا عادی هست)، نمایش صفحه بهم نمیریزه و مطلب اونا هم همونطور که بوده به رویت میرسه.

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

منظورم این بود که چطور هم استایل رو نشون بدیم هم خطری وجود نداشته باشه. چون ممکنه ما هنگام real_escape کردن کلی کدهای عجیب غریب رو Escape کرده باشیم که هنگام نمایش معمولی یه سری مضراتی داشته باشن.real_escape فقط چند کاراکتر معدود و شناخته شده رو Escape میکنه. دقیقا اینا رو:

NUL (ASCII 0), \n, \r, \, ', ", and Control-Z.
بقیه بدون هیچ تغییری باقی میمونن.
موقع نمایش هم که باید از تابع htmlspecialchars استفاده کنید. این تابع ربط خاصی به تابع real_escape_string نداره. از هردو در جای خودشون باید استفاده بشه. real_escape_string برای درج دیتای غیرقابل اعتماد در کوئری های MySQL و htmlspecialchars برای درج دیتای غیرقابل اعتماد در متن HTML.

چون ممکنه ما هنگام real_escape کردن کلی کدهای عجیب غریب رو Escape کرده باشیم که هنگام نمایش معمولی یه سری مضراتی داشته باشن.چه کدی مثلا؟ چه کاراکتری؟
اونایی رو که htmlspecialchars میشناسه که خب تبدیل و بی خطر میکنه. بقیش هم فکر نمیکنم خطرخاصی داشته باشه، ولی اگر در فیلد خاصی اصلا مورد انتظار نیستن میتونن توسط رگولار اکسپرشن، بلک لیست یا وایت لیست فیلتر بشن.
اتفاقا بنده قبلا از یکی از دوستان که خودش بقدر کافی در زمینهء هک کار کرده و اعتبار داره در این مورد سوال کردم و ایشون گفتن تاحالا مورد خاصی ندیدن که کد و کاراکتر خاصی از اون نظر خطرناک باشه. بهرحال انتظار هم نمیره مرورگر اینقدر درپیت باشه تا با مواجه شدن با چند کاراکتر خارج از انتظار دچار نفوذی چیزی بشه. مرورگر کاراکترهای HTML رو میشناسه و نسبت به بقیه بی تفاوت هست یا اونا رو با یک کاراکتر نمایشی جایگزین نشون میده.
خلاصه خطر خاصی در حیطهء دانش و تجربهء بنده نیست در این زمینه، ولی تنها فکری که میکنم از نظر بدنما شدن صفحه با کاراکترهای بی معنا و اینطور چیزهاست. حالا بحث اینکه اصلا وجود این کاراکترها در فیلدهای مختلف چی هست و باید حذف کرد یا نه جداست. مثلا کسی نگفته در نام کاربری کاراکتر نال یا Control-Z باشه. همینطور در کامنت هم فکر نمیکنم وجود این کاراکترها هیچ معنایی داشته باشه، و بنابراین میتونید اونا رو فیلتر کنید، ولی اگر هم فیلتر نکنید بنده شخصا هیچ خطر امنیتی خاصی جز بحث خرابکاری در ظاهر سایت نمیشناسم که البته خرابکاری ظاهری رو میشه با کاراکترهای معمولی هم تاحد زیادی انجام داد.
البته یوقت ممکنه یه نسخهء خاص از مرورگر خاصی باگی داشته که با استفاده از کاراکترهای غیرعادی خاصی یا توالی و ترکیب خاصی از اون کاراکترها میشده ازش بهره برداری کرد. بله این کاملا ممکنه!
من فکر میکنم بعضی از راهکارهایی که ارائه میدن و میخوان کلی کاراکتر رو بلاک کنن بخاطر همین باشه. یعنی یه وقتی یه باگی در یه نسخهء خاص یه نرم افزاری بوده، ولی الان لزوما اینطوری نیست. اون باگ اون نرم افزار بوده، و شاید این راه حلهای بصورت مقطعی و موقت در اون زمان مناسب بودن، اما لزوما الان ضرورتی ندارن، چون احتمالا مدتهاست دیگه کسی از اون نرم افزار استفاده نمیکنه و از طرف دیگه طبیعتا چنان حمله هایی هم در نت دیگه خیلی به ندرت وجود دارن. اگر یه نرم افزار باگ داشته باشه ممکنه حتی با چنتا کاراکتر و یا توالی و ترکیب و رشتهء خاصی باشه، لزوما محدود به کاراکترهای خاص و غیرعادی نمیشه (البته بنظرم باید بگیم که احتمال باگ با کاراکترهای غیرعادی در کل بیشتر هست).
راستی صحبت بنده با اون دوست هکرم فکر میکنم همون مسئلهء مورد نظر شما باشه:
پرسش بنده:

میگم اگر از متدهای Escape در همه جا استفاده کنیم، مثلا از mysql_real_escape_string موقع درج در دیتابیس، و از تابع htmlspecialchars موقع درج در متن صفحه، آیا بازم خطری هست؟ آیا کاراکترهای خاصی بازهم خطرناک هستن و باید کلا حذف بشن؟
مثلا وقتی کاربر کامنت میده، یا موقع انتخاب نام کاربری، آیا ضرورت داره کاراکترهای خاصی رو غیرمجاز بدونیم و حذف کنیم؟ مثلا کاراکتر نال (0x00) و امثالهم اگر هست.
موقع درج در دیتابیس که ضرری نمیزنن. ولی موقع ارسال به مرورگر حتی باوجود Escape کردن صحیح میتونن خطرناک باشن و چرا؟
پاسخش:

نه کاراکترهای خاص مثل نال جاهای دیگه خطرناکن اینجا توی خروجی اچ تی ام ال چندان تاثیری ندارن... لااقل چیزی که من بدونم..

mamali-mohammad
چهارشنبه 26 مرداد 1390, 19:48 عصر
من از mysql_real_escape_string برای ذخیره متن استفاده میکنم
اما مشکل دارم
اگه یه متن لینک رو بفرستیم ، ذخیرش اینطوری میشه :

%5C%22%5C%22%5C%22%5C%22%5C%22http://yourname.com%5C%22%5C%22%5C%22%5C%22%5C%22

mamali-mohammad
پنج شنبه 27 مرداد 1390, 13:26 عصر
دوستان ؟
کسی میتونه کمک کنه ؟

mamali-mohammad
جمعه 28 مرداد 1390, 00:35 صبح
کسی هست کمک کنه ؟