Menu
×
   ❮     
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 选择 SQL 选择 DISTINCT SQL WHERE SQL ORDER BY SQL AND SQL OR SQL NOT SQL 插入 SQL 空值 SQL 更新 SQL 删除 SQL 选择 TOP SQL 聚合函数 SQL MIN 和 MAX SQL COUNT SQL SUM SQL AVG SQL LIKE SQL 通配符 SQL IN SQL BETWEEN SQL 别名 SQL 联接 SQL 内联接 SQL 左联接 SQL 右联接 SQL 全联接 SQL 自联接 SQL UNION SQL GROUP BY SQL HAVING SQL EXISTS SQL ANY, ALL SQL SELECT INTO SQL INSERT INTO SELECT SQL CASE SQL 空函数 SQL 存储过程 SQL 注释 SQL 运算符

SQL 数据库

SQL 创建数据库 SQL 删除数据库 SQL 数据库备份 SQL 创建表 SQL 删除表 SQL 修改表 SQL 约束 SQL 非空 SQL 唯一 SQL 主键 SQL 外键 SQL 检查 SQL 默认值 SQL 索引 SQL 自增 SQL 日期 SQL 视图 SQL 注入 SQL 托管 SQL 数据类型

SQL 参考

SQL 关键字 MySQL 函数 SQL Server 函数 MS Access 函数 SQL 快速参考

SQL 示例

SQL 示例 SQL 编辑器 SQL 测验 SQL 练习 SQL Server SQL 集训营 SQL 证书

SQL 注入


SQL 注入

SQL 注入是一种代码注入技术,可能会破坏您的数据库。

SQL 注入是最常见的网络黑客技术之一。

SQL 注入是在 SQL 语句中通过网页输入放置恶意代码。


网页中的 SQL

SQL 注入通常发生在您要求用户输入信息(如用户名/用户 ID)时,用户提供的不是姓名/ID,而是一个您将**无意中**在数据库上运行的 SQL 语句。

请看下面的示例,它通过向选择字符串添加一个变量 (txtUserId) 来创建一个 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;

以及以下输入

用户 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();

×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
[email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
[email protected]

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Copyright 1999-2024 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.