大多数SQL注入的答案和示例都显示了某种形式的动态SQL或将参数解释为SQL。
我还没有找到“正确”方式的例子。微软和甲骨文的文档只是给出了一些不应该做的例子。
因此,我想我应该问一下这个存储过程示例是否受到SQL注入攻击的保护。
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;',但是无法这样做。我想我可能做错了攻击。
发布于 2023-03-15 16:26:37
SQL注入要求将恶意内容添加到(注入) SQL查询字符串,然后由数据库引擎解析并执行。因此,任何看似有效的SQL语句都将被执行。
存储过程中的查询在过程创建时被解析,很久之后它才能接收到任何恶意或非恶意的内容。在此之后,任何输入都将被简单地视为某种类型变量的值,而不是可执行指令。最糟糕的情况是存储在列中的值错误,或者语句由于值溢出或类似的错误而无法完全执行。没有任何意外的行动是可能的。
类似地,在可以接受任何参数值之前,将对准备好的语句进行分析和编译。稍后调用准备好的语句时,它将只接受与语句语义兼容的参数,并将它们视为值,而不是语句的一部分。
发布于 2023-03-16 18:36:28
仅仅是存储过程是防注入的是不够的。调用sproc的代码也必须是安全的。
作为一个简单的反例,请考虑以下调用sproc的C#代码:
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如下所示:
EXEC test @username = 'bob', @password = 'blaah'; drop database northwind;--'尽管存储过程可以很好地处理bob和blaah参数而不需要注入,但是代码的其余部分确实允许注入,因此您的一天将被毁。
安全的方法是使用参数化查询。其中,.Net客户端库确保正确转义传递给sproc参数的值。
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;发布于 2023-03-15 16:09:50
使用动态SQL,首先构建SQL语句,然后在以后的步骤中执行它们。但在这种情况下,您将参数传递给查询。执行此语句"EXEC test @password = '0; drop table credentials;'"时,password的where子句将查找表中的值'0; drop table credentials;'。因此,此过程不容易受到SQL注入的影响。
https://dba.stackexchange.com/questions/324787
复制相似问题