SQL Injection और Prevention
SQL Injection Query कैसे बदलता है
Untrusted input SQL text के साथ executable structure बन जाए तो injection होता है। Secure design SQL template और data अलग रखता है तथा class/tenant authorization भी enforce करता है। Parameterized query भी गलत record दिखा सकती है यदि ownership predicate missing हो।
Injection SELECT, INSERT, UPDATE, DELETE, login, reports, search, ORDER BY और import filters में हो सकता है।
Vulnerable Pattern पहचानें
$email=$_GET['email']??'';
$sql="SELECT student_id,name,email
FROM students WHERE email='$email'";
$rows=$pdo->query($sql)->fetchAll();' OR 1=1 -- जैसा test payload parsing allow करे तो predicate बदल सकता है। Manual escaping complete defense नहीं।
| Red flag | Risk |
|---|---|
| Concatenation | Data SQL grammar बनता है |
| Request से ORDER BY | Keyword/identifier structure है |
| Admin-only unsafe query | Session compromise possible |
| Root connection | Maximum impact |
Native PDO Prepared Statement
$pdo=new PDO(
'mysql:host=db.internal;dbname=school;charset=utf8mb4',
$dbUser,$dbPassword,[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]
);
$stmt=$pdo->prepare(
'SELECT student_id,name,email FROM students
WHERE class_id=:class_id AND email=:email'
);
$stmt->execute([
':class_id'=>$authorizedClassId,
':email'=>$validatedEmail,
]);Correct utf8mb4, exceptions और actual driver पर native prepares test करें। Password/exception browser या log में leak न करें।
Dynamic Identifiers Safely Handle करें
Markers table/column/keyword/ASC-DESC नहीं बनते। Hard-coded mapping रखें:
$sortMap=['name'=>'student_name','date'=>'admission_date'];
$dirMap=['asc'=>'ASC','desc'=>'DESC'];
$sort=$sortMap[$_GET['sort']??'name']??'student_name';
$dir=$dirMap[strtolower($_GET['direction']??'asc')]??'ASC';
$sql="SELECT student_id,student_name FROM students
WHERE class_id=:class ORDER BY `$sort` $dir";
$stmt=$pdo->prepare($sql);
$stmt->execute([':class'=>$authorizedClassId]);SQL structure में केवल mapping values आएँ। Arbitrary input को backticks में डालना authorization नहीं। यही rule table, operator, JOIN और report columns पर लागू है।
LIKE, IN और LIMIT Parameterize करें
$stmt=$pdo->prepare(
'SELECT student_id FROM students
WHERE student_name LIKE :pattern'
);
$stmt->execute([':pattern'=>'%'.$searchText.'%']);
$ids=array_values(array_filter(
$requestedIds,fn($v)=>filter_var($v,FILTER_VALIDATE_INT)!==false
));
if($ids){
$marks=implode(',',array_fill(0,count($ids),'?'));
$stmt=$pdo->prepare(
"SELECT student_id FROM students
WHERE class_id=? AND student_id IN ($marks)"
);
$stmt->execute(array_merge([$authorizedClassId],$ids));
}One marker पूरी IN list नहीं। Empty list behavior और max items तय करें। LIMIT को integer type bind और cap करें। LIKE में %/_ wildcard हैं या literal—policy explicit रखें।
Defense in Depth जोड़ें
- Dedicated host-scoped account; root नहीं।
- Required tables/actions only; migration/backup अलग।
- हर query में class/tenant ownership।
- Verified TLS और secrets outside code।
- Multi-statements disabled unless required।
- Size, timeout, pagination और rate limits।
- Generic user error, protected detailed log।
Stored procedure automatically safe नहीं; उसके dynamic SQL में injection हो सकता है और powerful DEFINER impact बढ़ाता है। least privilege और security पढ़ें।
Boundary Test और Attempts Monitor करें
- Synthetic isolated DB बनाएँ।
- SQL बनाने वाले सभी paths inventory करें।
- Quotes, comments, Unicode, numeric, NULL, long values test करें।
- Unknown sort/filter reject करें।
- Normal request success और shaped data no extra rows assert करें।
- Cross-class/tenant denied रखें।
- Code review/static और authorized dynamic tests।
- Syntax errors, denied requests, unusual exports monitor करें।
Full payload logs में न रखें; log fields normalize/limit करें।
SQL Injection Review Checklist
- No input concatenation।
- हर value correct type से bind।
- Identifiers/operators fixed allowlist।
- IN में bounded per-item markers।
- LIKE wildcard policy।
- Authorization predicate query में।
- Runtime least privilege।
- Native prepares/charset/errors configured।
- No SQL/schema/secret in user error।
- Positive, negative, cross-tenant tests।
prepared statements, GRANT/REVOKE और transactions पढ़ें।
Official संदर्भ
Marker limits, access control और PDO behavior official MySQL/PHP documentation से verified हैं।