تزریق SQL

از Secure Coding

نسخهٔ تاریخ ‏۱۹ دسامبر ۲۰۱۹، ساعت ۰۷:۴۷ توسط Admin (بحث | مشارکت‌ها)

در این نوع از آسیب پذیری های مهاجم می تواند payload خود را در قسمت های مختلف برنامه تزریق کند. از انواع آسیب پذیری های injection می توان به تزریق sql و یا تزریق command اشاره کرد.

تزریق sql

زبان پرس و جو sql راهی برای مدیریت داده های ذخیره شده در پایگاه داده های رابطه ای است. به این معنا که می توانیم در هر بستری از جمله وب داده هارا ذخیره، ویرایش و یا تغییر دهیم. گاهی اوقات احراز هویت کاربران، نمایش محتوای وبسایت و یا عکس های کاربران در پایگاه داده ذخیره می شود و توسط sql در مسیر های مختلف به کار برده می شود. حال فرض کنید attacker در پرس و جوی sql، دستکاری و یا Inject کند. در اینجا می گوییم sql injection رخ داده است.

Sql.png

برای مثال در تصویر بالا attacker به جای مقدار دسته بندی محصولات(Gift)این payload را وارد می کند.

' UNION SELECT username, password FROM users--

در نتیحه علاوه بر اطلاعات محصول دسته بندی Gifts تمام username و password های جدول users را هم در خروجی نمایش می دهد. حملات sql injection نوع های مختلفی دارد. چون به ازای هر query نوشته شده ممکن است حمله جدیدی رخ دهد. با این حال به صورت کلی 3 دسته بندی زیر را می توان نام برد.

بر مبنای خطا یا Error Based

مثال معروفی برای این روش وجود دارد. صفحه ای از وبسایتی برای نمایش جزییات خبر از id آن خبر استفاده می کند؛

https://web.tld/news?id=100

با توجه به مقدار id، داده های دیگری از پایگاه داده خوانده و نمایش داده می شود.

SELECT title,context FROM tbl_news WHERE id ='$id'

بر مبنای اجتماع یا Union Based

در این روش علاوه بر اطلاعات دریافت شده توسط پرس و جوی توسعه دهنده با دستور Union اطلاعات دیگری از پایگاه داده استخراج می شود.

http://fakesite.com/report.php?id=23

برای مثال فرض کنید صفحه ای وجود دارد که براساس id موجودیت های سیستم گزارشی از وضیعت آن موجودیت چاپ می کند.

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

http://fakesite.com/report.php?id=23 order by 5--+

بعد از دانستن تعداد ستون های جدول با دستور Union، ستونی که از آن اطلاعات خوانده می شود و در صفحه چاپ می شود را بدست می آوریم.

http://fakesite.com/report.php?id=-23 union select 'hello1','hello2','hello3','hello4','hello5'--+

هر کدام از hello ها که در صفحه چاپ شود به این معنی است که می توانیم به جای آن hello پرس و جوی خود را بنویسیم.

برای مثال نام دیتابیس را با database() بدست می آوریم.

http://fakesite.com/report.php?id=-23 union select 1,2,database(),4,5--+

بر مبنای تاریکی Blind Based

شاید اسم این روش عجیب باشد ولی با توجه به الگو "بر مبنای" تاریکی کلمه مناسب و هکر پسندانه تری است!

در این روش با استفاده از and و دستورات زمانی مانند sleep در بارگذاری اطلاعات از پایگاه داده تاخییر و یا تغییر ایجاد می کنیم.

برای مثال می دانیم 2=1 نیست پس آن را در مقدار id قرار می دهیم تا شرط False شود و بدین ترتیب اطلاعات به درستی از پایگاه داده استخراج نشود.

http://www.shop.local/item.php?id=34 and 1=2

در مرحله بعد شرط True می کنیم.

http://www.shop.local/item.php?id=34 and 1=1

حال با توجه به روش های بالا به سراغ روش های جلوگیری از این حمله می رویم.

روش های جلوگیری

کنترل ورودی ها

روش های جلوگیری در زبان PHP

مثال 1)

تکه کد زیر دو مقدار username و password را با درخواست از نوع POST دریافت می کند و سپس در پرس و جو با رکورد های موجود در پایگاه داده مقایسه می کند.


<?php
$userName=$_POST['userName'];
$password=$_POST['password'];
$sqlQuery="SELECT * FROM users WHERE user_name='".$username."' AND user_password='".$password"';"
?>