اطلاعیه

Collapse
No announcement yet.

امنیت در php قسمت دوم

Collapse
X
 
  • Filter
  • زمان
  • Show
Clear All
new posts

  • امنیت در php قسمت دوم

    نکته امنیتی شماره سوم حملات موسوم به
    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 '%



    که نتیجه تعصف برانگیز


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

     . 
    '"); 


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

    1;DROP TABLE users

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

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

    در مورد حفره اول تابعی را می نویسیم که بسیار ساده و در عین حال محکم و قابل اعتماد است
    کد PHP:
    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;


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

    query "SELECT * FROM users WHERE username='" sql_quote($username) . "'"
    در مورد نکته دوم هم که کلاس امیرمحمد عزیز رو مورد استفاده قرار دادم که یکی از مجموعه های بدرد بخور PEAR هست و به آدرس http://pear.php.net/package/Validate می تونین اون رو دریافت کنین و آدرسی که در کد هست رو به مسیر دلخواهی که این فایل درون قرار داره تغییر بدین


    کد PHP:
    //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...ects-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

  • #2
    یکم سرم شلوغه چند تا پروژه گرفتم امتحانات دانشگاه هم هست
    بد شد ببخشید

    Comment

    Working...
    X