SQL Injection چیست؟

Home » اطلاعات کاربردی » SQL Injection چیست؟

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

در شرایطی که آسیب‌پذیری SQL Injection وجود داشته باشد، مهاجم معمولاً می‌تواند این داده‌ها را تغییر دهد یا حتی حذف کند، و این ممکن است موجب بروز تغییرات دائمی و ناخواسته در عملکرد اپلیکیشن شود. در برخی موارد، شدت حمله SQL Injection ممکن است به حدی برسد که سرور میزبان پایگاه داده یا سایر زیرساخت‌های بک‌اند مورد هدف قرار گیرد و حتی حملات DoS (منع سرویس) به وقوع بپیوندد.

عواقب یک حمله SQL Injection موفق چیست؟

عواقب یک حمله SQL Injection موفق چیست؟

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

SQL چیست؟

SQL یک زبان استاندارد برای مدیریت پایگاه داده‌ها و انجام عملیات مختلف مانند جستجو، اضافه کردن، حذف یا به‌روزرسانی داده‌ها در پایگاه‌های داده است.

مثال‌هایی از تزریق SQL

آسیب‌پذیری‌ها و حملات SQL Injection دارای تنوع زیادی هستند که از شرایط خاصی نشأت می‌گیرند. در اینجا برخی از رایج‌ترین انواع حملات SQL Injection آورده شده است:

  • دستیابی به داده‌های پنهان: این حالت زمانی رخ می‌دهد که مهاجم بتواند یک کوئری را به گونه‌ای تغییر دهد که نتایج اضافی و اطلاعاتی که قرار نبوده در دسترس باشند، به او نمایش داده شود.
  • اختلال در منطق اپلیکیشن: در این نوع حمله، مهاجم قادر است که یک کوئری را طوری تغییر دهد که باعث ایجاد اختلال در منطق اپلیکیشن و تغییر در رفتار آن شود.
  • حملات UNION: در این نوع حمله، مهاجم می‌تواند داده‌ها را از چندین جدول مختلف پایگاه داده استخراج کند.
  • وارسی دیتابیس: در این حمله، مهاجم قادر است اطلاعاتی درباره نسخه و ساختار دیتابیس به دست آورد.
  • تزریق SQL کور: در این نوع تزریق، نتایج کوئری تغییر یافته به اپلیکیشن برنمی‌گردد، اما مهاجم با استفاده از عبارات شرطی، تأخیرها یا سایر تکنیک‌ها می‌تواند به‌طور آزمایشی اطلاعات پایگاه داده را کشف کند.

دستیابی به داده‌های پنهان (Retrieving Hidden Data)

فرض کنید یک اپلیکیشن خرید آنلاین داریم که محصولات را در دسته‌بندی‌های مختلف نمایش می‌دهد. هر کاربری که بر روی دسته‌بندی “هدایا” کلیک کند، مرورگر او یک درخواست به سرور ارسال می‌کند که شامل اطلاعات مربوط به آن دسته‌بندی خاص است. مهاجم می‌تواند این درخواست را دستکاری کرده و به داده‌هایی دست یابد که نباید به آن‌ها دسترسی داشته باشد.

https://insecure-website.com/products?category=Gifts

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

SELECT * FROM products WHERE category = ‘Gifts’ AND released = 1

در این سناریو، اپلیکیشن پس از دریافت درخواست کاربر، یک کوئری SQL به پایگاه داده ارسال می‌کند تا اطلاعات مربوط به محصولات موجود در دسته‌بندی “هدایا” را بازیابی کند. این کوئری به طور خاص از پایگاه داده می‌خواهد:

  • تمامی اطلاعات (علامت * برای انتخاب همه ستون‌ها)
  • از جدول محصولات (با دستور FROM products)
  • برای محصولاتی که در دسته‌بندی “هدایا” قرار دارند (شرط WHERE category = ‘Gifts’)
  • و تنها آن‌هایی که به عنوان محصولات منتشر شده شناخته می‌شوند (شرط AND released = 1)

هدف از اضافه کردن شرط released = 1 این است که فقط محصولاتی که به‌طور رسمی منتشر شده‌اند نمایش داده شوند و محصولات در حال آماده‌سازی یا هنوز منتشر نشده از نتایج حذف شوند (که احتمالاً برای آن‌ها مقدار released برابر 0 است).

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

‏https://insecure-website.com/products?category=Gifts’–

این درخواست منجر به ارسال کوئری SQL زیر از سوی اپلیکیشن به پایگاه داده می‌شود:

S‏ELECT * FROM products WHERE category = ‘Gifts’–‘ AND released = 1

نکته‌ مهمی که باید در اینجا به آن توجه شود، استفاده از دنباله‌ی «–» (دو خط فاصله) در SQL است. این دنباله به عنوان کامنت در زبان SQL شناخته می‌شود و باعث می‌شود که هر چیزی که پس از آن بیاید، نادیده گرفته شود و به‌عنوان بخشی از کوئری اجرا نشود. به عبارت دیگر، هر چیزی که پس از این دنباله قرار گیرد، به‌طور مؤثر از کوئری حذف می‌شود. بنابراین، قسمت AND released = 1 که قرار بود محصولات منتشر نشده را فیلتر کند، دیگر بخشی از کوئری نخواهد بود و تمام محصولات، حتی آن‌هایی که هنوز منتشر نشده‌اند، در نتایج نمایش داده می‌شوند.

با استفاده از این روش، مهاجم می‌تواند نه تنها محصولات منتشر نشده، بلکه تمامی محصولات را در دسته‌بندی “هدایا” مشاهده کند. اما در ادامه، مهاجم قادر است که فراتر از این رفته و باعث شود که اپلیکیشن تمامی محصولات از تمامی دسته‌بندی‌ها را نمایش دهد، حتی دسته‌بندی‌هایی که او از وجودشان اطلاعی نداشته است. برای مثال، مهاجم می‌تواند کوئری را به شکلی تغییر دهد که همه اطلاعات محصولات از تمام دسته‌ها نمایش داده شوند، به این صورت که دستور category = ‘Gifts’ را با یک عبارت عمومی‌تر جایگزین کند.

این درخواست:

https://insecure-website.com/products?category=Gifts’+OR+1=1–

منجر به ارسال کوئری زیر توسط اپلیکیشن می‌شود:

SELECT * FROM products WHERE category = ‘Gifts’ OR 1=1–‘ AND released = 1

در این کوئری دستکاری‌شده، شرایط فیلتر به‌طور کامل تغییر می‌کند. کوئری اکنون تمامی آیتم‌هایی را برمی‌گرداند که یکی از این دو شرط برای آن‌ها صادق باشد: یا دسته‌بندی محصول “هدیه” باشد (category = ‘Gifts’)، یا عبارت 1=1 که همیشه صحیح است، درست باشد. از آن‌جایی که 1=1 همیشه صحیح است، این قسمت از کوئری باعث می‌شود که تمام رکوردهای موجود در پایگاه داده بدون در نظر گرفتن دسته‌بندی‌شان بازگردانده شوند.

به عبارت دیگر، مهاجم قادر است به تمامی داده‌های موجود در دیتابیس دسترسی پیدا کند، حتی به داده‌هایی که هیچ ارتباطی با دسته‌بندی “هدایا” ندارند.

اختلال در منطق اپلیکیشن (Subverting Application Logic)

اختلال در منطق اپلیکیشن (Subverting Application Logic)

تصور کنید یک اپلیکیشن به کاربران این امکان را می‌دهد که با وارد کردن یک یوزرنیم و پسورد به حساب خود وارد شوند. برای مثال، اگر کاربری یوزرنیم “wiener” و پسورد “bluecheese” را وارد کند، اپلیکیشن این اطلاعات را با کوئری SQL زیر بررسی می‌کند:

SELECT * FROM users WHERE username = ‘wiener’ AND password = ‘bluecheese’

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

با این حال، یک مهاجم می‌تواند بدون داشتن پسورد، به راحتی با یوزرنیم هر کاربری که می‌خواهد وارد اپلیکیشن شود. چگونه؟ تنها کاری که مهاجم باید انجام دهد این است که از علامت کامنت SQL، یعنی — استفاده کند تا شرط بررسی پسورد را از عبارت WHERE در کوئری حذف کند. به عنوان مثال، اگر مهاجم یوزرنیم “administrator” را به این شکل وارد کند:

administrator’–

و پسورد را خالی بگذارد، کوئری SQL به این صورت ارسال می‌شود:

SELECT * FROM users WHERE username = ‘administrator’– AND password = ”

در این کوئری، علامت — باعث می‌شود که قسمت مربوط به پسورد به‌عنوان کامنت در نظر گرفته شود و دیگر در بررسی صحت پسورد هیچ نقشی نداشته باشد. در صورتی که یوزرنیم “administrator” در دیتابیس وجود داشته باشد، مهاجم بدون نیاز به پسورد به‌طور موفقیت‌آمیز وارد حساب کاربری “administrator” می‌شود.

دستیابی به داده‌های جدول‌های دیگر (UNION Attack)

زمانی که نتایج یک کوئری SQL در پاسخ‌های اپلیکیشن نمایش داده می‌شوند، مهاجم می‌تواند از آسیب‌پذیری SQL Injection برای استخراج داده‌ها از جدول‌های دیگر پایگاه داده نیز استفاده کند. این کار با استفاده از دستور UNION انجام می‌شود. دستور UNION به مهاجم این امکان را می‌دهد که یک کوئری SELECT اضافی اجرا کرده و نتایج آن را به کوئری اصلی الحاق کند.

برای مثال، اگر یک اپلیکیشن کوئری زیر را اجرا کند که ورودی کاربر، یعنی “Gifts” را دریافت می‌کند:

SELECT name, description FROM products WHERE category = ‘Gifts’

مهاجم می‌تواند ورودی خود را به شکل زیر وارد کند:

‘ UNION SELECT username, password FROM users–

با این کار، کوئری SQL ارسال‌شده به شکل زیر درمی‌آید:

SELECT name, description FROM products WHERE category = ‘Gifts’ UNION SELECT username, password FROM users–

این کوئری به جای بازگرداندن فقط نام و توضیحات محصولات در دسته‌بندی “هدایا”، علاوه بر آن‌ها، یوزرنیم‌ها و پسوردهای موجود در جدول users را نیز نمایش می‌دهد. به این ترتیب، مهاجم قادر خواهد بود به اطلاعات حساسی مانند یوزرنیم‌ها و پسوردهای کاربران دست یابد.

وارسی دیتابیس (Examining the Database)

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

برای مثال، اگر دیتابیس مورد نظر Oracle باشد، برای استخراج نسخه‌ی آن، دستور زیر مورد استفاده قرار می‌گیرد:

SELECT * FROM v$version

همچنین، برای به دست آوردن لیستی از جداول موجود در دیتابیس، اغلب می‌توان از دستور زیر استفاده کرد:

SELECT * FROM information_schema.tables

این دستور در اکثر دیتابیس‌ها کار می‌کند و فهرستی از جداول موجود در دیتابیس را نمایش می‌دهد.

تزریق SQL کور (Blind SQL Injection)

تزریق SQL کور (Blind SQL Injection)

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

در Blind SQL Injection، مهاجم می‌تواند از روش‌های مختلفی برای استخراج اطلاعات استفاده کند. یکی از این روش‌ها تغییر در منطق کوئری SQL است تا در پاسخ اپلیکیشن، تغییراتی مشاهده شود که به صحت یا عدم صحت منطق کوئری بستگی دارد. برای این کار، مهاجم ممکن است شرط‌هایی را به کوئری اضافه کند که باعث بروز خطاهای خاص، مانند خطای تقسیم بر صفر، شود. این خطاها می‌توانند به مهاجم کمک کنند تا نوع دیتابیس یا اطلاعات مربوط به ساختار آن را شناسایی کند.

یکی دیگر از روش‌های مورد استفاده در Blind SQL Injection ایجاد تاخیرهای زمانی در پردازش کوئری‌هاست. در این روش، مهاجم می‌تواند به‌گونه‌ای کوئری را طراحی کند که در صورت صحیح بودن یک شرط خاص، زمان پاسخ‌دهی سیستم افزایش یابد. با اندازه‌گیری مدت زمان تاخیر، مهاجم می‌تواند از صحت یا عدم صحت شرایط مطلع شود و به این ترتیب اطلاعاتی را استخراج کند.

در شرایطی که تکنیک‌های دیگر کارایی نداشته باشند، مهاجم می‌تواند از تکنیک‌های Out-of-Band (OAST) برای برقراری ارتباط خارج از باند استفاده کند. این تکنیک به‌ویژه زمانی که سایر روش‌ها ناکارآمد هستند، به‌طور مؤثری عمل می‌کند. با استفاده از OAST، مهاجم می‌تواند داده‌ها را از طریق کانال‌های خارج از باند، مانند درخواست‌های DNS، استخراج کند. در این روش، داده‌ها به دامنه‌ای که تحت کنترل مهاجم است ارسال می‌شود، و این امکان را فراهم می‌کند که اطلاعات از سیستم هدف به‌طور غیرمستقیم به مهاجم منتقل شود.

شناسایی آسیب‌پذیری‌های SQL Injection

برای شناسایی آسیب‌پذیری‌های SQL Injection، روش‌های مختلفی وجود دارد که یکی از مؤثرترین و سریع‌ترین آن‌ها استفاده از اسکنر آسیب‌پذیری وب Burp Suite است. با این حال، این آسیب‌پذیری‌ها را می‌توان به‌صورت دستی و با انجام تست‌های دقیق و نظام‌مند روی تمام درگاه‌های ورود داده به اپلیکیشن نیز شناسایی کرد. در این بخش، به برخی از مهم‌ترین تست‌هایی که برای شناسایی SQL Injection انجام می‌شوند، اشاره می‌کنیم:

  1. تست با استفاده از کاراکتر Quote: یکی از ساده‌ترین و مؤثرترین روش‌ها برای شناسایی آسیب‌پذیری‌های SQL Injection، وارد کردن یک کاراکتر quote (‘) به داخل فیلدهای ورودی است. این کار معمولاً باعث ایجاد خطاهای خاص در کوئری‌های SQL می‌شود و می‌تواند نشان‌دهنده وجود آسیب‌پذیری باشد.
  2. تست با دستورات SQL مختلف: در این روش، می‌توانید چند دستور SQL با املای متفاوت وارد کنید که مقادیر پایه (مقدار اصلی) فیلد ورود داده را ارزیابی کنند. سپس دستورات دیگری که مقادیر متفاوتی را ارزیابی می‌کنند، وارد کرده و تغییرات در پاسخ‌های اپلیکیشن را بررسی می‌کنید. این تفاوت‌ها می‌توانند نشان‌دهنده آسیب‌پذیری SQL Injection باشند.
  3. تست با شرایط بولی: وارد کردن شرایط بولی مانند OR 1=1، OR 1=2 یا AND یکی از رایج‌ترین تکنیک‌ها برای شناسایی SQL Injection است. این روش به شما کمک می‌کند تا تفاوت‌های احتمالی در پاسخ‌های اپلیکیشن را بررسی کرده و متوجه وجود آسیب‌پذیری شوید.
  4. تست با پی‌لودهای زمان‌بندی (Time-based Payloads): در این روش، پی‌لودهایی وارد می‌کنید که به‌گونه‌ای طراحی شده‌اند که هنگام اجرای کوئری SQL، تاخیر زمانی ایجاد کنند. با بررسی مدت زمان پاسخ اپلیکیشن، می‌توانید متوجه شوید که آیا کوئری SQL اجرا شده است یا خیر و از این طریق آسیب‌پذیری‌های SQL Injection را شناسایی کنید.
  5. تست با پی‌لودهای OAST: یکی از پیشرفته‌ترین روش‌ها برای شناسایی SQL Injection، استفاده از پی‌لودهای OAST (Out-of-Band SQL Injection Payloads) است. این پی‌لودها به‌گونه‌ای طراحی می‌شوند که باعث تعامل خارج از باند در شبکه شوند، مانند ارسال درخواست‌های DNS. با مانیتورینگ این تعامل‌ها، می‌توانید وجود آسیب‌پذیری SQL Injection را تشخیص دهید.

تزریق SQL در بخش‌های مختلف کوئری

آسیب‌پذیری‌های SQL Injection معمولا در کوئری‌های WHERE و SELECT ظاهر می‌شوند. متخصصان امنیتی که در زمینه تست نفوذ فعالیت دارند، معمولا با این نوع آسیب‌پذیری آشنایی دارند و قادرند آن را شناسایی کنند. با این حال، تزریق SQL می‌تواند در بخش‌های مختلفی از کوئری رخ دهد و در انواع مختلف کوئری‌ها دیده شود. بخش‌های دیگر که ممکن است دچار آسیب‌پذیری تزریق SQL شوند، شامل موارد زیر هستند:

دستورات UPDATE: در مقادیر به‌روزرسانی‌شده یا شرایط WHERE

دستورات INSERT: در مقادیر وارد شده

دستورات SELECT: در نام جداول یا ستون‌ها

دستورات SELECT: در عبارت ORDER BY

تزریق SQL مرتبه دو

تزریق SQL مرتبه دو

تزریق SQL مرتبه یک زمانی رخ می‌دهد که ورودی کاربر از یک ریکوئست HTTP گرفته می‌شود و به‌طور ناایمن در یک کوئری SQL استفاده می‌شود. اما تزریق SQL مرتبه دو (که به آن “تزریق SQL ذخیره‌شده” نیز گفته می‌شود) زمانی اتفاق می‌افتد که ورودی کاربر دریافت شده و برای استفاده‌های آینده ذخیره می‌شود. این ذخیره‌سازی معمولا در یک دیتابیس انجام می‌شود، و در این مرحله هیچ‌گونه آسیب‌پذیری وجود ندارد.

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

تزریق SQL مرتبه دو معمولا زمانی رخ می‌دهد که توسعه‌دهندگان از آسیب‌پذیری‌های SQL Injection آگاه هستند و از روش‌های ایمن برای وارد کردن داده‌ها به دیتابیس استفاده می‌کنند. اما هنگام پردازش داده‌ها در مراحل بعدی، به اشتباه فرض می‌شود که داده‌ها ایمن هستند چون قبلاً به روش ایمن ذخیره شده‌اند. در این مرحله، این داده‌ها به‌طور غیرایمن استفاده می‌شوند.

عوامل وابسته به دیتابیس

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

روش‌های ترکیب رشته‌ها: نحوه پیاده‌سازی ترکیب یا الحاق رشته‌ها در SQL ممکن است در هر دیتابیس متفاوت باشد. این تفاوت‌ها می‌توانند روی شیوه نوشتن کوئری‌ها تاثیر بگذارند.

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

استفاده از کوئری‌های Batched (یا Stacked): برخی از دیتابیس‌ها از امکان اجرای چندین دستور SQL در یک کوئری واحد (Batched Queries) پشتیبانی می‌کنند. این امر می‌تواند به مهاجم این اجازه را بدهد که دستورات مختلف را همزمان اجرا کند و از آسیب‌پذیری‌ها بهره‌برداری کند.

API های اختصاصی پلتفرم: هر دیتابیس ممکن است APIهای خاصی برای ارتباط با آن داشته باشد. این APIها می‌توانند روش‌های متفاوتی برای اجرای دستورات SQL ارائه دهند که ممکن است بر روی شیوه‌های شناسایی و اکسپلویت SQL Injection تاثیر بگذارند.

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

چگونه از تزریق SQL جلوگیری کنیم؟

چگونه از تزریق SQL جلوگیری کنیم؟

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

برای مثال، در کد زیر ورودی کاربر به‌طور مستقیم در کوئری SQL وارد می‌شود که باعث آسیب‌پذیری در برابر SQL Injection می‌شود:

String query = “SELECT * FROM products WHERE category = ‘” + input + “‘”;

Statement statement = connection.createStatement();

ResultSet resultSet = statement.executeQuery(query);

در این حالت، اگر ورودی کاربر حاوی دستور SQL مخرب باشد، می‌تواند به راحتی در کوئری تزریق شود. اما با استفاده از کوئری‌های پارامتری می‌توان این مشکل را حل کرد:

PreparedStatement statement = connection.prepareStatement(“SELECT * FROM products WHERE category = ?”);

statement.setString(1, input);

ResultSet resultSet = statement.executeQuery();

در این روش، ورودی کاربر به‌عنوان پارامتر به کوئری اضافه می‌شود و به طور ایمن پردازش می‌شود.

استفاده از کوئری‌های پارامتری زمانی که ورودی کاربر در قسمت‌هایی از کوئری وارد می‌شود که ممکن است غیرقابل اطمینان باشند، مانند مقادیر در عبارات WHERE یا در دستورات INSERT و UPDATE توصیه می‌شود. اما باید توجه داشت که این روش نمی‌تواند برای بخش‌هایی مانند نام جدول‌ها یا ستون‌ها، یا عبارات ORDER BY استفاده شود. برای ایمن کردن این قسمت‌ها، باید از روش‌های دیگری استفاده کرد. به عنوان مثال، می‌توان یک لیست سفید از مقادیر مجاز ایجاد کرد یا از منطق‌های دیگری برای تعیین رفتارهای مورد نیاز استفاده کرد.

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

نتیجه‌گیری

SQL Injection یکی از خطرات بزرگ برای امنیت اپلیکیشن‌های وب است که می‌تواند به دسترسی غیرمجاز به داده‌ها و دستکاری سیستم‌های داخلی منجر شود. برای پیشگیری از این آسیب‌پذیری، استفاده از کوئری‌های پارامتری، اعتبارسنجی ورودی‌ها و ایجاد لیست سفید برای مقادیر مجاز از جمله روش‌های مؤثر هستند. با این حال، توجه به جزئیات در نحوه پیاده‌سازی این روش‌ها و استفاده از بهترین شیوه‌ها برای محافظت از اپلیکیشن ضروری است.

برای اطمینان از امنیت بیشتر در پروژه‌های وب، می‌توانید از منابع و ابزارهای تخصصی موجود درتیم امنیت مجموعه فریا بهره‌برداری کنید. فریا به شما کمک می‌کند تا با جدیدترین تکنیک‌های امنیتی، اپلیکیشن‌هایتان را در برابر تهدیدات مختلف از جمله SQL Injection، مقاوم کنید.

رفرنس

این مقاله شالوده ای از محتوای What is SQL Injection? که در یک مقاله جامع به همین نام در وبسایت portswigger.net با نام What is SQL Injection? Tutorial & Examples تهیه و ترجمه شده و در آن نویسنده اندکی نظرات خیش را نیز افزوده است.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *