SQL Injection ایپلیکیشن ڈیٹابیس پر حملے کی ایک قسم ہے جس میں حملہ آور کیری پیرامیٹرز میں نقصان دہ SQL کوڈ داخل کرتا ہے، ڈیٹا تک غیر مجاز رسائی یا ان میں تبدیلی کی صلاحیت حاصل کرتا ہے۔ OWASP (2025) کے مطابق، SQL Injection ان اہم کمزوریوں میں سے ایک ہے جو ڈیٹابیس سے مکمل سمجھوتہ کر سکتی ہے۔ SQL کوڈ انجیکشن حملہ آور کو ریکارڈ پڑھنے، تبدیل کرنے اور حذف کرنے کی اجازت دیتا ہے، اور بعض صورتوں میں، سرور کے آپریٹنگ سسٹم تک رسائی حاصل کرنے کی بھی۔
اہم نکات
SQL Injection ایک کمزوری ہے جو اس وقت پیدا ہوتی ہے جب کوئی ایپلیکیشن صارف کے ڈیٹا کے ساتھ سٹرنگ کنکاٹینیشن کے ذریعے SQL کیری بناتی ہے۔ حملہ آور کیری پیرامیٹر میں خاص طور پر تیار کردہ ایک سٹرنگ داخل کرتا ہے جو SQL کمانڈ کی ساخت کو تبدیل کر دیتی ہے۔ ڈیٹا ہونے کے بجائے، داخل کردہ سٹرنگ SQL کوڈ کا حصہ بن جاتی ہے، جس سے حملہ آور ڈیٹابیس پر من مانی کیری عملدرآمد کر سکتا ہے۔ Verizon ڈیٹا کی خلاف ورزی رپورٹ (2025) کے مطابق، SQL Injection تمام تحقیقات کردہ ڈیٹا کی خلاف ورزیوں میں 8% میں موجود ہے۔
ایک معروف کمزوری ہونے کے باوجود (پہلی بار 1990 کی دہائی کے آخر میں ذکر)، SQL Injection جدید ایپلیکیشنز میں اب بھی پایا جاتا ہے۔ اس کی وجہ انسانی غلطی ہے: ڈویلپر سٹرنگ کنکاٹینیشن والا کوڈ لکھتے ہیں، پرانا کوڈ ری فیکٹر نہیں کیا جاتا، اور ORM فریم ورک غلط طریقے سے استعمال ہوتے ہیں (مثلاً، سٹرنگ انٹرپولیشن والی خام کیری)۔ Veracode (2026) کے مطابق، اسکین کردہ تمام ایپلیکیشنز میں سے تقریباً 14% میں کم از کم ایک SQLi کمزوری ہوتی ہے۔
ایک کامیاب SQL Injection حملہ آور کو وسیع صلاحیتیں دیتا ہے: پاس ورڈ ہیش اور صارفین کے ذاتی ڈیٹا سمیت کسی بھی ڈیٹابیس جدول کو پڑھنا؛ ریکارڈ کو تبدیل اور حذف کرنا؛ انتظامی کارروائیاں انجام دینا (DROP TABLE, TRUNCATE)؛ اور بعض کنفیگریشنز میں، xp_cmdshell (MSSQL) یا INTO OUTFILE (MySQL) کے ذریعے دور دراز کمانڈ عملدرآمد۔ نتائج صارف کے ڈیٹا کے اخراج سے لے کر سسٹم پر مکمل کنٹرول کھونے تک ہوتے ہیں۔
SQL انجیکشن کو ڈیٹابیس سے ڈیٹا نکالنے کے طریقہ کے مطابق درجہ بند کیا جاتا ہے۔ طریقہ کا انتخاب اس بات پر منحصر ہے کہ ایپلیکیشن کیری کے نتائج اور خرابی کے پیغامات کو کیسے ہینڈل کرتی ہے۔ OWASP درجہ بندی تین اہم اقسام کی نشاندہی کرتی ہے: In-band (اسی چینل کے ذریعے ڈیٹا نکالنا)، Inferential/Blind (منطقی اندازے)، اور Out-of-band (دوسرے چینل کے ذریعے ڈیٹا منتقل کرنا)۔
| قسم | ڈیٹا نکالنے کا طریقہ | پیچیدگی | تعدد |
|---|---|---|---|
| In-band (کلاسک) | براہ راست کیری کے نتیجہ کے ذریعے | کم | زیادہ |
| Blind SQLi | سرور کے جوابات سے منطقی اندازے | زیادہ | درمیانہ |
| Out-of-band | بیرونی چینل (DNS, HTTP) کے ذریعے | درمیانہ | کم |
سب سے عام قسم۔ حملہ آور کیری پیرامیٹر میں SQL کوڈ داخل کرتا ہے، اور انجیکشن کا نتیجہ براہ راست سرور کے جواب میں نظر آتا ہے۔ دو ذیلی اقسام: Error-based (DB خرابی کے پیغامات کے ذریعے) اور UNION-based (UNION SELECT آپریٹر کے ذریعے)۔ Error-based خرابی کے پیغامات سے معلومات استعمال کرتا ہے، جیسے MySQL نحو کی خرابی جو جدول کا نام یا کیری کی ساخت ظاہر کر سکتی ہے۔ UNION-based جائز کیری کے نتائج کو ڈیٹابیس کے دوسرے جدولوں کے ڈیٹا کے ساتھ جوڑنے کی اجازت دیتا ہے۔
جب ایپلیکیشن کیری کے نتائج یا خرابی کے پیغامات ظاہر نہیں کرتی تو استعمال کیا جاتا ہے۔ حملہ آور منطقی شرائط والی کیری بھیج کر اور سرور کے جوابات (مثلاً، جوابی وقت یا صفحہ کے مواد) میں فرق کا تجزیہ کرکے ہاں/نہیں سوالات پوچھتا ہے۔ Time-based Blind SQLi شرائط کی تصدیق کے لیے تاخیر کے فنکشنز (SLEEP, WAITFOR DELAY) استعمال کرتا ہے — اگر صفحہ لوڈ ہونے میں زیادہ وقت لیتا ہے، شرط درست ہے۔ یہ طریقہ بہت سست ہے — ایک ریکارڈ نکالنے میں گھنٹے لگ سکتے ہیں۔
# Blind SQL Injection کی مثال (وقت پر مبنی)
# اگر SQLi کمزور ہے، SLEEP(2) شرط پوری ہونے پر عملدرآمد کرتا ہے
import requests
import time
payload = "' OR IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a',SLEEP(2),0) -- "
url = "http://example.com/user?id=1" + payload
start = time.time()
response = requests.get(url)
elapsed = time.time() - start
# اگر جواب >2 سیکنڈ بعد آتا ہے — پاس ورڈ کا پہلا حرف 'a' ہے
print(f"Time: {elapsed:.2f}s - First letter is 'a'" if elapsed > 2 else "First letter is not 'a'")
ڈیٹا HTTP جواب کے ذریعے نہیں بلکہ متبادل چینلز (DNS کیریز، بیرونی سرور کو HTTP درخواستیں، SMTP) کے ذریعے منتقل کیا جاتا ہے۔ جب ایپلیکیشن کیری کے نتائج واپس نہیں کرتی یا خرابیاں نہیں دکھاتی تو استعمال کیا جاتا ہے۔ MySQL LOAD_FILE() فنکشن کو سپورٹ کرتا ہے، جو DNS کیری شروع کر سکتا ہے، اور MSSQL میں دور دراز SMB سرور کو ڈیٹا بھیجنے کے لیے xp_dirtree ہے۔ Out-of-band SQL Injection مؤثر ہے لیکن اس کے لیے اضافی حملہ آور سرور سیٹ اپ اور مخصوص DB فنکشنز کی ضرورت ہوتی ہے۔
SQL Injection کا طریقہ کار اس حقیقت پر مبنی ہے کہ SQL سٹرنگ لٹریلز کے لیے اقتباس استعمال کرتا ہے۔ اگر کوئی ایپلیکیشن صارف کے ان پٹ کو بغیر escape کیے براہ راست SQL کیری میں داخل کرتی ہے، تو حملہ آور سٹرنگ کو “بند” کر سکتا ہے اور من مانی SQL کوڈ شامل کر سکتا ہے۔ مثال کے طور پر، کیری SELECT * FROM users WHERE name = '$input' میں، ' OR '1'='1 داخل کرنے سے یہ SELECT * FROM users WHERE name = '' OR '1'='1' میں تبدیل ہو جاتی ہے، جو تمام صارفین کو لوٹاتی ہے۔
کیری SELECT * FROM users WHERE username = '$user' AND password = '$pass' والے لاگ ان فارم پر غور کریں۔ اگر حملہ آور صارف نام کے فیلڈ میں admin' -- داخل کرتا ہے اور پاس ورڈ خالی چھوڑ دیتا ہے، نتیجے میں کیری SELECT * FROM users WHERE username = 'admin' -- ' AND password = '' بن جاتی ہے۔ -- حروف بقیہ کیری کو کمنٹ کر دیتے ہیں، پاس ورڈ کی جانچ کو غیر فعال کر دیتے ہیں۔ سرور ایڈمن صارف کا ریکارڈ لوٹاتا ہے، اور حملہ آور پاس ورڈ جانے بغیر لاگ ان کر لیتا ہے۔
# SQL Injection کی مثال — تصدیق کو نظرانداز کرنا
# کمزور کوڈ: براہ راست سٹرنگ کنکاٹینیشن
def login_vulnerable(username, password):
query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
cursor.execute(query)
return cursor.fetchone() is not None
# username = "admin' --" پاس ورڈ کی جانچ کو کالعدم کرتا ہے
# محفوظ ورژن: پیرامیٹرائزڈ کیری
def login_secure(username, password):
query = "SELECT * FROM users WHERE username = %s AND password = %s"
cursor.execute(query, (username, password))
return cursor.fetchone() is not None
UNION SELECT آپریٹر دو SELECT کیریز کے نتائج کو جوڑنے کی اجازت دیتا ہے۔ اگر حملہ آور کو کوئی کمزور پیرامیٹر ملتا ہے، تو وہ دوسرے جدول سے کیری کے ساتھ UNION SELECT شامل کرتا ہے۔ مثال: ' UNION SELECT username, password FROM admins --. کامیابی کی شرط یہ ہے کہ دونوں کیریز میں کالمز کی تعداد برابر ہونی چاہیے۔ کالمز کی تعداد ORDER BY کے ذریعے متعین کی جاتی ہے (' ORDER BY 1--، پھر 2، 3... جب تک خرابی نہ آئے)۔ کالمز کی تعداد جان کر، حملہ آور اتنی ہی تعداد میں فیلڈز کے ساتھ UNION SELECT داخل کرتا ہے۔
موبائل ایپلیکیشنز سرور سائڈ (API) اور کلائنٹ سائڈ — مقامی ڈیٹابیسز (SQLite, Realm) دونوں پر SQL Injection کا سامنا کرتی ہیں۔ جبکہ موبائل API میں سرور سائڈ SQLi ویب ایپلیکیشنز کی طرح ہے، مقامی ڈیٹابیسز ایک اضافی ویکٹر بناتے ہیں۔ اگر کوئی ایپلیکیشن SQLite میں ڈیٹا ذخیرہ کرتی ہے اور سٹرنگ کنکاٹینیشن کے ساتھ کیریز چلاتی ہے، تو API کے ذریعے مقامی ڈیٹابیس میں داخل ہونے والا نقصان دہ ڈیٹا بعد کی پروسیسنگ کے دوران SQLi کو متحرک کر سکتا ہے۔
ڈیوائس پر مقامی SQLite ڈیٹابیس بھی SQL Injection کے لیے کمزور ہے اگر ایپلیکیشن سٹرنگ کنکاٹینیشن سے کیریز بناتی ہے۔ Android پر Content Providers اور iOS پر Core Data ڈیفالٹ طور پر پیرامیٹرائزیشن استعمال کرتے ہیں، لیکن خام کیریز کے لیے ڈویلپر کی توجہ درکار ہے۔ SQLite سیمیکولن سے الگ کردہ متعدد کیریز کو سپورٹ نہیں کرتا، جو حملہ آور کے اختیارات کو محدود کرتا ہے لیکن WHERE شرائط کے ذریعے ڈیٹا پڑھنے سے نہیں بچاتا۔ Android میں ہمیشہ selectionArgs اور iOS میں پیرامیٹرز کے ساتھ NSPredicate استعمال کریں۔
موبائل ایپلیکیشن جس API سے بات چیت کرتی ہے، وہ کسی بھی ویب سرور کی طرح کمزور ہے۔ موبائل ڈویلپر اکثر سمجھتے ہیں کہ SQLi صرف بیک اینڈ کا مسئلہ ہے، لیکن کمزوری API اینڈ پوائنٹ پر ہوتی ہے جو کلائنٹ سے پیرامیٹرز قبول کرتا ہے۔ ذمہ داریوں کی علیحدگی تحفظ نہیں دیتی: اگر بیک اینڈ ڈویلپر کیری کو پیرامیٹرائز کرنا بھول گیا، تو صارف کی موبائل ایپ حملے کا ویکٹر بن جاتی ہے۔ بیک اینڈ سے ORM یا prepared statements استعمال کرنے کا مطالبہ کریں۔
// Android پر مقامی SQLite میں SQL Injection کی مثال
// کمزور کوڈ: براہ راست کنکاٹینیشن
fun getUserVulnerable(db: SQLiteDatabase, userId: String): Cursor {
return db.rawQuery(
"SELECT * FROM users WHERE id = $userId", null
)
}
// محفوظ ورژن: selectionArgs کے ذریعے پیرامیٹرائزیشن
fun getUserSecure(db: SQLiteDatabase, userId: String): Cursor {
return db.rawQuery(
"SELECT * FROM users WHERE id = ?",
arrayOf(userId)
)
}
SQL Injection سے تحفظ ایک سادہ اصول پر مبنی ہے: SQL کیریز میں صارف کے ان پٹ پر کبھی بھروسہ نہ کریں۔ واحد قابل اعتماد طریقہ کیری پیرامیٹرائزیشن (prepared statements) ہے، جہاں SQL کوڈ اور ڈیٹا علیحدہ علیحدہ بھیجے جاتے ہیں۔ دیگر تمام طریقے — escape کرنا، توثیق، WAF — اضافی تحفظ کی تہیں ہیں لیکن پیرامیٹرائزیشن کا متبادل نہیں ہیں۔ OWASP (2025) کے مطابق، پیرامیٹرائزیشن 100% SQL Injection حملوں کو روکتی ہے۔
Prepared statements استعمال کرتے وقت، SQL کیری پہلے DB سرور کے ذریعے ڈیٹا کے بغیر کمپائل کی جاتی ہے، اور پھر پیرامیٹر کی قدریں علیحدہ بھیجی جاتی ہیں۔ ڈیٹابیس پیرامیٹرز کو قابل عمل کوڈ کے بجائے ڈیٹا کے طور پر دیکھتا ہے۔ یہاں تک کہ اگر حملہ آور ' OR '1'='1 بھیجے، ڈیٹابیس اسے SQL کوڈ کے بجائے ایک سٹرنگ ویلیو سے تعبیر کرتا ہے۔ Prepared statements تمام جدید زبانوں اور فریم ورکس میں سپورٹ ہوتے ہیں: PHP میں PDO، Java میں PreparedStatement، Python میں cursor.execute۔
جدید ORM (Hibernate, Entity Framework, SQLAlchemy, Room) کیریز چلاتے وقت خودکار طور پر پیرامیٹرائزیشن استعمال کرتے ہیں، جب تک کہ ڈویلپر خام کیریز پر سوئچ نہ کرے۔ تاہم، ORM مکمل تحفظ نہیں دیتے: JPA میں @Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true) جیسی ساختوں کے لیے نامزد پیرامیٹرز کے ذریعے پیرامیٹر بھیجنے کی ضرورت ہوتی ہے، کنکاٹینیشن سے نہیں۔ کیری بلڈر (Knex, jOOQ) بھی ڈیفالٹ طور پر کیریز کو پیرامیٹرائز کرتے ہیں اگر خام طریقے استعمال نہ کیے جائیں۔
خصوصی حروف کو escape کرنا (mysql_real_escape_string) ایک پرانا طریقہ ہے جو تمام اقسام کے SQL Injection سے تحفظ نہیں دیتا۔ مسئلہ: escape کرنا انکوڈنگ پر منحصر ہے اور ملٹی بائٹ انکوڈنگز (مثلاً، ایشیائی نظاموں میں GBK) استعمال کرتے وقت نظرانداز کیا جا سکتا ہے۔ escape کرنا صرف پرانے کوڈ میں استعمال کریں جہاں پیرامیٹرائزیشن ممکن نہ ہو، اور ہمیشہ سخت ان پٹ ٹائپ توثیق کے ساتھ۔
| طریقہ | مؤثریت | سفارش |
|---|---|---|
| Prepared Statements | 100% | تمام کیریز کے لیے لازمی |
| ORM (صحیح استعمال) | 99% | سفارش کردہ |
| سٹرنگ escape کرنا | 70% (انکوڈنگ پر منحصر) | صرف پرانا |
| ان پٹ توثیق (سفید فہرست) | 50% (صرف اعداد) | اضافی |
| WAF (Web Application Firewall) | 60% | اضافی |
ایپلیکیشن اکاؤنٹ میں کم سے کم ضروری استحقاق ہونے چاہئیں: SELECT, INSERT, UPDATE, DELETE — صرف ان جدولوں پر جن کی ایپلیکیشن کو حقیقت میں ضرورت ہے۔ ایپلیکیشن اکاؤنٹ کے لیے DROP, TRUNCATE, CREATE کے استعمال پر پابندی لگائیں۔ یہ کامیاب SQL Injection کی صورت میں بھی نقصان کو محدود کرتا ہے: حملہ آور جدولوں کو حذف نہیں کر سکے گا یا انتظامی کارروائیاں انجام نہیں دے سکے گا۔
باقاعدہ SQL Injection جانچ محفوظ ترقیاتی پائپ لائن کا حصہ ہونی چاہیے۔ جامد تجزیہ، متحرک اسکیننگ اور دستی پینیٹریشن ٹیسٹنگ کا امتزاج بہترین نتائج دیتا ہے۔ Synopsys سائبر سیکیورٹی رپورٹ (2025) کے مطابق، خودکار اسکینر 70% تک SQLi کمزوریاں تلاش کر لیتے ہیں، لیکن پیچیدہ Blind حملوں کے لیے دستی جانچ کی ضرورت ہوتی ہے۔
موبائل ایپلیکیشنز کے لیے، مقامی SQLite تجزیہ بھی اہم ہے: تمام rawQuery کالز، ContentProvider کیریز اور rawQuery والی Room کیریز کی جانچ کریں۔ اوزار: Android Studio Lint (SQLite میں SQLi کا پتہ لگاتا ہے)، APK/IPA کے خودکار جامد اور متحرک تجزیہ کے لیے MobSF (Mobile Security Framework)۔ یہ بھی تجویز کی جاتی ہے کہ موبائل ایپلیکیشن کے ٹریفک کے پراکسی مداخلت کے ساتھ sqlmap کے ذریعے API اینڈ پوائنٹس کی جانچ کریں۔
اکثر پوچھے گئے سوالات
SQL Injection SQL کیریز کے ذریعے رلیشنل ڈیٹابیس پر حملہ کرتا ہے۔ NoSQL Injection ان کے کیری آپریٹرز ($gte, $ne, $where) کے ذریعے غیر رلیشنل ڈیٹابیسز (MongoDB, Couchbase) کو متاثر کرتا ہے۔ MongoDB میں، انجیکشن ممکن ہے اگر ایپلیکیشن JSON سٹرنگ سے BSON دستاویز بناتی ہے۔ تحفظ کے طریقہ کار ایک جیسے ہیں: پیرامیٹرائزیشن اور ٹائپ توثیق۔
وہ تمام مقامات تلاش کریں جہاں SQL کیریز صارف کے ڈیٹا کے ساتھ سٹرنگ کنکاٹینیشن سے بنتی ہیں۔ "SELECT ... WHERE id = " + userId یا f"UPDATE ... SET name = '{name}'" جیسے پیٹرن دیکھیں۔ ایسی ہر لائن ممکنہ SQL انجیکشن ہے۔ ان سب کو پیرامیٹرائزڈ کیریز یا prepared statements سے بدل دیں۔
ORM فریم ورک صرف اس وقت خود بخود بچاتے ہیں جب آپ ان کے کیری بلڈر طریقے اور نامزد پیرامیٹرز استعمال کریں۔ اگر آپ خام کیریز (JPA میں nativeQuery، Room میں rawQuery) استعمال کرتے ہیں، تو تحفظ کام نہیں کرتا — آپ کو سٹرنگ کنکاٹینیشن کے ذریعے نہیں بلکہ تیار شدہ اظہار کے ذریعے پیرامیٹر بھیجنے ہوں گے۔
Second-Order SQL Injection ایک حملہ ہے جس میں نقصان دہ ڈیٹا ڈیٹابیس میں محفوظ طریقے سے ذخیرہ کیا جاتا ہے، لیکن پھر اسے بغیر escape کیے کسی اور کیری میں استعمال کیا جاتا ہے۔ مثال کے طور پر، ایک حملہ آور ' OR '1'='1 جیسے صارف نام سے رجسٹر ہوتا ہے۔ ڈیٹا ایک سٹرنگ کے طور پر محفوظ ہوتا ہے — رجسٹریشن پر کوئی حملہ نہیں ہوتا۔ لیکن اگر کوئی اور کیری پیرامیٹرائزیشن کے بغیر SQL میں اس صارف نام کو استعمال کرتی ہے، تو انجیکشن متحرک ہو جاتا ہے۔
NoSQL Injection ڈویلپر کی آگاہی کم ہونے کی وجہ سے ممکنہ طور پر زیادہ خطرناک ہو سکتا ہے۔ ڈویلپر SQL Injection کے بارے میں جانتے ہیں اور زیادہ تر ORM استعمال کرتے ہیں، لیکن بہت کم NoSQL Injection کے بارے میں جانتے ہیں۔ MongoDB میں، نامناسب طریقے سے تشکیل شدہ کیری ایک مجموعہ کے تمام دستاویزات واپس کر سکتی ہے۔ تحفظ وہی ہے — prepared statements (BSON پیرامیٹرائزیشن) اور سخت ان پٹ توثیق۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں