www.itiran.4umer.com
هل تريد التفاعل مع هذه المساهمة؟ كل ما عليك هو إنشاء حساب جديد ببضع خطوات أو تسجيل الدخول للمتابعة.

sgl 2

اذهب الى الأسفل

sgl 2 Empty sgl 2

پست  Admin الأحد نوفمبر 18, 2007 4:56 am

پاسخ نکته امنیتی شماره سوم حملات موسوم به SQL Injection پیش از هر چیز سعی می‌کنم تعریفی از 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
affraid
Admin
Admin
Admin

تعداد پستها : 63
Registration date : 2007-11-08

https://itiran.4umer.com

بازگشت به بالاي صفحه اذهب الى الأسفل

بازگشت به بالاي صفحه


 
صلاحيات هذا المنتدى:
شما نمي توانيد در اين بخش به موضوعها پاسخ دهيد