MySQL SQL Injection
In this page:
PREPARE statement_name FROM 'SELECT columns FROM table_name WHERE column = ?';
SET @value = input_value;
EXECUTE statement_name USING @value;
DEALLOCATE PREPARE statement_name;
SQL Injection क्या है?
SQL injection तब होता है जब untrusted input, जैसे किसी login form में type किया गया text, सीधे एक SQL query string में concatenate हो जाता है, एक attacker को अपनी खुद की SQL logic आपकी query में inject करने देते हुए। एक classic example "SELECT * FROM users WHERE username = '" + input + "'" जैसी एक query बनाना है, जहाँ एक attacker एक ऐसी value enter कर सकता है जो सिर्फ एक username supply करने के बजाय query का meaning पूरी तरह बदल दे।
उदाहरण: What Is SQL Injection?
-- Vulnerable: username comes from raw, unescaped user input
SET @input = "' OR '1'='1";
-- SELECT * FROM users WHERE username = '' OR '1'='1'; -- matches every row
यह Dangerous क्यों है
एक successful injection एक attacker को authentication पूरी तरह bypass करने, ऐसा data पढ़ने जो उसे कभी नहीं देखना चाहिए, rows modify या delete करने, या कुछ configurations में administrative database commands execute करने भी दे सकता है। क्योंकि malicious input को plain data की जगह executable SQL माना जाता है, damage उस तक limited नहीं जो application का अपना logic आमतौर पर allow करता है।
उदाहरण: Why It Is Dangerous
-- A crafted input can bypass a login check entirely:
-- WHERE username = '' OR '1'='1' -- ' AND password = 'anything'
-- Everything after the -- becomes a comment, so the password check never runs
Prepared Statements इसे रोकते हैं
Prepared statements SQL structure को data values से अलग करते हैं: query पहले placeholders के साथ compile होती है, और actual input बाद में pure data की तरह भेजा जाता है जिसे कभी SQL syntax की तरह reinterpret नहीं किया जा सकता। यह injection के against standard, reliable defense है, क्योंकि database driver -- string concatenation नहीं -- हर बार सही से values को escape करता है।
उदाहरण: Prepared Statements Prevent It
PREPARE stmt FROM 'SELECT * FROM users WHERE username = ?';
SET @uname = "' OR '1'='1";
EXECUTE stmt USING @uname;
DEALLOCATE PREPARE stmt;
Escaping एक Weaker Fallback की तरह
Special characters को manually escape करना (जैसे quotes को double करना या पुराने APIs में mysql_real_escape_string जैसा function इस्तेमाल करना) injection risk कम कर सकता है, लेकिन यह fragile है और गलत करना आसान है -- सिर्फ एक input point escape करना भूल जाना vulnerability फिर से खोल देता है। Prepared statements strongly preferred हैं क्योंकि वे escaping के बारे में सोचने की ज़रूरत ही खत्म कर देते हैं।
उदाहरण: Escaping as a Weaker Fallback
-- Escaping only helps if every single input point is escaped correctly:
SELECT QUOTE("O'Brien") AS escaped_value;
Least-Privilege Accounts
Prepared statements होने के बावजूद, applications को सिर्फ actually ज़रूरी privileges वाले एक account से database से connect होना चाहिए, कभी एक root या admin account से नहीं। अगर एक injection attack या कोई दूसरी vulnerability फिर भी घुस जाए, एक least-privilege account damage को उस तक limit कर देता है जो वह account करने के लिए allowed है, पूरे server को expose करने के बजाय।
उदाहरण: Least-Privilege Accounts
CREATE USER 'app_readonly'@'localhost' IDENTIFIED BY 'pass123';
GRANT SELECT ON mydb.* TO 'app_readonly'@'localhost';
-- Never connect the application as root
- input concatenate करके एक query बनाना, जैसे
"... WHERE name = '" + input + "'", जो' OR 1='1को query बदलने देता है। - protection की तरह error messages छुपाने पर भरोसा करना, जबकि injection अभी भी काम करता है।
- application को
rootजैसे एक powerful account से connect करना, जो एक injection का damage कहीं ज़्यादा बुरा बना देता है।
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: