此存储过程是否容易受到SQL注入攻击?

时间:2013-05-10 11:53:49

标签: sql sql-server-2008 sql-injection

此存储过程将检查用户名和密码,如果凭据与其他1匹配,则返回0

CREATE PROCEDURE usp_CheckPermisssions 
    @UserName NVARCHAR(50),
    @Password NVARCHAR(50)
AS
BEGIN
    SET NOCOUNT ON;

    IF EXISTS( SELECT 1 FROM dbo.Users WHERE Username=@username and Password=@password)
     RETURN 1
    ELSE
     RETURN 0
END
GO

这只是一个示例存储过程。我只想学习SQL注入技术,以防止我的代码被注入。

假设输入未在前端消毒。

我知道如果我在存储过程中使用动态查询或在前端定义查询,那么SQL注入技术将起作用。

不:输入将通过前端传递。

我的问题换句话说

有人可以对此查询进行注射吗?如果是,怎么样?

3 个答案:

答案 0 :(得分:5)

SQL注入很少发生在存储过程中。为此,您需要在过程中动态创建查询。

通常是调用受SQL注入的存储过程的代码。当您通过连接值而不正确编码来创建查询时,可以使用SQL注入来中断值并将代码注入查询。

危险代码示例:

string userName = Request.Form("username");
string password = Request.Form("password");

int ok;
using (SqlConnection conn = new SqlConnection(connStr)){

  // parameters are not encoded correctly, so totally open to SQL INJECTION!
  string query = "usp_CheckPermissions '" + userName + "', '" + password + "'";

  using (SqlCommand cmd = new SqlCommand(query, conn)) {
    cmd.CommandType = CommandType.Procedure;
    ok = cmd.ExecuteScalar();
  }
}

如果您使用密码';drop table Users;--登录,那就太糟糕了......

答案 1 :(得分:0)

防止sql注入的第一个经验法则是:

请勿使用用户输入连接您的查询字符串。

使用您在示例中所做的参数!

顺便说一下。你的例子不起作用,因为你只是声明了 @ -variables没有赋值。应该是参数 对于您的存储过程f.e。

答案 2 :(得分:0)

Microsoft在SQL注入方面有一些有用的documentation。正如它解释的那样,有两种情况:

  • 输入会立即与其他代码连接并执行
  • 输入直接保存到表中,稍后检索,与其他代码连接并执行

由于此过程中没有连接(动态SQL),因此它本身是安全的。但是,如果其他一些完全不同的代码段后来连接这些值,那么理论上你可能会遇到问题。

问题在于,在大多数系统中,';drop table Users;--是完全有效的密码,因为一般来说系统不应检查密码。所以有人可能会输入密码作为密码,希望稍后它会被连接并执行。

这意味着您需要在所有代码中随时随地使用参数。如果某些数据完全由用户控制 - 如密码 - 那么您需要确保即使在输入后也能正确处理它们。