در این پست میخوام شمارو با مفهومی بنام   " تزریق اس کیو ال "  آشنا کنم:

فکر میکنم هیچ سایت داینامیکی وجود نداشته باشه که داخل صفحاتش فرمی برای ارسال اطلاعات نداشته باشه ، چون اصلا وجود فرم ها در سایت های استاتیک احساس شد که زبانهای سمت سرور پدید اومدن (مثل php)

حالا از حسن این فرم ها که بگذریم ، میتونیم بگیم به ازای هر ورودی که این فرمها دارن یک حفره امنیتی هم به سایت ما باز شده

بنابراین ما باید خیلی حواسمون باشه که ببینیم کاربران سایتمون چه داده هایی رو برامون ارسال میکنند ، از اونجائیکه معمولا پس از دریافت اطلاعات از فرم ها ، ما این اطلاعات رو میریزیم توی دیتابیس ، پس اگر درون صفحات پردازش فرم ها از صحت و درستی داده ها اطمینان حاصل نکنیم ممکنه کاربری به همراه داده یک دستور SQL هم ارسال کنه و چون این مقدار درون رشته کوئری قرار میگیره و به نرم افزار مدیریت بانک اطلاعتی مون ارسال میشه ، پس اونجا کد اس کیو ال نیز  execute (اجرا)  خواهد شد و ممکنه باعث تخریب یا دستکاری داده ها و دیتابیسمون بشه

برای اینکه ما جلوی ارسال داده های مخرب (SQL) رو به دیتابیس بگیریم باید قبل از ارسال اونها به نرم افزار DBMS (نرم افزار مدیریت بانک اطلاعاتی) بایستی اونهارو آماده سازی کنیم و هرگونه کد اس کیو الی رو ازشون حذف کنیم و سپس به دیتابیس بفرستیم.

خوشبختانه در زبان php توابع زیادی برای آماده سازی داده های ارسالی به دیتابیس وجود داره که من یکی از این روشها رو که متعلق به کلاس PDO میباشد رو خدمتتون آموزش میدم : 

(البته برخی از توسعه دهندگان وب میان یک لیست سیاه از کاراکترها رو  تعیین میکنند و اون کاراکتر هارو از ورودی های کاربر حذف میکنند که اصلا مناسب نیست ، چون ممکنه ما کاراکتری رو از یک ورودی محدود کنیم که اصلا نیاز هست تا کاربران برایمان ارسال کنند)

روشی که در اینجا با استفاده از متدهای کلاس PDO میخواهیم انجام بدیم تمام مقادیر رو بصورت پارامتری به دیتابیس میفرسته و این باعث میشه که کاربر وقتی درون یک فیلدی از یک فرم مقدار مثلا یک اسم رو وارد کرده و در انتهاش یک کد اس کیو الی هم نوشته و ارسال کرده ، تمامش به عنوان یک پارامتر متعلق به یک ستون از یک جدول به دیتابیس معرفی بشه و اگر کدی همراه اونا ارسال کرده باشه توسط DBMS اجرا نشه

 

فرض کنید کاربری مثلا برای اینکه به یک سیستم لاگین کنه وارد صفحه لاگین سایت میشه و به جای اینکه مقادیر صحیح نام کاربری و رمز عبورش رو وارد کنه و ارسال کنه تا از دیتابیس استعلام بشه ، میاد کد زیر رو میفرسته !  حالا خودتون ببینید آیا نمیتونه بدون اطلاعات صحیح هم وارد بشه !!!

تزریق اس کیو ال

 

حالا همونطور که در تصویر بالا میبینید کاربر وقتی مقادیر بالا رو وارد کنه به شکل زیر در کوئری قرار میگیرن :

 

sqlinjection

 

برای جلوگیری اینگونه حملات از دو متد کلاس PDO استفاده میکنیم که یکی رشته کوئری رو بدون مقادیر به دیتابیس معرفی میکنه تا دیتابیس از ساختار دستور اس کیو الی ما آگاه بشه  و دومی هم مقادیر رو برای اجرا به دیتابیس میفرسته

اولی متد prepare و دومی هم  execute  هست.

$name=trim($_POST['dname']);
$familly=trim($_POST['dfamilly']);
$mobile=trim($_POST['dmobile']);
$tell=trim($_POST['dtell']);
$email=trim($_POST['demail']);
$address=trim($_POST['address']);
$message=trim($_POST['message']);
$type=trim($_POST['type']);

date_default_timezone_set("Asia/Tehran");
$date=date("Ymd",time());
$time=date("His",time());




    $db=new pdo("mysql:host=localhost;dbname=mydb;charset=utf8","root","");
    $q="INSERT INTO dorders(name,familly, tell, mobile,email,type,address,message,date,time) VALUES (?,?,?,?,?,?,?,?,?,?)";
    $stmt=$db->prepare($q);
    $stmt->execute(array($name,$familly,$tell,$mobile,$email,$type,$address,$message,$date,$time));


    echo "اطلاعات شما با موفقیت در دیتابیس ثبت شد";