SQL Injection (SQLi) হলো এক ধরনের সাইবার আক্রমণ (Cyber Attack), যেখানে আক্রমণকারী ইউজার ইনপুটের মাধ্যমে ক্ষতিকর SQL কোড ইনজেক্ট করে ডেটাবেসের নিয়ন্ত্রণ নিয়ে নিতে পারে। যদি ইউজার ইনপুট সঠিকভাবে ভ্যালিডেট না করা হয়, তাহলে অ্যাটাকার এই ম্যালিসিয়াস কোড এক্সিকিউট করে ডেটাবেস থেকে সংবেদনশীল তথ্য চুরি, মুছে ফেলা বা পরিবর্তন করতে পারে। এটি ওয়েব অ্যাপ্লিকেশন সিকিউরিটির অন্যতম ভয়ংকর দুর্বলতা।
SQL Injection কীভাবে কাজ করে?
একটি সাধারণ ওয়েব অ্যাপ্লিকেশন যেখানে ইউজার লগইন সিস্টেম থাকে, সেখানে ইউজারের Username এবং Password যাচাই করার জন্য ব্যাকএন্ডে নিচের মতো SQL Query ব্যবহার করা হতে পারে:
SELECT * FROM users WHERE username = 'user_input' AND password = 'password_input';
এখন, ধরো অ্যাটাকার নিচের মতো ম্যালিসিয়াস ইনপুট ব্যবহার করল:
Username:
' OR '1'='1Password: (কিছু না দিলেও চলবে)
তাহলে ব্যাকএন্ডে গিয়ে SQL Query-টি দাঁড়াবে ঠিক এরকম:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '';এখানে 1=1 শর্তটি সর্বদা সত্য (True)। ফলে সিস্টেম পাসওয়ার্ড চেক না করেই ডেটাবেসের তথ্য রিটার্ন করবে। এর মাধ্যমে অ্যাটাকার পাসওয়ার্ড না জেনেই সিস্টেমে লগইন করে ফেলবে।
SQL Injection-এর ভয়াবহ প্রভাব
Authentication Bypass: লগইন ক্রেডেনশিয়াল না জেনেই অ্যাটাকার সিস্টেমে ঢুকে যেতে পারে।
Data Leakage: সংবেদনশীল ডেটা (যেমন: ইউজার ইনফো, ক্রেডিট কার্ড ডিটেইলস) চুরি হতে পারে।
Data Manipulation: অ্যাটাকার ডেটাবেসের তথ্য পরিবর্তন বা সম্পূর্ণ মুছে দিতে পারে।
System Takeover: ডেটাবেস সার্ভারের সম্পূর্ণ নিয়ন্ত্রণ অ্যাটাকারের হাতে চলে যেতে পারে।
কীভাবে SQL Injection প্রতিরোধ করবে?
তুমি যদি তোমার অ্যাপ্লিকেশনকে সুরক্ষিত রাখতে চাও, তবে নিচের পদ্ধতিগুলো অনুসরণ করা উচিত:
১. Prepared Statements এবং Parameterized Queries ব্যবহার করা
এটি SQL Injection প্রতিরোধের সবচেয়ে কার্যকর পদ্ধতি। এই পদ্ধতিতে ইউজার ইনপুট সরাসরি SQL Query-তে টেক্সট হিসেবে যুক্ত হয় না, বরং প্যারামিটার হিসেবে আলাদাভাবে বাইন্ড হয়। ফলে ডেটাবেস ড্রাইভার ইনপুটটিকে কোড হিসেবে এক্সিকিউট না করে শুধুমাত্র ডেটা হিসেবে ট্রিট করে।
পাইথন উদাহরণ:
import mysql.connector
# Database Connection setup
conn = mysql.connector.connect(
host="localhost",
user="db_user",
password="secure_password",
database="test_db"
)
cursor = conn.cursor()
# Secure Query using Prepared Statement
query = "SELECT * FROM users WHERE username = %s AND password = %s"
user_input = ("admin", "mypassword")
# The database driver safely escapes the inputs
cursor.execute(query, user_input)
result = cursor.fetchall()
print(result)
cursor.close()
conn.close()
যেহেতু তুমি পাইথনের পাশাপাশি জাভা নিয়েও কাজ করো, তাই জাভাতে স্প্রিং বুট (Spring Boot) বা সাধারণ JDBC ব্যবহার করার সময়ও একই নীতি প্রযোজ্য। সেখানে PreparedStatement ব্যবহার করতে হয়।
২. User Input Validation করা
সবসময় ইনপুট ভ্যালিডেট করতে হবে। Whitelist Approach ব্যবহার করে শুধু নির্দিষ্ট ক্যারেক্টার (যেমন: লেটার এবং নাম্বার) অ্যালাও করা উচিত এবং Regular Expressions ব্যবহার করে ইনপুটের প্যাটার্ন চেক করা উচিত।
import re
def validate_input(user_input):
# Only allow alphanumeric characters and underscores
if re.match("^[a-zA-Z0-9_]+$", user_input):
return True
return False
# Testing the validation
print(validate_input("admin")) # Returns True
print(validate_input("admin' OR 1=1 --")) # Returns False
৩. Least Privilege নীতি অনুসরণ করা
ডেটাবেস ইউজারের অ্যাক্সেস লিমিট করে রাখা। অ্যাপ্লিকেশনের ডেটাবেস কানেকশনের জন্য রুট (Root) ইউজার ব্যবহার না করে একটি আলাদা ইউজার তৈরি করা, যার শুধুমাত্র নির্দিষ্ট টেবিল পড়া বা লেখার পারমিশন থাকবে।
৪. Web Application Firewall (WAF) ব্যবহার করা
Cloudflare WAF বা ModSecurity-এর মতো সিকিউরিটি সিস্টেম ব্যবহার করা। এগুলো ইনকামিং ট্রাফিকে SQL Injection-এর পরিচিত প্যাটার্নগুলো ডিটেক্ট করে এবং তা সার্ভারে পৌঁছানোর আগেই ব্লক করে দেয়।
SQL Injection একটি মারাত্মক নিরাপত্তা দুর্বলতা হলেও, কোড লেখার সময় Parameterized Query এবং Input Validation এর মতো বেসিক নিয়মগুলো মেনে চললে সহজেই এই সমস্যার সমাধান সম্ভব। Security is not a feature, it's a process.