UpT*_*ide 10 security sql-server sql-injection t-sql
大多数 SQL 注入的答案和示例都显示某种形式的动态 SQL 或将参数解释为 SQL。
我还没有找到“正确”方式的例子。Microsoft 和 Oracle 的文档仅显示了不应做什么的示例。
因此,我想我应该询问这个存储过程示例是否受到 SQL 注入攻击的保护。
CREATE PROCEDURE test
@username = varchar(30)
@password = varchar(30)
AS
BEGIN
SELECT *
FROM credentials
WHERE username = @username
AND password = @password;
END
GO
Run Code Online (Sandbox Code Playgroud)
这个特定的过程是否容易受到 SQL 注入的影响?我创建了该过程并通过各种尝试注入 SQL 来执行它,例如EXEC test @password = '0; drop table credentials;'
,但无法这样做。我想我可能没有正确地进行攻击。
mus*_*cio 15
SQL注入需要将恶意内容添加到(注入)SQL查询字符串中,然后由数据库引擎解析并执行。因此,任何看起来像有效 SQL 语句的内容都将被执行。
存储过程中的查询是在过程创建时解析的,早在它可以接收任何内容(无论是否恶意)之前。此后,任何输入都将被简单地视为某种类型变量的值,而不是可执行指令。最糟糕的情况是列中存储了错误的值,或者由于值溢出或类似错误而导致语句完全执行失败。不可能采取意外的行动。
类似地,在接受任何参数值之前,将解析和编译准备好的语句。当您稍后调用准备好的语句时,它只会接受与语句语义兼容的参数,并将它们视为值,而不是语句的一部分。
仅存储过程是防注入的还不够。调用存储过程的代码也必须是安全的。
作为一个简单的反例,请考虑以下调用存储过程的 C# 代码:
string commandText = string.Format(
"EXEC test @username = '{0}', @password = '{1}';",
username, password
);
SqlCommand command = new SqlCommand(commandText, connection);
command.Connection.Open();
command.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)
用户名和密码由用户提示。假设用户名是,bob
但密码是 blaah'; drop database northwind;--
。在这种情况下,发送到 SQL Server 的 commandText 将如下所示:
EXEC test @username = 'bob', @password = 'blaah'; drop database northwind;--'
Run Code Online (Sandbox Code Playgroud)
尽管存储过程无需注入即可正常处理bob
和blaah
参数,但其余代码确实允许注入,因此您的一天将被毁了。
安全的方法是使用参数化查询。在这些中,.Net 客户端库确保传递给存储过程参数的值被正确转义。
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;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2622 次 |
最近记录: |