SQL 注入

SQL 注入

SQL 注入是一种可以破坏数据库的代码注入技术。SQL 注入是一种常见的网络攻击技术。

SQL 注入是指攻击者将恶意 SQL 代码插入到用户输入字段,从而能够读取、修改或删除数据库中的敏感数据。

SQL 注入通常发生在您要求用户输入(如用户名/用户 ID)时,攻击者不是输入名称/ID,而是插入在数据库中执行某些操作的 SQL 命令。

看下面的例子,它通过将一个变量(txtUserId)添加到 SELECT 语句中来创建 SELECT 语句。该变量是从用户输入(getRequestString)中获取的:

实例

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

本章的其余部分描述了在 SQL 语句中使用用户输入的潜在危险。

接下来的章节展示了使用 SQL 参数SQL 预处理语句防止 SQL 注入的最有效方法。

基于 1=1 始终为真的 SQL 注入

再看一下上面的例子。SQL 代码的原始目的是选择具有给定用户 ID 的用户。

如果没有任何措施阻止用户输入“错误”的输入,用户可以输入一些“巧妙”的输入,如下所示:

UserId:

那么,SQL 语句将如下所示:

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

上面的 SQL 是有效的,并且将返回 Users 表中的所有行,因为 OR 1=1 始终为真。

上面的例子看起来危险吗?如果 Users 表包含名称和密码会怎样?

攻击者只需在输入字段中插入 105 OR 1=1,就可能获取数据库中所有用户名和密码的访问权限。

基于 OR ""="" 始终为真的 SQL 注入

以下是网站用户登录的示例:

Username:

Password:

实例

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 ""=",就可能获取数据库中用户名和密码的访问权限:

User Name:

Password:

现在 SQL 语句将如下所示:

结果

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

上面的 SQL 是有效的,并且将返回 Users 表中的所有行,因为 OR ""="" 始终为真。

来自批处理 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;