菜单
×
   ❮     
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 提供支持