1

此存储过程将检查用户名和密码,1如果凭据匹配 else 则返回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 注入技术将起作用。

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

换句话说我的问题

任何人都可以对这个查询进行注入吗?如果是,如何?

4

3 回答 3

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;--,那就太糟糕了...

于 2013-05-10T12:00:13.247 回答
0

Microsoft 有一些关于 SQL 注入的有用文档。正如它所解释的,有两种情况:

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

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

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

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

于 2013-05-10T14:19:54.673 回答
0

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

不要将您的查询字符串与用户输入连接。

像在示例中那样使用参数!

顺便提一句。您的示例不起作用,因为您只是声明了 @-variables 而不分配任何值。应该是您的存储过程 fe 的参数

于 2013-05-10T11:56:17.213 回答