選單
×
   ❮     
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

SQL 教程

SQL 主頁 SQL 入門 SQL 語法 SQL Select SQL Select Distinct SQL Where SQL Order By SQL And SQL Or SQL Not SQL Insert Into SQL Null Values SQL Update SQL Delete SQL Select Top SQL Aggregate Functions SQL Min and Max SQL Count SQL Sum SQL Avg SQL Like SQL Wildcards SQL In SQL Between SQL Aliases SQL Joins SQL Inner Join SQL Left Join SQL Right Join SQL Full Join SQL Self Join SQL Union SQL Group By SQL Having SQL Exists SQL Any, All SQL Select Into SQL Insert Into Select SQL Case SQL Null Functions SQL Stored Procedures SQL Comments SQL Operators

SQL 資料庫

SQL Create DB SQL Drop DB SQL Backup DB SQL Create Table SQL Drop Table SQL Alter Table SQL Constraints SQL Not Null SQL Unique SQL Primary Key SQL Foreign Key SQL Check SQL Default SQL Index SQL Auto Increment SQL Dates SQL Views SQL Injection SQL Hosting SQL Data Types

SQL 參考

SQL 關鍵字 MySQL 函式 SQL Server 函式 MS Access 函式 SQL 快速參考

SQL 示例

SQL 示例 SQL 編輯器 SQL 測驗 SQL 練習 SQL Server SQL Bootcamp SQL 證書

SQL 注入


SQL 注入

SQL 注入是一種程式碼注入技術,可能會破壞您的資料庫。

SQL 注入是最常見的 Web 攻擊技術之一。

SQL 注入是透過網頁輸入,將惡意程式碼放置在 SQL 語句中。


網頁中的 SQL

SQL 注入通常發生在您要求使用者輸入資訊(如使用者名稱/使用者 ID)時,但使用者提供給您的不是姓名/ID,而是您將“不知情地”在資料庫上執行的 SQL 語句。

請看下面的示例,該示例透過將變數 (txtUserId) 新增到 select 字串中來建立 SELECT 語句。該變數從使用者輸入 (getRequestString) 中獲取。

示例

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

本章的其餘部分將描述在 SQL 語句中使用使用者輸入的潛在危險。


基於 1=1 永真的 SQL 注入

再次看上面的示例。程式碼的原始目的是建立一個 SQL 語句,根據給定的使用者 ID 來選擇一個使用者。

如果沒有措施阻止使用者輸入“錯誤”的輸入,使用者可以輸入一些“聰明”的輸入,例如

UserId

然後,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;

駭客只需在輸入欄位中插入 105 OR 1=1,就可以訪問資料庫中的所有使用者名稱和密碼。



基於 ""="" 永真的 SQL 注入

以下是網站使用者登入的示例

使用者名稱

密碼

示例

uName = getRequestString("username");
uPass = getRequestString("userpassword");

sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

結果

SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

駭客只需在使用者名稱或密碼文字框中插入 " OR ""=" 即可訪問資料庫中的使用者名稱和密碼。

使用者名稱

密碼

伺服器上的程式碼將建立一個有效的 SQL 語句,如下所示

結果

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

上述 SQL 是有效的,並且將返回“Users”表中的所有行,因為 **OR ""=""** 始終為 TRUE。


基於批次 SQL 語句的 SQL 注入

大多數資料庫支援批次 SQL 語句。

批次 SQL 語句是一組兩個或多個 SQL 語句,用分號分隔。

以下 SQL 語句將返回“Users”表中的所有行,然後刪除“Suppliers”表。

示例

SELECT * FROM Users; DROP TABLE Suppliers

看下面的例子

示例

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

以及以下輸入

User id

有效的 SQL 語句將如下所示

結果

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers;

使用 SQL 引數進行保護

要保護網站免受 SQL 注入的侵害,您可以使用 SQL 引數。

SQL 引數是在執行時以受控方式新增到 SQL 查詢中的值。

ASP.NET Razor 示例

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);

請注意,SQL 語句中的引數由 @ 標記表示。

SQL 引擎會檢查每個引數,以確保它適合其列,並且被視為文字,而不是要執行的 SQL 的一部分。

另一個示例

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);

示例

以下示例顯示瞭如何在一些常見的 Web 語言中構建引數化查詢。

ASP.NET 中的 SELECT 語句

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

ASP.NET 中的 INSERT INTO 語句

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

PHP 中的 INSERT INTO 語句

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

×

聯絡銷售

如果您想將 W3Schools 服務用於教育機構、團隊或企業,請傳送電子郵件給我們
sales@w3schools.com

報告錯誤

如果您想報告錯誤,或想提出建議,請傳送電子郵件給我們
help@w3schools.com

W3Schools 經過最佳化,旨在方便學習和培訓。示例可能經過簡化,以提高閱讀和學習體驗。教程、參考資料和示例會不斷審查,以避免錯誤,但我們無法保證所有內容的完全正確性。使用 W3Schools 即表示您已閱讀並接受我們的使用條款Cookie 和隱私政策

版權所有 1999-2024 Refsnes Data。保留所有權利。W3Schools 由 W3.CSS 提供支援