SQL Injection یکی از خطرناکترین آسیبپذیریهای وب هست. هکر با تزریق SQL مخرب میتونه کل دیتابیس رو بخونه، تغییر بده یا حذف کنه. تو این مقاله راههای جلوگیری رو یاد میگیرید.
SQL Injection چیه؟
وقتی برنامه ورودی کاربر رو مستقیم در SQL query قرار میده، هکر میتونه کد SQL خودش رو اضافه کنه.
مثال آسیبپذیر
$id = $_GET['id'];
$sql = "SELECT * FROM users WHERE id = " . $id;
هکر: id=1 OR 1=1
Result: SELECT * FROM users WHERE id = 1 OR 1=1
همه کاربران برمیگرده!
حمله UNION
id=1 UNION SELECT username, password FROM users
هکر Password ها رو میخونه.
حمله DROP
id=1; DROP TABLE users;
کل جدول پاک میشه!
راههای جلوگیری
۱. Prepared Statements (بهترین)
PHP PDO:
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
MySQLi:
$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
۲. ORM
Laravel Eloquent:
User::where('id', $id)->first();
Doctrine، Sequelize و ORM های دیگه پیشفرض امن هستن.
۳. Escape (کمتر توصیه)
mysqli_real_escape_string($conn, $input)
ضعیفتر از Prepared، ولی از هیچی بهتر.
۴. Type Casting
برای اعداد:
$id = (int)$_GET['id'];
۵. Input Validation
Whitelist:
if (!in_array($sort, ['name', 'date'])) die('Invalid');
Framework Protection
Laravel، Django، Rails، Symfony پیشفرض ازش محافظت میکنن. فقط از ORM استفاده کنید.
Stored Procedure
خودش امن نیست ولی اگه با Prepared استفاده بشه، اضافه امنیت.
Least Privilege
کاربر دیتابیس Application فقط دسترسی لازم رو داشته باشه. root نده.
Error Handling
خطاهای SQL رو به کاربر نشون ندید. اطلاعات مفید برای هکره.
display_errors = Off در production.
WAF
Web Application Firewall الگوهای SQL Injection رو تشخیص میده.
Blind SQL Injection
حتی اگه خطا نمایش داده نشه، هکر با True/False میتونه اطلاعات استخراج کنه. Rate Limit ضروریه.
Time-based Blind
هکر با SLEEP() زمانسنجی میکنه. Query Timeout بذارید.
Testing
sqlmap: ابزار خودکار
Burp Suite: حرفهای
OWASP ZAP: رایگان
Manual: ورودی ' OR '1'='1
WordPress و SQLi
هسته WordPress امنه ولی پلاگینهای ضعیف مشکل دارن. مدام آپدیت. Wordfence هشدار میده.
NoSQL Injection
MongoDB و امثالش هم آسیبپذیر هستن. Prepared query یا Parameter Object.
Second-order SQLi
ورودی یه بار escape میشه ولی بعد در query دیگه استفاده میشه بدون escape. Escape هر بار.
Legacy Code
کد قدیمی PHP معمولاً آسیبپذیره. مهاجرت به Framework مدرن.
OWASP Top 10
SQL Injection از سال ۲۰۱۳ در Top 3 OWASP بوده. توجه جدی.
سباهاست
سرورهای سباهاست با ModSecurity رولهای SQLi از قبل فعال.
جمعبندی
SQL Injection قابل جلوگیری کامل با Prepared Statements. هیچ بهانهای برای عدم استفاده نیست.