首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这个SQL过程是“注入验证”吗?

问这个SQL过程是“注入验证”吗?
EN

Database Administration用户
提问于 2023-03-15 15:06:26
回答 6查看 2.5K关注 0票数 9

大多数SQL注入的答案和示例都显示了某种形式的动态SQL或将参数解释为SQL。

我还没有找到“正确”方式的例子。微软和甲骨文的文档只是给出了一些不应该做的例子。

因此,我想我应该问一下这个存储过程示例是否受到SQL注入攻击的保护。

代码语言:javascript
复制
CREATE PROCEDURE test
    @username = varchar(30)
    @password = varchar(30)
AS
BEGIN
    SELECT *
    FROM credentials
    WHERE username = @username
    AND password = @password;
END
GO

这个特定的过程会受到SQL注入的影响吗?我创建了这个过程,并通过各种尝试来执行它,比如EXEC test @password = '0; drop table credentials;',但是无法这样做。我想我可能做错了攻击。

EN

回答 6

Database Administration用户

回答已采纳

发布于 2023-03-15 16:26:37

SQL注入要求将恶意内容添加到(注入) SQL查询字符串,然后由数据库引擎解析并执行。因此,任何看似有效的SQL语句都将被执行。

存储过程中的查询在过程创建时被解析,很久之后它才能接收到任何恶意或非恶意的内容。在此之后,任何输入都将被简单地视为某种类型变量的值,而不是可执行指令。最糟糕的情况是存储在列中的值错误,或者语句由于值溢出或类似的错误而无法完全执行。没有任何意外的行动是可能的。

类似地,在可以接受任何参数值之前,将对准备好的语句进行分析和编译。稍后调用准备好的语句时,它将只接受与语句语义兼容的参数,并将它们视为值,而不是语句的一部分。

票数 15
EN

Database Administration用户

发布于 2023-03-16 18:36:28

仅仅是存储过程是防注入的是不够的。调用sproc的代码也必须是安全的。

作为一个简单的反例,请考虑以下调用sproc的C#代码:

代码语言:javascript
复制
string commandText = string.Format(
  "EXEC test @username = '{0}', @password = '{1}';", 
  username, password
);

SqlCommand command = new SqlCommand(commandText, connection);
command.Connection.Open();
command.ExecuteNonQuery();

用户名和密码由用户提示。假设用户名是bob,密码是blaah'; drop database northwind;--。在这种情况下,发送到Server的commandText如下所示:

代码语言:javascript
复制
EXEC test @username = 'bob', @password = 'blaah'; drop database northwind;--'

尽管存储过程可以很好地处理bob和blaah参数而不需要注入,但是代码的其余部分确实允许注入,因此您的一天将被毁。

安全的方法是使用参数化查询。其中,.Net客户端库确保正确转义传递给sproc参数的值。

代码语言:javascript
复制
SqlCommand cmd = new SqlCommand("sp_Add_contact", con)
cmd.CommandType = CommandType.StoredProcedure;

cmd.Parameters.Add("@username", SqlDbType.VarChar).Value = username;
cmd.Parameters.Add("@password", SqlDbType.VarChar).Value = password;
票数 8
EN

Database Administration用户

发布于 2023-03-15 16:09:50

使用动态SQL,首先构建SQL语句,然后在以后的步骤中执行它们。但在这种情况下,您将参数传递给查询。执行此语句"EXEC test @password = '0; drop table credentials;'"时,password的where子句将查找表中的值'0; drop table credentials;'。因此,此过程不容易受到SQL注入的影响。

票数 4
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/324787

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档