SQL injection چیست و چگونه از آن جلوگیری کنیم ؟
SQL injection چیست جلوگیری از آن – تزریق SQL یکی از محبوب ترین باگ های نفوذ گران دنیا وب است به طوری که بیشترین سهم را در هک وبسایت دارد .
چرا که تمامی اطلاعات یک وبسایت در دیتابیس آن ذخیره می شود و دسترسی به این منبع ارزشمند یعنی دسترسی به کل وبسایت . ( SQL injection چیست جلوگیری از آن )
در صورتی که برنامه نویس با این باگ خطرناک آشنا نباشد با کدنویسی غیر ایمن باعث به خطر افتادن وبسایت می شود .
بررسی SQL injection
1- ابتدا کاربر با اضافه کردن ‘ در متغیری که بدون بررسی ورودی انجام شود درخواست را می فرستد تا بررسی کند که آیا دارای باگ SQLi می باشد یا خیر . در صورتی که باگ وجود داشت دستور های MYSQL را تزریق می کند .
2- اطلاعات را به سرور می فرستد تا بررسی شود . کد های برنامه نویس که بدون هیچ بررسی ورودی کاربر دریافت کرده و پردازش می کند .
3- اطلاعات ورودی کاربر ( همان اطلاعاتی که هکر تزریق کرده ) را به دیتابیس می فرستد .
4- دیتابیس با توجه به query پاسخ می دهد و مجدد به سرور می فرستد .
5- سرور اطلاعات ( رکورد های ) دریافت شده از دیتابیس را دریافت کرده و بر اساس پردازش هایی که انجام می شود نتیجه را به کاربر برمی گرداند که
نتیجه حاکی از این است که کاربر نام کاربری و رمز عبور خود را به درستی وارد کرده این در حالی است که فقط نام کاربری وارد شده و هیچ رمز عبوری وجود نداشته .
کد آسیب پذیر SQLi
معمولا نام کاربری و رمز عبور با متود GET صورت نمی گیرد و POST است اما برای سرعت بخشیدن و عدم نیاز به ابزار های جداگانه برای ارسال POST به صورت GET در نظر گرفته شده .
$mysqli = new mysqli("localhost", "root", "", "api"); if ($mysqli->connect_error) { die("MYSQL ISSUE : " . $mysqli->connect_error); } $mysqli->set_charset("utf8"); $username = $_GET['username']; $password = $_GET['password']; $query = "SELECT * FROM `my_tbl` WHERE username='$username' AND password='$password' LIMIT 1"; $row = []; if ($res = $mysqli->query($query)) { if ($res->num_rows) { while ($row_loop = $res->fetch_row()) { $row = $row_loop; } } $res->close(); } echo $row ? "Access Granted" : "Access Denied"; $mysqli->close();
کد ایمن در برابر SQLi با استفاده از stmt
انجمن تحقیقاتی و امنیتی owasp با توجه به موضوع sql inejction توصیه می کند که از mysqli یا PDO کمک گرفته و حتما از stmt استفاده کنید .
با استفاده از stmt دیگر باگ SQLi رخ نخواهد داد کد نمونه زیر :
$mysqli = new mysqli("localhost", "root", "", "api"); if ($mysqli->connect_error) { die("MYSQL ISSUE : " . $mysqli->connect_error); } $mysqli->set_charset("utf8"); $stmt = $mysqli->stmt_init(); $username = $_GET['username']; $password = $_GET['password']; $query = "SELECT * FROM `my_tbl` WHERE username=? AND password=? LIMIT 1"; $stmt->prepare($query); $stmt->bind_param('ss' , $username , $password); $row = []; if ($stmt->execute() && $res = $stmt->get_result()) { if ($stmt->affected_rows || $res->num_rows) { while ($row_loop = $res->fetch_assoc()) { $row = $row_loop; } } } echo $row ? "Access Granted" : "Access Denied"; $mysqli->close();
ارسال نظر