تزریق

از ویکی‌کد، دانشنامهٔ برنامه‌نویسی
پرش به ناوبری پرش به جستجو
Main Page Tutorial
Sql-menu.png
موارد آموزشی
بانک اطلاعاتی
۱عبارت CREATE DATABASE
۲عبارت DROP DATABASE
۳پشتیبان‌گیری بانک اطلاعاتی برای SQL Server
۴عبارت CREATE TABLE
۵عبارت DROP TABLE
۶عبارت ALTER TABLE
۷محدودیت‌ها
۸محدودیت NOT NULL
۹محدودیت UNIQUE
۱۰محدودیت PRIMARY KEY
۱۱محدودیت FOREIGN KEY
۱۲محدودیت CHECK
۱۳محدودیت DEFAULT
۱۴عبارت CREATE INDEX
۱۵فیلد افزایش خودکار
۱۶کار با تاریخ‌ها
۱۷Viewها
۱۸تزریق
۱۹میزبانی
مرجع
مثال‌ها

تزریق SQL

SQL injection یک تکنیک تزریق کد است که ممکن است بانک اطلاعاتی شما را از بین ببرد.[۱]

SQL injection یکی از رایج‌ترین تکنیک‌های هک کردن وب است.

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

SQL در صفحات وب

به مثال زیر توجه کنید، که یک عبارت SELECT را با اضافه‌کردن یک متغیر (txtUserId) به رشته انتخاب ایجاد می‌کند. این متغیر از ورودی کاربر واکشی (به انگلیسی: Fetch) می‌شود (getRequestString):

مثال
1 txtUserId = getRequestString("UserId");
2 txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

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

تزریق SQL بر اساس 1=1 همیشه True است

دوباره به مثال بالا دقت کنید. هدف اصلی این کد ایجاد عبارت SQL برای انتخاب یک کاربر، با شناسه کاربری داده شده‌است.

اگر مانعی برای جلوگیری از واردکردن ورودی «اشتباه» توسط کاربر وجود نداشته باشد، کاربر می‌تواند ورودی «هوشمندی» مانند این وارد کند:

Time2wait.svg ساخت نمونه مثال این بخش در دست اقدام است.


بنابراین عبارت SQL به شکل زیر خواهد بود:

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

SQL بالا معتبر است و همه ردیف‌های جدول "Users" را برمی‌گرداند، زیرا OR 1=1 همیشه TRUE است.

آیا مثال بالا خطرناک به نظر می‌رسد؟ اگر جدول "Users" دارای نام و کلمات عبور باشد چه؟

عبارت SQL بالا بسیار شبیه این است:

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;

یک هکر ممکن است به سادگی با واردکردن ۱۰۵ یا ۱=۱ در فیلد ورودی، به همه نام‌های کاربری و کلمات عبور در بانک اطلاعاتی دسترسی پیدا کند.

تزریق SQL بر اساس ""="" همیشه True است

در اینجا مثالی از ورود یک کاربر به وب‌سایت آمده‌است:

Time2wait.svg ساخت نمونه مثال این بخش در دست اقدام است.


مثال
1 uName = getRequestString("username");
2 uPass = getRequestString("userpassword");
3 
4 sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'
نتیجه
SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

یک هکر ممکن است به سادگی با واردکردن " OR ""=" در قسمت نام کاربری یا کلمه عبور، به همه نام‌های کاربری و کلمات عبور در بانک اطلاعاتی دسترسی پیدا کند:

Time2wait.svg ساخت نمونه مثال این بخش در دست اقدام است.


این کد در سرور یک عبارت SQL معتبر شبیه به این تولید می‌کند:

نتیجه
SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

عبارت SQL بالا معتبر است و همه ردیف‌های جدول "Users" را برمی‌گرداند، زیر OR ""="" همیشه TRUE است.

تزریق SQL بر اساس عبارت‌های SQL دسته ای

اکثر بانک اطلاعاتی‌ها عبارت SQL دسته ای (به انگلیسی: Batched) را پشتیبانی می‌کنند.

دسته ای از عبارت‌های SQL، گروهی از دو یا چند عبارت SQL است که توسط نقطه ویرگول , از هم جدا شده‌اند.

عبارت SQL زیر همه ردیف‌های جدول "Users" را برمی‌گرداند، سپس جدول "Suppliers" را حذف می‌کند.

مثال
SELECT * FROM Users; DROP TABLE Suppliers

به مثال زیر نگاه کنید:

مثال
1 txtUserId = getRequestString("UserId");
2 txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

و ورودی زیر:

Time2wait.svg ساخت نمونه مثال این بخش در دست اقدام است.


عبارت SQL معتبر شبیه این خواهد بود:

نتیجه
SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers;

استفاده از پارامترهای SQL برای محافظت

برای محافظت از یک وب‌سایت از SQL injection، می‌توان از پارامترهای SQL استفاده کرد.

پارامترهای SQL مقدارهایی هستند که به در زمان اجرا، به روش کنترل شده، به پرس‌وجوی SQL اضافه می‌شوند.

مثال ASP.NET Razor
1 txtUserId = getRequestString("UserId");
2 txtSQL = "SELECT * FROM Users WHERE UserId = @0";
3 db.Execute(txtSQL,txtUserId);

دقت کنید که پارامترها در عبارت SQL با علامت @ نشان داده می‌شوند.

موتور SQL هر پارامتر را بررسی می‌کند تا مطمئن شود ستونش صحیح است و دقیق با آن رفتار می‌شود و نه بعنوان بخشی از SQL برای اجرا.

مثال دیگر
1 txtNam = getRequestString("CustomerName");
2 txtAdd = getRequestString("Address");
3 txtCit = getRequestString("City");
4 txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
5 db.Execute(txtSQL,txtNam,txtAdd,txtCit);

مثال‌ها

مثال‌های زیر نحوه ساختن پرس‌وجوی دارای پارامتر را در برخی از زبان‌های رایج وب نشان می‌دهند.

عبارت SELECT در ASP.NET:

1 txtUserId = getRequestString("UserId");
2 sql = "SELECT * FROM Customers WHERE CustomerId = @0";
3 command = new SqlCommand(sql);
4 command.Parameters.AddWithValue("@0",txtUserID);
5 command.ExecuteReader();

عبارت INSERT INTO در ASP.NET:

1 txtNam = getRequestString("CustomerName");
2 txtAdd = getRequestString("Address");
3 txtCit = getRequestString("City");
4 txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
5 command = new SqlCommand(txtSQL);
6 command.Parameters.AddWithValue("@0",txtNam);
7 command.Parameters.AddWithValue("@1",txtAdd);
8 command.Parameters.AddWithValue("@2",txtCit);
9 command.ExecuteNonQuery();

عبارت INSERT INTO در PHP:

1 $stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)
2 VALUES (:nam, :add, :cit)");
3 $stmt->bindParam(':nam', $txtNam);
4 $stmt->bindParam(':add', $txtAdd);
5 $stmt->bindParam(':cit', $txtCit);
6 $stmt->execute();



منابع آموزشی