Free tutorials & notes in Hindi & English · Clean code examples · Mobile friendly learning
MySQL + SQL · Lesson 110

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 हो।

Three controls: हर data value parameter, dynamic structure fixed allowlist और minimum-privilege DB account.

Injection SELECT, INSERT, UPDATE, DELETE, login, reports, search, ORDER BY और import filters में हो सकता है।

Vulnerable Pattern पहचानें

यह isolated learning example है; real data पर deploy/run न करें।
$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 flagRisk
ConcatenationData SQL grammar बनता है
Request से ORDER BYKeyword/identifier structure है
Admin-only unsafe querySession compromise possible
Root connectionMaximum 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,
]);
Valid authorized email: one row Injection-shaped text: literal value; normally zero rows

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 करें

  1. Synthetic isolated DB बनाएँ।
  2. SQL बनाने वाले सभी paths inventory करें।
  3. Quotes, comments, Unicode, numeric, NULL, long values test करें।
  4. Unknown sort/filter reject करें।
  5. Normal request success और shaped data no extra rows assert करें।
  6. Cross-class/tenant denied रखें।
  7. Code review/static और authorized dynamic tests।
  8. Syntax errors, denied requests, unusual exports monitor करें।

Full payload logs में न रखें; log fields normalize/limit करें।

Regression: हर query change के बाद desired और denied access दोनों prove करें।

SQL Injection Review Checklist

  1. No input concatenation।
  2. हर value correct type से bind।
  3. Identifiers/operators fixed allowlist।
  4. IN में bounded per-item markers।
  5. LIKE wildcard policy।
  6. Authorization predicate query में।
  7. Runtime least privilege।
  8. Native prepares/charset/errors configured।
  9. No SQL/schema/secret in user error।
  10. Positive, negative, cross-tenant tests।

prepared statements, GRANT/REVOKE और transactions पढ़ें।

Official संदर्भ

Marker limits, access control और PDO behavior official MySQL/PHP documentation से verified हैं।

अक्सर पूछे जाने वाले प्रश्न (FAQ)

SQL injection क्या है?
यह input-handling vulnerability है जिसमें untrusted data intended SQL structure बदलकर data read/change/delete या application checks bypass कर सकता है।
क्या prepared statements injection पूरी तरह रोकते हैं?
Correctly bound data values protect होते हैं। Dynamic identifiers, operators, clauses और concatenated fragments के लिए fixed mapping/allowlist चाहिए; authorization भी जरूरी है।
क्या user input escape करना पर्याप्त है?
नहीं। Manual escaping context-dependent और आसानी से miss/misuse होता है। Values के लिए parameters, structure के लिए allowlists और least privilege रखें।
क्या एक placeholder IN list bind कर सकता है?
नहीं। हर validated item का placeholder बनाएँ, सभी bind करें और empty list behavior define करें।
क्या SQL errors website users को दिखाने चाहिए?
नहीं। Generic error/correlation ID दें और protected server log में credentials, sensitive data या full attacker payload के बिना event रखें।
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 लाइव कोड एडिटर

इस पेज के प्रोग्राम यहीं तैयार हैं — चलाएँ, बदलें और सीखें। कुछ भी इंस्टॉल किए बिना।
OneCompiler द्वारा संचालित। कोड एडिटर में अपने आप आ जाता है — Run दबाकर आउटपुट देखें। अगर एडिटर न खुले तो नए टैब में खोलें.