SQL injection: কীভাবে কাজ করে ও কীভাবে ঠেকাবেন
SQL injection আক্রমণকারীর input-কে আপনার query-র অংশ বানিয়ে দেয়। সমাধান সহজ ও সুপরিচিত: string জুড়ে SQL কখনো বানাবেন না।

SQL injection (SQLi) হয় যখন অ্যাপ user input লেখার মধ্যে বসিয়ে SQL query বানায়, ফলে input query-র অর্থ বদলে দিতে পারে। বছরের পর বছর এটি OWASP Top 10-এ আছে, আর আসল সিস্টেমে এখনও পাওয়া যায়।
একটি দুর্বল উদাহরণ
// বিপজ্জনক: string জোড়া দেওয়া
const sql = "SELECT * FROM users WHERE email = '" + email + "' AND password = '" + pass + "'";
User email হিসেবে ' OR '1'='1 লিখলে query হয়:
SELECT * FROM users WHERE email = '' OR '1'='1' AND password = '...'
শর্ত সবসময় সত্য, আর login যাচাই এড়ানো যেতে পারে। আক্রমণকারীর টেক্সট data নয়, SQL কোড হিসেবে ধরা হয়েছে।
আক্রমণকারী কী করতে পারে
Bug ও database permission অনুযায়ী: login এড়ানো, অন্য user-দের data পড়া, data বদলানো বা মোছা, এবং কিছু setup-এ server পর্যন্ত পৌঁছানো। Data ফাঁস প্রায়ই এখান থেকেই শুরু হয়।
ধরন
- In-band: ফল বা error স্বাভাবিক response-এ আসে (error-based, UNION-based)।
- Blind: কোনো data দেখা যায় না, কিন্তু আক্রমণকারী true/false পেজের পার্থক্য বা সময় থেকে উত্তর অনুমান করে।
- Second-order: ক্ষতিকর input প্রথমে নিরাপদে সংরক্ষিত হয়, পরে অন্য query-তে অনিরাপদে ব্যবহৃত হয়।
আসল সমাধান: parameterized query
SQL ও data আলাদাভাবে পাঠান। Database কখনো data-কে কোড ভাবে না।
const row = await db.query(
"SELECT * FROM users WHERE email = $1 AND password_hash = $2",
[email, hash]
);
এটি সব ভাষায় কাজ করে (prepared statement, placeholder ? বা $1)। ORM ডিফল্টে এটি ব্যবহার করে।
সাধারণ ভুল
- ORM-এর ভেতরে raw query। String interpolation দিয়ে raw SQL বানালে bug ফিরে আসে।
- Parameter করা যায় না এমন গতিশীল অংশ, যেমন table-এর নাম, column-এর নাম বা
ORDER BYদিক। Allow-list ব্যবহার করুন: user-এর পছন্দ নির্দিষ্ট জানা মানের সেটে ম্যাপ করুন। - হাতে escape করা। ভুল করা সহজ। Parameter ব্যবহার করুন।
- ভেতরে SQL string বানানো stored procedure।
Defence in depth
- Least privilege: অ্যাপের database account যেন table মুছতে বা অন্য schema পড়তে না পারে।
- Input যাচাই করুন (ধরন, দৈর্ঘ্য, ফরম্যাট)। সাহায্য করে, কিন্তু parameter-এর বিকল্প নয়।
- User-এর কাছ থেকে database error লুকান। ব্যক্তিগতভাবে log করুন।
- WAF ঝুঁকি কমাতে পারে, কিন্তু কোড ঠিক করে না।
- Library হালনাগাদ রাখুন এবং string-দিয়ে-বানানো query-র জন্য কোড স্ক্যান (static analysis) করুন।
নিরাপদে পরীক্ষা
শুধু আপনার নিজের বা লিখিত অনুমতি আছে এমন সিস্টেম পরীক্ষা করুন। শেখার নিরাপদ জায়গা: DVWA-র মতো স্থানীয় practice অ্যাপ বা আপনার নিজের staging কপি। অনুমতি ছাড়া আসল সাইটে কখনো পরীক্ষা করবেন না।
মূল কথা: সর্বত্র parameterized query ব্যবহার করুন, গতিশীল অংশ allow-list করুন, অ্যাপকে কম-অধিকারের database user দিন, এবং error-এর বিবরণ লুকান।
ওয়েব সিকিউরিটি সিরিজ, পর্ব ১ (injection ও access control): 1 নম্বর (মোট 4)।

