لطفا جاواسکریپت مرورگر خود را فعال سازید!

نحوه فعال سازی در کروم
  1. ابتدا باید اینکارو بگنید
  2. بعدش اونکارو
نحوه فعال سازی در فایرفاکس
  1. ابتدا باید اینکارو بگنید
  2. بعدش اونکارو
آشنایی با مفهوم SQL Injection در زبان PHP

آشنایی با مفهوم SQL Injection در زبان PHP

نیاز به توضیح نیست که SQL نام زبانی است که برای کار با دیتابیسی همچون MySQL به کار گرفته می شود. واژه Injection به معنی "تزریق" است و به طور کلی منظور از SQL Injection فرایندی است که از آن طریق هکرها دستوراتی از جنس SQL ایجاد کرده بنابراین به سادگی با استفاده از فرم های اینترنتی می توانند این دستورات را به سمت دیتابیس مد نظرشان ارسال نموده و به هدف خود دست یابند که این هدف طیف گسترده ای از دستیابی به اطلاعات محرمانه دیتابیس ها گرفته تا حتی تخریب آنها را شامل می گردد.

به نظر می رسد اگر اصطلاح "تزریق دستورات اس کیو ال" را به عنوان معادلی برای SQL Injection انتخاب نماییم، معادل خیلی بدی انتخاب نکرده باشیم زیرا همانطور که از نام آن بر می آید، هکر ها با "تزریق" کدهای مد نظر خود به راحتی اقدام به نوشتن یکسری دستورات واقعی SQL می کنند و با استفاده از آنها به راحتی هر کاری که تمایل داشته باشند می توانند انجام دهند. هکرها معمولا برای تزریق کدهای اس کیو ال، از فرم های اینترنتی مثل فرم تماس با ما، فرم ورود به ناحیه کاربری، فرم ثبت نام و ... استفاده می کنند. برای روشن شدن این مسئله، فرم زیر را در نظر می گیریم:


<form action="script.php" method="post">
    <input type="text" name="username" placeholder="Please Enter Your Username">
    <input type="password" name="password" placeholder="Please Enter Your Password">
    <input type="submit" value="Login">
</form>

خروجی کدهای فوق به صورت زیر خواهد بود:

sql injection

همانطور که در کد فوق می بینیم، فرمی داریم که حاوی دو فیلد است یکی برای نام کاربری و دیگری برای رمز عبور. اکشنی هم که برای این فرم در نظر گرفته ایم یک فایل PHP است تحت عنوان script.php:


session_start();
$username_set = false;
$password_set = false;
$username = $_POST['username'];
$password = $_POST['password'];
if (empty($username)) {
    echo "<p class=\"error\">Please Enter your username</p>";
} else {
    $username_set = true;
}
if (empty($password)) {
    echo "<p class=\"error\">Please Enter your password</p>";
} else {
    $password = sha1($_POST['password']);
    $password_set = true;
}
if ($username_set == true && $password_set == true) {
    $sql = "SELECT * FROM `users` WHERE `username` = '$username' AND `password` = '$password'";
    $query = mysql_query($sql, $connection);
    $result = mysql_fetch_assoc($query);
    $_SESSION['id'] = $result['id'];
    $_SESSION["user_name"] = $result["username"];
    echo "You are logged in. In a second or two, you`ll be redirected to your profile page";
    header("location:logged-in.php");
}

در واقع کاربران برای ورود به یک ناحیه کاربری فرضی، می بایست نام کاربری و رمز عبور خود را وارد فرم فوق نمایند و در صورتی که این کار با موفقیت انجام شود، وارد صفحه ای تحت عنوان logged-in.php می شویم که حاوی اسکریپت زیر است:


session_start();
if (!$_SESSION['user_name']) {
    header("location:./");
}
$title = "Hi " .  $_SESSION['user_name'] . " you are logged in";
$userID = $_SESSION['id'];
define("TITLE", $title);
include("includes/header.php");
require("includes/db_config.php");

$sql = "SELECT * FROM `users` WHERE `id` = '$userID'";
$query = mysql_query($sql, $connection);
$result = mysql_fetch_assoc($query);

<table>
    <tr>
        <td>ID</td>
        <td>Username</td>
        <td>Password</td>
    </tr>
    <tr>
        <td><?php echo $result['id']; ?></td>
        <td><?php echo $result['username']; ?></td>
        <td><?php echo $result['password']; ?></td>
    </tr>
</table>
<a href="logout.php">Logout</a>

هم نام کاربری و هم رمز عبور در نظر گرفته شده در این آموزش admin است و پس از وارد کردن آن وارد فیلدهای مربوطه، با تصویر زیر مواجه خواهیم شد:

sql injection

می بینیم که توانستیم با موفقیت وارد ناحیه کاربری شویم. پس از کلیک روی لینک Logout، به فایل تحت عنوان logout.php ارجاع داده می شویم که حاوی اسکریپت زیر است:

session_start();
session_destroy();
define("TITLE", "Logout");
include("includes/header.php");
require("includes/db_config.php");
header("location:./");

این بار قصد داریم تا این وب اپلیکیشن را دور بزنیم:

sql injection

همانطور که در تصویر فوق مشخص است، به عنوان هم نام کاربری و هم رمز عبور عبارت


' OR ' 1' = ' 1

را وارد نموده ایم. حال روی دکمه Login کلیک می کنیم:

sql injection

می بینیم که بدون آگاهی از نام کاربری و رمز عبور، به راحتی توانستیم این وب اپلیکیشن را دور زده و وارد ناحیه کاربری آن هم از نوع ادمین شویم. در ادامه قصد داریم تا رویکرد فوق را مورد بررسی قرار دهیم. با وارد کردن کد

' OR ' 1' = ' 1

به عنوان نام کاربری و رمز عبور، دستور اس کیو ال ما به صورت زیر خواهد بود:


$sql = "SELECT * FROM `users` WHERE `username` = ' ' OR ' 1' = ' 1' AND `password` = ' ' OR ' 1' = ' 1' ";

در واقع در زبان SQL مقادیر یک جدول داخل علامت های ‘ ‘ قرار می گیرند. کدهای فوق بدون قرار دادن مقادیر برای username و password به صورت زیر خواهند بود:

 $sql = "SELECT * FROM `users` WHERE `username` = '  ' AND `password` = '  ' ";

حال زمانی که این عبارت را داخل فیلدهای نام کاربری و رمز عبور قرار می دهیم، دستور فوق به صورت زیر در خواهد آمد:

 
$sql = "SELECT * FROM `users` WHERE `username` = ' ' OR ' 1' = ' 1' AND `password` = ' ' OR ' 1' = ' 1' ";

همانطور که در کد فوق می بینیم، ابتدا مقدار username و یا password را برابر با ‘ ‘ قرار داده یعنی تهی، سپس از دستور OR که به معنی "یا" می باشد استفاده نموده ایم. کاری که این دستور اس کیو ال انجام می دهد این است که این امکان را به ما می دهد تا بتوانیم دو مقدار مختلف برای username یا password در نظر بگیریم. مقدار اول که تهی بود و پس از دستور OR هم گفته ایم اگر مقدار عدد 1 برابر با 1 بود و از آنجا که جواب این شرط همواره درست است، پس این مقدار برای نام کاربری و رمز عبور انتخاب می شود. برای گرفتن جلوی این حمله سایبری، می بایست از متدی تحت عنوان mysql_real_escape_string استفاده کنیم:


session_start();
$username_set = false;
$password_set = false;
$username = $_POST['username'];
$password = $_POST['password'];
//Function to prevent SQL Injection
$secure_password = mysql_real_escape_string($password);
if (empty($username)) {
    echo "<p class=\"error\">Please Enter your username</p>";
} else {
    $username_set = true;
}
if (empty($password)) {
    echo "<p class=\"error\">Please Enter your password</p>";
} else {
    //$password = sha1($_POST['password']);
    $password_set = true;
}
if ($username_set == true && $password_set == true) {
    $sql = "SELECT * FROM `users` WHERE `username` = '$username' AND `password` = '$password'";
    //    $sql = "SELECT * FROM `users` WHERE `username` = ' ' AND `password` = '' OR ' 1' = ' 1' ";
    $query = mysql_query($sql, $connection);
    $result = mysql_fetch_assoc($query);
    $_SESSION['id'] = $result['id'];
    $_SESSION["user_name"] = $result["username"];
    echo "You are logged in. In a second or two, you`ll be redirected to your profile page";
    header("location:logged-in.php");
}

همانطور که در کد فوق می بینیم، متغیر جدیدی ساخته ایم تحت عنوان secure_password که مقدار آن را برابر با متد mysql_real_escape_string قرار داده و پارامتر قرار داده شده برای این متد، همان متغیر password است. از این پس متد mysql_real_escape_string کلیه علائمی همچون ‘ و غیره که برای نوشتن دستورات اس کیو ال مورد استفاده قرار می گیرند را حذف می نماید لذا هکرها نخواهند توانست تا از طریق فرم های اینترنتی به دیتابیس ما و داده های آن دسترسی پیدا کنند. اکنون اگر یک بار دیگر عبارت مد نظر را وارد فرم خود کنیم، خواهیم دید که قادر به ورد به ناحیه ادمین نمی باشیم.