【问题标题】:Dynamic SQL - Search Query - Variable Number of Keywords动态 SQL - 搜索查询 - 可变数量的关键字
【发布时间】:2010-09-14 09:20:30
【问题描述】:

我们正在尝试更新我们的经典 asp 搜索引擎以保护它免受 SQL 注入。我们有一个 VB 6 函数,它通过基于各种搜索参数将查询连接在一起来动态构建查询。我们已将其转换为使用动态 sql 的存储过程,用于除关键字之外的所有参数。

关键字的问题是用户提供的单词数量不定,我们想为每个关键字搜索几列。由于我们不能为每个关键字创建单独的参数,我们如何构建一个安全的查询?

例子:

@CustomerId AS INT
@Keywords AS NVARCHAR(MAX)

@sql = 'SELECT event_name FROM calendar WHERE customer_id = @CustomerId '

--(loop through each keyword passed in and concatenate)

@sql = @sql + 'AND (event_name LIKE ''%' + @Keywords + '%'' OR event_details LIKE ''%' + @Keywords + '%'')'

EXEC sp_executesql @sql N'@CustomerId INT, @CustomerId = @CustomerId

处理此问题并保持对 SQL 注入的保护的最佳方法是什么?

【问题讨论】:

    标签: sql sql-injection dynamic-sql


    【解决方案1】:

    您可能不喜欢听到这种说法,但在针对数据库发出之前,您最好回到用代码动态构建 SQL 查询的方式。如果您在 SQL 字符串中使用参数占位符,您将获得针对 SQL 注入攻击的保护。

    例子:

    string sql  = "SELECT Name, Title FROM Staff WHERE UserName=@UserId";
    using (SqlCommand cmd = new SqlCommand(sql))
    {
      cmd.Parameters.Add("@UserId", SqlType.VarChar).Value = "smithj";
    

    您可以根据需要查询的列集构建 SQL 字符串,然后在字符串完成后添加参数值。这样做有点麻烦,但我认为这比使用真正复杂的 TSQL 要容易得多,因为 TSQL 会取消选择可能输入的许多可能排列。

    【讨论】:

      【解决方案2】:

      这里有 3 个选项。

      1. 使用function that converts lists tables 并加入其中。所以你会有这样的东西。

        SELECT * 
        FROM calendar c
           JOIN dbo.fnListToTable(@Keywords) k 
               ON c.keyword = k.keyword  
        
      2. 有一组固定的参数,只允许搜索最多N个关键字

        CREATE PROC spTest
        @Keyword1 varchar(100),
        @Keyword2 varchar(100),
        .... 
        
      3. 在 TSQL 中编写转义字符串函数并转义关键字。

      【讨论】:

        【解决方案3】:
        • 除非您需要它,否则您可以简单地删除任何不在 [a-zA-Z] 中的字符 - 大多数这些内容不会出现在搜索中,并且您不应该以这种方式被注入,您也不必担心关键字或类似的东西。但是,如果您允许使用引号,则需要更加小心。

        • 与 sambo99 的 #1 类似,您可以将关键字插入到临时表或表变量中并连接到它(即使使用通配符),而没有注入的危险:

        这并不是真正的动态:

        SELECT DISTINCT event_name
        FROM calendar
        INNER JOIN #keywords
            ON event_name LIKE '%' + #keywords.keyword + '%'
            OR event_description LIKE '%' + #keywords.keyword + '%'
        
        • 您实际上可以生成具有大量参数的 SP,而不是手动编码(根据您对搜索编码的偏好,将默认值设置为 '' 或 NULL)。如果你发现你需要更多的参数,增加它生成的参数的数量会很简单。

        • 您可以将搜索移至数据库外部的全文索引(如 Lucene),然后使用 Lucene 结果拉取匹配的数据库行。

        【讨论】:

          【解决方案4】:

          你可以试试这个:

          SELECT * FROM [tablename] WHERE LIKE % +keyword%
          

          【讨论】:

            猜你喜欢
            • 2016-04-05
            • 1970-01-01
            • 1970-01-01
            • 2015-11-15
            • 2020-11-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多