تصدیق کو بائی پاس کرنا
admin' OR '1'='1WHERE شرط کو ہمیشہ درست بنا کر لاگ اِن بائی پاس کرنے کی کوشش
صارف کی فراہم کردہ ویلیوز کبھی SQL ٹیکسٹ میں انٹرپولیٹ نہیں کی جاتیں — ویلیوز پیرامیٹر پلیس ہولڈرز کے ذریعے بائنڈ کی جاتی ہیں (ڈائلیکٹ کے لحاظ سے، مثلاً $1 یا ?)
SQL انجیکشن آج بھی ویب ایپلیکیشنز کی سب سے سنگین کمزوریوں میں سے ایک ہے
SQL انجیکشن تب ہوتا ہے جب ناقابلِ اعتماد ڈیٹا کو محفوظ پیرامیٹر بائنڈنگ کے بغیر SQL ٹیکسٹ میں شامل کیا جائے۔ حملہ آور کوئری کا مطلب بدل کر غیر مجاز ڈیٹا تک رسائی حاصل کر سکتے ہیں، ریکارڈز میں ترمیم کر سکتے ہیں، یا غیر ارادی آپریشنز چلا سکتے ہیں۔
admin' OR '1'='1WHERE شرط کو ہمیشہ درست بنا کر لاگ اِن بائی پاس کرنے کی کوشش
' UNION SELECT password FROM users--دوسرے ٹیبلز سے ڈیٹا نکالنے کی کوشش کے لیے UNION کا استعمال
'; DROP TABLE users; --ڈیٹا حذف کرنے کے لیے اضافی اسٹیٹمنٹس جوڑنے کی کوشش
استحصال: اگر پلیس ہولڈرز اور پیرامیٹرز میں مطابقت نہ ہو تو اجازت کی جانچ غلط ویلیوز استعمال کر سکتی ہےمثال: WHERE userId=$1 AND isAdmin=$2، لیکن [123, true] کی بجائے params=[true, 123] غلطی سے ایڈمن رسائی دے سکتا ہے
ہر کوئری کئی سیکیورٹی توثیقی لیئرز سے گزرتی ہے
صارف کی تمام فراہم کردہ ویلیوز بائنڈڈ پیرامیٹرز میں تبدیل کی جاتی ہیں۔ ویلیوز لٹرلز کے طور پر SQL ٹیکسٹ میں داخل نہیں ہوتیں۔
کوئری تیار ہونے سے پہلے ہر فیلڈ نام کی Prisma اسکیما میٹا ڈیٹا کے مقابل توثیق کی جاتی ہے۔
ٹیبل نام، کالم نام اور ایلیاسز کی توثیق کی جاتی ہے اور ضرورت کے مطابق انہیں محفوظ طریقے سے کوٹ/ایسکیپ کیا جاتا ہے۔
ہر فیلڈ ٹائپ کے لیے صرف معلوم اور محفوظ آپریٹرز کی اجازت ہے۔
سخت ترتیب یقینی بناتی ہے کہ ہر پلیس ہولڈر اندراج کی ترتیب میں بالکل ایک پیرامیٹر سے میپ ہو، جس سے عدم مطابقت نہیں ہوتی۔
بیان کردہ ڈیزائن مفروضات (پیرامیٹر بائنڈنگ، خام SQL سے کوئی بائی پاس نہیں، ڈرائیور کا درست استعمال) کے تحت انجیکشن مزاحمت کے ثبوت کے خاکے
صارف کی فراہم کردہ تمام ویلیوز V کے لیے، ایسا کوئی ایگزیکیوشن پاتھ موجود نہیں جہاں V تیار کردہ کوئری اسٹرنگ میں SQL ٹیکسٹ کے طور پر ظاہر ہو۔
ساخت کے لحاظ سے، صارف کی ویلیوز ہینڈل کرنے والے تمام کوڈ پاتھس addParameter(value) کال کرتے ہیں، جو: 1. ویلیو کو ایک الگ params ارے میں محفوظ کرتا ہے 2. SQL ٹیکسٹ کے لیے ایک پلیس ہولڈر ٹوکن واپس کرتا ہے 3. SQL اسٹرنگ میں صرف پلیس ہولڈر ٹوکن جوڑا جاتا ہے 4. ڈیٹابیس ڈرائیور SQL ٹیکسٹ اور پیرامیٹر ویلیوز الگ الگ وصول کرتا ہے ∴ صارف کی ویلیوز SQL سنٹیکس کے طور پر پارس نہیں ہوتیں
const addParameter = (params: any[], value: any) => {
params.push(value)
const index = params.length
return `$${index}`
}کسی بھی تیار کردہ کوئری میں فیلڈ ناموں کا سیٹ F، اسکیما میں متعین فیلڈز S کا ذیلی سیٹ ہے، یعنی F ⊆ S۔
ہر فیلڈ ریفرنس کے لیے: 1. کوئری آبجیکٹ سے فیلڈ نام نکالا جاتا ہے 2. اسکیما میٹا ڈیٹا میں تلاش کی جاتی ہے 3. اگر فیلڈ اسکیما میں موجود نہ ہو تو ایرر پھینکا جاتا ہے 4. صرف توثیق شدہ فیلڈز SQL کی تیاری تک پہنچتے ہیں ∴ من مانے فیلڈ نام SQL میں ظاہر نہیں ہو سکتے
const validateField = (field: string, model: Model) => {
if (!model.fields.has(field)) {
throw new Error(`Field ${field} does not exist`)
}
return model.fields.get(field)
}فیلڈ F پر لاگو کسی بھی آپریٹر O کے لیے، O فیلڈ F کی ٹائپ T کے لیے اجازت یافتہ آپریٹرز میں شامل ہے۔
آپریٹر کی توثیق کا الگورتھم: 1. اسکیما سے فیلڈ ٹائپ T نکالیں 2. allowed_ops(T) = { ٹائپ T کے درست آپریٹرز } متعین کریں 3. کوئری میں آپریٹر O کے لیے: - اگر O ∉ allowed_ops(T)، تو ایرر پھینکیں - ورنہ پیرامیٹر بائنڈنگ کے ساتھ آپریٹر لاگو کریں ∴ صرف ٹائپ کے مطابق آپریٹرز استعمال ہو سکتے ہیں
const ALLOWED_OPS: Record<string, string[]> = {
String: ['contains', 'startsWith', 'endsWith'],
Int: ['lt', 'lte', 'gt', 'gte']
}
if (!ALLOWED_OPS[fieldType]?.includes(operator)) {
throw new Error('Invalid operator')
}تمام SQL آئیڈینٹیفائرز I کی توثیق کی جاتی ہے تاکہ کنٹرول کریکٹرز روکے جائیں اور ہر ڈائلیکٹ کے مطابق محفوظ کوٹنگ/ایسکیپنگ یقینی ہو۔
آئیڈینٹیفائر پروسیسنگ: 1. کنٹرول کریکٹرز ہوں تو مسترد کریں 2. اندرونی کوٹ کریکٹرز کو ڈائلیکٹ کے اصولوں کے مطابق ایسکیپ کریں 3. ضرورت ہو تو آئیڈینٹیفائرز کو کوٹ کریں (مخصوص کلیدی الفاظ یا خاص کریکٹرز) 4. ہر ڈائلیکٹ کی آئیڈینٹیفائر لمبائی کی حد نافذ کریں ∴ آئیڈینٹیفائرز SQL سنٹیکس نہیں توڑ سکتے اور نہ ہی انجیکٹ شدہ ٹوکنز شامل کر سکتے ہیں
const quoteIdentifier = (id: string) => {
if (/[\x00-\x1F]/.test(id)) {
throw new Error('Invalid characters')
}
const escaped = id.replace(/"/g, '""')
const needsQuoting = /[^a-z0-9_]/i.test(id) || isReservedKeyword(id)
return needsQuoting ? `"${escaped}"` : id
}SQL ٹیکسٹ میں شامل ہر پلیس ہولڈر پوزیشن N کے لیے، params[N-1] میں بالکل وہی ویلیو ہوتی ہے جو اس پوزیشن کے لیے مقصود ہے، بغیر کسی ترتیب کی تبدیلی یا عدم مطابقت کے۔
پیرامیٹر ترتیب کی ضمانت: 1. ایک ہی ٹریکر اندراج کی ترتیب برقرار رکھتا ہے 2. ہر add() کال ویلیو کو params میں جوڑتی ہے اور فوراً اگلا پلیس ہولڈر ٹوکن جاری کرتی ہے 3. SQL ٹیکسٹ اور params کی تعمیر ساتھ ساتھ (lockstep) ہوتی ہے 4. کوئی درمیانی ترتیب بدلنے والا آپریشن نہیں ہوتا ∴ پورے عمل میں یک بہ یک مطابقت برقرار رہتی ہے
class ParameterTracker {
private params: any[] = []
add(value: any): string {
this.params.push(value)
return `$${this.params.length}`
}
getParams(): any[] {
return this.params
}
}
const tracker = new ParameterTracker()
const sql = `WHERE email = ${tracker.add(email)} AND age > ${tracker.add(age)}`
const params = tracker.getParams()موجودہ سوٹ SQL انجیکشن کے عام طریقوں اور ایج کیسز کے خلاف تحفظ کی توثیق کرتا ہے
const email = req.body.email
const sql = "SELECT * FROM users WHERE email = '" + email + "'"const email = req.body.email
const { sql, params } = toSQL('User', 'findMany', {
where: { email }
})
const result = { sql, params }مرکزی پیرامیٹر ٹریکنگ یقینی بناتی ہے کہ صارف کی ہر فراہم کردہ ویلیو پیرامیٹر بائنڈڈ ہو اور اس کی ترتیب مستحکم رہے
class ParameterTracker {
private params: any[] = []
add(value: any): string {
this.params.push(value)
return `$${this.params.length}`
}
getParams(): any[] {
return this.params
}
}اسکیما پر مبنی توثیق من مانی فیلڈ رسائی کو روکتی ہے
function validateField(
fieldName: string,
model: ModelInfo
): FieldInfo {
const field = model.fields.get(fieldName)
if (!field) {
throw new Error(
`Field "${fieldName}" does not exist`
)
}
return field
}ڈائلیکٹ سے آگاہ آئیڈینٹیفائر توثیق اور کوٹنگ آئیڈینٹیفائر پر مبنی سنٹیکس انجیکشن کو روکتی ہے
function quoteIdentifier(identifier: string): string {
if (/[\x00-\x1F]/.test(identifier)) {
throw new Error('Invalid control characters')
}
const escaped = identifier.replace(/"/g, '""')
const needsQuoting = /[^a-z0-9_]/i.test(identifier) || isReservedKeyword(identifier)
if (needsQuoting) {
return `"${escaped}"`
}
return identifier
}اسکیما کی توثیق یا فیلڈ کی جانچ کو بائی پاس نہ کریں۔ یہ اہم سیکیورٹی لیئرز ہیں۔
یقینی بنائیں کہ آپ کا Prisma اسکیما آپ کے ڈیٹابیس کی ساخت کی درست عکاسی کرتا ہے۔
TypeScript کمپائل ٹائم سیفٹی دیتا ہے، لیکن رن ٹائم توثیق دفاع کی ایک اور تہہ شامل کرتی ہے۔
بے ضابطگیوں اور غلط استعمال کا پتا لگانے کے لیے پروڈکشن میں تیار کردہ SQL اور پیرامیٹرز کو لاگ کریں اور ان کی نگرانی کریں۔
SQL انجیکشن سے تحفظ اس لائبریری کی ہر لیئر میں شامل ہے۔ سیکیورٹی ٹیسٹس اور عمل درآمد کی تفصیلات کا براہِ راست جائزہ لیں۔