【问题标题】:Remove apostrophe from parameter query in MVC?从 MVC 中的参数查询中删除撇号?
【发布时间】:2015-08-25 18:40:37
【问题描述】:

我意识到这个话题已经被大量讨论...我已经阅读了很多关于 SQL 注入等的帖子。如果我问类似的问题,我很抱歉,但我无法找到我的情况的答案.

我在搜索页面上有一个字段,允许用户根据标题进行搜索。我的项目构建了一个 SQL 查询字符串来检索数据,但该字符串绝不是 URL 的一部分。如果有人搜索包含撇号的标题,则查询失败。我想知道如何解决这个问题,以及在允许用户根据标题进行搜索的同时,我还需要哪些其他安全措施来确保安全。请注意,最终将有大约 20,000 个标题可供选择。

在我的控制器的 POST 中:(以及大约 50 个其他参数)

 if (results.Title != null)
                wherestatements.Add("title like '%" +  results.Title + "%'");
 //Collect all other values of the search//

 //BUILD SQL statement//
 SQLstatement = string.Format("select * from Cards where {0} and {1} and (({2}) or ({3})) 
 and CardID In (Select CardID from CardAbilities where {4});",
 final, //This is my where the title is included
 finalexcludefrommulti, finalsplit, finalmulti, finalability);

 //EXECUTE Query & Return View//
 var CardList = db.Cards.SqlQuery(SQLstatement).ToList();
  return View(CardList.ToPagedList(pageNumber, pageSize));

【问题讨论】:

  • 肯定想要摆脱那个 SQL 注入漏洞。这就是你的问题的根本原因,并且可能成为更严重的问题的根本原因。从发布的 SQL 查询中并不清楚它的实际结构是什么,因为它是由我们看不到的变量构建的。但本质上你想使用查询参数而不是直接将用户输入作为代码执行。向WHERE 子句动态添加检查可能会有点棘手,但并非不可能。
  • 永远不要根据用户输入构建完整的 sql 语句。如果您已经进行了适当的研究,那么您应该完全意识到传递用户输入的唯一安全方法是通过参数。
  • 我完全赞成摆脱这个漏洞。我只是不知道如何使用查询参数,也不确定如何让它与 where 语句一起使用。使用参数如何仍然允许某人搜索包含撇号的标题而不让 SQL 注入撇号通过?

标签: sql asp.net-mvc security


【解决方案1】:

与此同时,我已经做到了,只有字母可以被接受作为输入,但撇号除外,然后在传递给查询之前将其替换。我仍然想知道如何使用参数来做到这一点。

【讨论】:

    【解决方案2】:

    更好的方法是使用 ORM 并根据需要查询列表/过滤它。 我同意其他永远不会使用 sql 注入公开您的网站的观点。

    【讨论】:

    • 给定上面带有变量的 SQL 字符串,这里是一个可以转换为 SQL 语句的示例。由于字符限制,我将不得不将其分解为多个 cmets:select * from Cards where power > 3 and toughness <= 5 and maintypeid = 1 and subtypeid = 15 and rarityid = 1 and greenbluemanacost is null and greenblackmanacost is null and blueblackmanacost is null and greenmanacost is null and bluemanacost is null and blackmanacost is null and ((redwhitemanacost > 0 or redgreenmanacost > 0 or redbluemanacost > 0 or redblackmanacost > 0 or redorlifecost > 0
    • or whitegreenmanacost > 0 or redwhitemanacost > 0 or whitebluemanacost > 0 or whiteblackmanacost > 0 or whiteorlifecost > 0 ) or (redmanacost > 0 or whitemanacost > 0 )) and CardID In (Select CardID from CardAbilities where abilityid = 2) and CardSetID In(Select distinct CardSetID from Cardsets where cardsets.ReleaseDate= (Select Max(ReleaseDate) from CardSets)); 如何安全地从用户输入创建查询?
    【解决方案3】:

    好吧,我会说更改为使用参数而不是向 SQL 中注入值,但是由于您的 WHERE 子句非常动态,因此并不简单。看来您需要:

    1) 生成 WHERE 子句的集合,每个子句都包含对参数的引用 2) 将参数值添加到值列表中

    类似:

    List<object> parameters = new List<object>();
    
    ...
    
    
    if (results.Title != null)
    {
        wherestatements.Add("title like @title");
        parameters.Add("%" + results.Title + "%");
    }
    //Collect all other values of the search//
    
    //BUILD SQL statement//
    SQLstatement = string.Format("select * from Cards where {0} and {1} and (({2}) or ({3})) and CardID In (Select CardID from CardAbilities where {4});",
    final, //This is my where the title is included
    finalexcludefrommulti, finalsplit, finalmulti, finalability);
    

    然后通过传入参数执行您的查询:

    //EXECUTE Query & Return View//
    var CardList = db.Cards.SqlQuery(SQLstatement, parameters).ToList();
                                                   ^-- pass parameters here
    

    【讨论】:

    • 这如何防止{0}成为-- Drop Table Users(sql注入)?
    • @ErikPhilips 这取决于注入的值是如何生成的。如果是用户输入,那么仍然存在漏洞。但是,如果它是由问题所建议的代码生成的 ("title like @title"),那么 SQL 注入是不可能的。
    猜你喜欢
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 2021-07-18
    • 2014-09-12
    • 1970-01-01
    相关资源
    最近更新 更多