اخبار داخلی آرمان داده پویان

مقالات

جلوگیری از حملات تزریق SQL در برنامه‌های کاربردی PHP

جلوگیری از حملات تزریق SQL در برنامه‌های کاربردی PHP

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

SQL injection در PHP

SQL injection در واقع یک آسیب پذیری امنیتی وب است که به مهاجم اجازه می‌دهد از طریق queryهایی که یک برنامه تحت وب به پایگاه داده اش ارسال می‌نماید به اطلاعات پایگاه داده دسترسی یابد. این اطلاعات ممکن است، اطلاعات مربوط به کاربران دیگر باشد یا هر اطلاعات دیگری که مهاجم در حالت عادی اجازه دسترسی به آن‌ها را ندارد. همچنین در بسیاری موارد مهاجم می‌تواند اطلاعاتی که به آن‌ها دست یافته است را تغییر دهد یا پاک کند. همچنین در مواردی موفق به دسترسی به سرور و یا سایر تجهیزات back-end شده و حملات انکار سرویس به راه می‌اندازد. برای جزئیات بیشتر می‌توانید به حمله SQL injection در بخش مقالات آموزشی مراجعه نمایید.

حال به موضوع اصلی بپردازیم. برای آموزش جلوگیری از آسیب‌پذیری SQL injection در برنامه‌های کاربردی PHP یک مثال آورده‌ایم. در این مثال یک پایگاه داده از نوع MySQL با نام users داریم. وب اپلیکیشن مورد نظر ما کار ساده‌ای را انجام می‌دهد: شناسه کاربر را دریافت کرده و نام او را در جواب برمی‌گرداند. ساختار پایگاه داده users را در زیر می‌توانید مشاهده کنید:

شناسه نام کاربری گذرواژه نام نام خوانوادگی
۱ negint $۲a$10$SakFH.Eatq3QnknC1j1uo.rjM4KIYn.o8gPb6Y2YBnNNNY.61mR9K نگین طاهری
۲ marvejdani $۲a$10$hA/hwCzhr6F23BsbRZBjdOA5eqTgV01cv30sy/O2EcL2/zG9k0aGy مریم وجدانی
۳ samini $۲a$10$OkV5tCMMsy91pkkMXHa94OgcunNtuhxsQcxaOW6tJimuaCO0FMDZm سهیل امینی
۴ radores $۲a$10$2NgAjstT9NcN58zMcF/Rq.pYt5bg3iQ6OmdRgR3YWfT.ZVgmJR4FK راز درستانی

در ادامه، کد آسیب‌پذیر PHP این وب اپلیکیشن را آورده‌ایم. اگر برنامه نویسی به بحث امنیت آشنا نباشد حاصل کارش قطعا کدهای آسیب پذیر خواهند بود. در مثال زیر می‌توانید یکی از ساده ترین موارد را مشاهده نمایید.

connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}

/* SQL query vulnerable to SQL injection */
$sql = "SELECT username
FROM users
WHERE id = $id";

/* Select queries return a result */
if ($result = $mysqli->query($sql)) {
while($obj = $result->fetch_object()){
print($obj->username);
}
}
/* If the database returns an error, print it to screen */
elseif($mysqli->error){
print($mysqli->error);
}
}

سپس دو درخواست HTTP را مشاهده می‌کنید. اولی یک درخواست عادی و دومی یک درخواست مخرب و از سوی یک مهاجم است.

این مثال یک درخواست HTTP عادی و بدون مشکل است:

http://localhost/?id=1
> negint

این مثال نیز یک درخواست HTTP مخرب است:

در ادامه چندین آسیب‌پذیری‌ای که در کدها وجود دارد را فهرست کرده‌ایم.

اعتبارسنجی ورودی‌ها

شرح: اعتبارسنجی داده‌ها به تنهایی نمی‌تواند از حمله SQL injection جلوگیری به عمل آورد اما تا حدود زیادی می‌تواند اوضاع را بهبود بخشد. در این مثال داده ورودی ما شناسه کاربر است که به عدد است، پس در ورودی برنامه کاربردی بایستی تنها اعداد را قبول کند و به کاربر اجازه ارسال وروردی دیگری را ندهد.

راهکار پیشنهادی: عملیات ارزیابی ورودی بایستی حتی قبل از روند پردازش SQL query (پرس و جو SQL) انجام پذیرد. در این مثال همانطور که گفتیم بایستی ورودی ارزیابی باشد و تنها اعداد مورد قبول واقع شوند.

کد اجازه SQL injection را می‌دهد

شرح: در کد PHP که به طور مثال آورده‌ایم میبینید که از طریق دستور GET وروردی کاربر گرفته می‌شود و مستقیما به SQL ارجاع داده می‌شود. در نتیجه کاربر قادر خواهد بود در قسمت ورودی‌اش به جای عدد دستور مورد نظرش را وارد نماید.

راهکار پیشنهادی: بایستی از parameterized query استفاده شود زیرا در این صورت مشخص می‌گردد با کدام قسمت از SQL query باید عنوان ورودی کاربر برخورد شود.

خطاها به کاربر نشان داده می‌شود

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

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

ذخیره لاگ‌های مربوط به خطاها

شرح: در نظر داشته باشید جمع آوری لاگ‌های خطاها بسیار مهم بوده و فواید زیادی خواهد داشت. جمع آوری لاگ خطاها به شما کمک می‌نماید تا راحت‌تر مشکلات را حل نمایید. همچنین در یافتن نقاط ضعف امنیتی مفید می‌باشد و می‌توانید قبل از اینکه مهاجمان به آسیب‌پذیری وب اپلیکیشن شما پی ببرند شما متوجه آن شوید. همچنین بررسی لاگ خطاها مشخص می‌نماید آیا اخیرا مهاجمی برنامه کاربردی شما را مورد حمله قرار داده یا خیر.

راهکار پیشنهادی: به جای اینکه خطاها را به کاربرانتان نشان دهید آن را در فایلی ذخیره نمایید. دقت داشته باشید این فایل به هیچ وجه مورد دسترس مهاجمین قرار نگیرد.

پویشگر آسیب‌پذیری

اگر برنامه کاربردی بالا را در پویشگر آسیب پذیری acunetix و یا Nessus در دسته بندی SQL injection پویش نمایید، پویشگر تایید خواهد کرد که برنامه کاربردی شما موثر. یک برنامه نویس در مرحله نوشتن کدها با داشتن دانش مناسبی از حمله SQL Injection می‌تواند کدهای امنیت بنویسد. همچنین یک متخصص تست نفوذ وب اپلیکیشن با استفاده از پویشگرآسیب‌پذیری می‌تواند پی به این آسیب‌پذیری برده و آن را به تیم برنامه نویسی گزارش نماید.

جلوگیری از SQL Injection در PHP

با استفاده از Parametrize queries

فهم و نوشتن Parameterized queries آسان بوده و حتما بایستی توسط توسعه دهندگان در نظر گرفته شود. در واقع بایستی کدها به صورتی نوشته شوند که پایگاه داده بتواند بین دستورات SQL و داده‌هایی که توسط کاربر وارد شده است تمایز قائل شود. در نتیجه زمانی که مهاجمی در ورودی دستورات SQL را تزریق می‌کند نمی‌تواند کاری از پیش برد.

(PHP Data Objects (PDO

بسیاری از توسعه دهندگان PHP با استفاده از اکستنشن‌های mysql یا mysqli به پایگاه داده‌ها دسترسی می‌یابند. در قسمت قبلی در ارتباط با لزوم استفاده از parametrized queries صحبت کردیم و بایتسی بگوییم استفاده از آن‌ها با اکستنشن‌های mysqli امکان پذیر است. در PHP 5.1 راه بهتری برای کار با پایگاه داده‌ها معرفی شده است: PHP Data Objects (PDO). در واقع PDO استفاده از parametrized queries را آسان‌تر می‌نماید. همچنین PDO خواندن کدها را آسان‌تر کرده و همچنین با پایگاه داده‌های زیادی کار می‌کند. در ادامه کدهای بهبود یافته مثالی را که در ابتدا آورده‌ایم را می‌بینید:

نتیجه گیری

در آخر بایستی بگوییم SQL injection یکی از رایج‌ترین و خطرناک‌ترین آسیب‌پذیری‌ها در وب اپلیکیشن می‌باشد. در فرآیند تست نفوذ وب اپلیکیشن این آسیب‌پذیری در برنامه هدف مورد بررسی قرار می‌گیرد. آرمان داده پویان با سابقه‌ای ده سال در حوزه تست نفوذ وب اپلیکیشن و امنیت وب به شما توصیه می‌نماید برقراری امنیت وب اپلیکیشنی که در حال توسعه آن هستید را از ابتدای چرخه به وجود آمدن آن در نظر بگیرید. مشاوره با یک تیم حرفه‌ای از ابتدا بسیار کارآمد بوده و اگر به درستی صورت گیرد نه تنها باعث کند شدن روند توسعه نمی‌گردد بلکه صرفه جویی زیادی را در هزینه و زمان شما خواهد شد. اگر توسعه برنامه کاربردی شما به پایان رسیده است تست نفوذ برنامه کاربردی وب بنیان خود را جدی گرفته و از یک تیم حرفه‌ای متشکل از برنامه‌نویسان و متخصصان امنیت وب برای شناسایی و برطرف کردن نقاط آسیب پذیری نرم افزار خود استفاده نمایید.

آرمان داده پویان با یک دهه تجربه در زمینه ارائه انواع تست نفوذ یکی از شرکت‌های پیشرو در این عرصه بوده است. آرمان داده پویان با بهره‌گیری از تیم متخصص برنامه نویسی و امنیت ارائه دهنده تست نفوذ برنامه‌های وب بنیان می‌باشد.

برای مشاوره و کسب اطلاعات بیشتر با کارشناسان ما تماس بگیرید

تعداد بازدید: 210


تازه ترین ها