بنابراین شما فکر می کنید پایگاه داده SQL شما عملکردی دارد و از نابودی فوری محافظت می کند؟ خوب ، SQL Injection مخالف است!

بله ، این یک نابودی فوری است که ما در مورد آن صحبت می کنیم ، زیرا من نمی خواهم این مقاله را با اصطلاحات معمول لنگ “تشدید امنیت” و “جلوگیری از دسترسی مخرب” باز کنم. SQL Injection یک ترفند قدیمی در کتاب است که همه ، هر توسعه دهنده ، آن را خیلی خوب می داند و به خوبی از نحوه جلوگیری از آن آگاه است. به جز آن زمان عجیب و غریب که لغزش می کنند و نتایج نمی تواند چیزی فاجعه بار باشد.

اگر می دانید SQL Injection چیست ، در صورت تمایل به قسمت نیمه دوم مقاله بروید. اما برای کسانی که به تازگی در زمینه توسعه وب ظاهر می شوند و آرزو می کنند نقش های ارشد تری را بازی کنند ، مقدمه ای در دستور کار است.

تزریق SQL چیست؟?

کلید فهم SQL Injection به اسم آن است: SQL + Injection. کلمه “تزریق” در اینجا هیچ مفهوم پزشکی ندارد ، بلکه کاربرد فعل “تزریق” است. با هم ، این دو کلمه ایده قرار دادن SQL در یک برنامه وب را منتقل می کند.

قرار دادن SQL در یک برنامه وب. . . هوم . . آیا این کاری نیست که ما انجام می دهیم؟ بله ، اما ما نمی خواهیم یک مهاجم پایگاه داده خود را هدایت کند. بیایید این را با کمک یک مثال درک کنیم.

بیایید بگوییم که شما در حال ایجاد یک وب سایت معمولی PHP برای یک فروشگاه تجارت الکترونیکی محلی هستید ، بنابراین تصمیم می گیرید یک فرم تماس مانند این اضافه کنید:

اسم شما

پیغام تو

و فرض کنیم پرونده send_message.php همه چیز را در یک پایگاه داده ذخیره کند تا صاحبان فروشگاه بتوانند بعداً پیامهای کاربر را بخوانند. ممکن است این کد مانند این باشد:

<?پی اچ پی

$ name = $ _POST [‘name’]؛
$ message = $ _POST [‘پیام’]؛

// بررسی کنید که آیا این کاربر قبلاً پیام دارد
mysqli_query ($ اتصال, "از پیامهایی که نام = $ نام دارد ، انتخاب کنید")؛

// کد دیگر در اینجا

بنابراین شما برای نخستین بار سعی می کنید ببینید این کاربر پیغام خوانده نشده دارد یا خیر. عبارت SELECT * از پیامهایی که به نظر می رسد نام = $ به اندازه کافی ساده است ، درست است?

اشتباه!

در معصومیت خود ، ما درهای نابودی فوری پایگاه داده خود را باز کرده ایم. برای این اتفاق ، مهاجم باید شرایط زیر را داشته باشد:

  • برنامه بر روی یک پایگاه داده SQL در حال اجرا است (امروز ، تقریباً همه برنامه ها است)
  • اتصال فعلی پایگاه داده دارای مجوزهای “ویرایش” و “حذف” در پایگاه داده است
  • نام جداول مهم را می توان حدس زد

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

جو؛ سفارشات کوتاه ؛؟ بله قربان! بیایید ببینیم با اجرای اسکریپت پی اچ پی چه پرس و جو می شود:

SELECT * از پیام های که نام = جو؛ سفارشات کوتاه؛

خوب ، قسمت اول پرس و جو خطای نحوی (بدون نقل قول “Joe”) دارد ، اما نیمه کلون موتور MySQL را مجبور به شروع تفسیر یک مورد جدید می کند: دستورات کوتاه. دقیقاً مثل همین ، در یک خرابکاری واحد ، کل تاریخچه سفارشات از بین می رود!

اکنون که می دانید SQL Injection چگونه کار می کند ، وقت آن رسیده است که چگونگی متوقف کردن آن را بررسی کنید. دو شرط مورد نیاز برای تزریق موفقیت آمیز SQL عبارتند از:

  1. اسکریپت PHP باید امتیازاتی را در پایگاه داده اصلاح یا حذف کند. من فکر می کنم این در مورد همه برنامه ها صحیح است و شما نمی توانید برنامه های خود را فقط خواندنی کنید. �� و حدس بزنید چه ، حتی اگر همه امتیازات اصلاح شده را حذف کنیم ، تزریق SQL هنوز هم می تواند به شخصی اجازه دهد نمایش داده شد SELECT را اجرا کند و مشاهده همه بانک اطلاعاتی ، داده های حساس را شامل شود. به عبارت دیگر ، کاهش سطح دسترسی به بانک اطلاعاتی کار نمی کند و به هر حال برنامه شما به آن احتیاج دارد.
  2. ورودی کاربر در حال پردازش است. تنها راه تزریق SQL می تواند زمانی باشد که داده های کاربران را می پذیرید. یک بار دیگر ، متوقف کردن همه ورودی ها برای برنامه شما عملی نیست زیرا نگران تزریق SQL هستید.

جلوگیری از تزریق SQL در PHP

حال با توجه به اینکه اتصالات پایگاه داده ، نمایش داده شد و ورودی های کاربر بخشی از زندگی هستند ، چگونه می توان از تزریق SQL جلوگیری کرد؟ خوشبختانه ، این بسیار ساده است ، و دو روش برای انجام آن وجود دارد: 1) بهداشت ورودی کاربر و 2) استفاده از عبارات آماده.

ورودی کاربر را ضدعفونی کنید

اگر از نسخه PHP قدیمی تر (5.5 یا پایین تر استفاده می کنید ، و این اتفاق در میزبانی مشترک اتفاق می افتد) ، عاقلانه تر است که تمام ورودی های کاربر خود را از طریق عملکردی به نام mysql_real_escape_string () اجرا کنید. اصولاً آنچه انجام می دهد باعث حذف کلیه شخصیت های خاص در یک رشته می شود تا هنگام استفاده از پایگاه داده معنای خود را از دست دهند.

به عنوان مثال ، اگر رشته ای مانند من رشته ای داشته باشید ، یک شخصیت اضافه نقل قول (‘) می تواند توسط یک مهاجم برای دستکاری پرس و جو از پایگاه داده ایجاد شود و باعث تزریق SQL شود. اجرای آن از طریق mysql_real_escape_string () رشته ای را تولید می کند ، که با فرار از آن ، یک backslash به نقل قول اضافه می کند. در نتیجه ، اکنون کل رشته به عنوان یک رشته بی ضرر به پایگاه داده منتقل می شود ، به جای اینکه بتواند در دستکاری پرس و جو شرکت کند..

یک رویکرد با این روش وجود دارد: این یک تکنیک واقعا قدیمی است که همراه با اشکال قدیمی تر دسترسی به پایگاه داده در PHP است. همانطور که در PHP 7 وجود دارد ، این عملکرد حتی دیگر وجود ندارد ، که ما را به راه حل بعدی خود می رساند.

از عبارات آماده استفاده کنید

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

<?پی اچ پی
$ servername = "محل محلی"؛
$ نام کاربری = "نام کاربری"؛
رمز عبور $ = "کلمه عبور"؛
$ dbname = "myDB"؛

// ایجاد ارتباط
$ conn = mysqli جدید ($ سرور نام ، نام کاربری $ ، رمز عبور $ ، dbname)؛

// بررسی اتصال
اگر ($ اتصال)->conn_error)
بمیر ("ارتباط ناموفق بود: " . $ conn->conn_error)؛
}

// آماده سازی و پیوند زدن
$ stmt = $ conn->آماده کردن("INSERT INTY MyGuests (نام خانوادگی ، نام خانوادگی ، ایمیل) ارزش ها (؟ ،؟ ،؟؟)")؛
$ stmt->bind_param ("اس اس اس", نام خانوادگی $ ، نام خانوادگی $ ، ایمیل)؛

// تنظیم پارامترها و اجرای
$ firstname = "جان"؛
$ نام خانوادگی = "دوه"؛
$ ایمیل = "[ایمیل محافظت شده]
$ stmt->اجرا کردن()؛

$ firstname = "مریم"؛
$ نام خانوادگی = "معلم"؛
$ ایمیل = "[ایمیل محافظت شده]
$ stmt->اجرا کردن()؛

$ firstname = "جولی"؛
$ نام خانوادگی = "دولی"؛
$ ایمیل = "[ایمیل محافظت شده]
$ stmt->اجرا کردن()؛

پژواک "سوابق جدید با موفقیت ایجاد شد"؛

$ stmt->بستن()؛
$ conn->بستن()؛
?>

من می دانم که اگر تازه به بیانیه های آماده شده بروید ، فرایند غیر ضروری به نظر می رسد ، اما مفهوم ارزش تلاش را دارد. اینجا یک مقدمه خوب برای آن.

برای کسانی که قبلاً با برنامه PDO پی اچ پی آشنا هستند و از آن برای ایجاد جمله های آماده استفاده می کنند ، یک توصیه کوچک دارم.

هشدار: هنگام تنظیم PDO مراقب باشید

هنگام استفاده از PDO برای دسترسی به پایگاه داده ، می توانیم به یک احساس غلط امنیتی بپردازیم. “آه ، خب ، من از PDO استفاده می کنم. حالا دیگر لازم نیست که به هر چیز دیگری فکر کنم “- این طور است که تفکر ما به طور کلی پیش می رود. درست است که PDO (یا MySQLi اظهارات آماده شده) برای جلوگیری از انواع حملات تزریق SQL کافی است ، اما هنگام تنظیم آن باید مراقب باشید. معمول است فقط کپی کردن چسباندن کد را از آموزش ها یا پروژه های قبلی خود انجام دهید و به کار خود ادامه دهید ، اما این تنظیم می تواند همه چیز را خنثی کند:

$ dbConnection->setAttribute (PDO :: ATTR_EMULATE_PREPARES ، درست)؛

کاری که این تنظیم انجام می دهد این است که به PDO بگویید که بیانیه های آماده شده را تقلید کند تا اینکه از ویژگی های عبارت های آماده شده در پایگاه داده استفاده کند. در نتیجه ، PHP رشته های پرس و جو ساده را به پایگاه داده می فرستد ، حتی اگر به نظر می رسد کد شما این است که بیانیه های آماده شده و پارامترهای تنظیم شده و همه آن را ایجاد می کند. به عبارت دیگر ، شما مانند قبل از تزریق SQL آسیب پذیر هستید. ��

راه حل ساده است: حتما این تقلید را نادرست تنظیم کنید.

$ dbConnection->setAttribute (PDO :: ATTR_EMULATE_PREPARES ، نادرست)؛

اکنون اسکریپت PHP مجبور است از عبارات آماده شده در سطح بانک اطلاعاتی استفاده کند و از انواع تزریق SQL جلوگیری می کند.

جلوگیری از استفاده از WAF

آیا می دانید با استفاده از WAF (فایروال برنامه وب) می توانید برنامه های وب را نیز از تزریق SQL محافظت کنید?

خوب ، نه فقط تزریق SQL بلکه بسیاری دیگر از آسیب پذیری های لایه ای 7 مانند اسکریپت کراس سایت ، تأیید هویت شکسته شده ، جعل سطح سایت ، قرار گرفتن در معرض اطلاعات و غیره را در هر صورت می توانید از خود میزبان مانند Mod Security یا cloud-based مانند موارد زیر استفاده کنید..

تزریق SQL و چارچوب های مدرن PHP

تزریق SQL بسیار معمول است ، بسیار آسان ، بسیار ناامیدکننده و آنقدر خطرناک که تمام چارچوب های وب مدرن PHP با اقدامات متقابل ساخته می شوند. به عنوان مثال در وردپرس $ wpdb داریم->تابع () را آماده کنید ، در حالی که اگر از چارچوب MVC استفاده می کنید ، تمام کارهای کثیف را برای شما انجام می دهد و حتی لازم نیست که در مورد جلوگیری از تزریق SQL فکر کنید. کمی آزار دهنده است که در وردپرس باید صریحاً بیانیه ها را تهیه کنید ، اما سلام ، این WordPress است که ما در مورد آن صحبت می کنیم. ��

به هر حال ، نظر من این است که نژاد مدرن توسعه دهندگان وب لازم نیست درباره تزریق SQL فکر کنند ، و در نتیجه ، آنها حتی از این امکان آگاه نیستند. به همین ترتیب ، حتی اگر آنها یک پشتیبان خود را در برنامه خود باز نگه دارند (شاید این یک پارامتر پرس و جو $ _GET و عادت های قدیمی برای شلیک یک ضربه پرس و جو کثیف به داخل باشد) ، نتایج می تواند فاجعه بار باشد. بنابراین همیشه بهتر است که وقت بگذاریم تا عمیق تر به زیربناها برویم.

نتیجه

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

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me