c#基本反SQL注入脚本

c# basic anti SQL Injection script

我已经构建了一个网页(ASP.Net C# 网络表单)以允许用户通过 select 自己的过滤选项来查询数据库。 用户知道基本的 SQL,并且知道他们要查询的 table 的字段名称。

我想尽可能多地阻止用户可以编写的任何恶意 sql 命令。

因此网页的结构是一个下拉列表,用户 select table 可以在其中查询,然后他们可以在文本框中键入 where 子句。所以构建查询的服务器端代码是:

"SELECT * FROM " + DdlTableName.SelectedValue + " WHERE " + TxtWhereClause.Text;

可能的安全漏洞在最后一部分,即他们可以输入“;Drop TableName

所以我试图通过在 TxtWhereClause.Text 字符串中搜索它们来消除所有这些可能的恶意命令。

public static Boolean checkForSQLInjection(string userInput)
{
    bool isSQLInjection = false;
    string[] sqlCheckList = { "--",";--",";","/*","*/","@@","@"};
    string[] sqlCheckList2 = { " alter ", " create ", " declare ", "delete ", " drop ", " insert ", " select ", " update ", " union " };
    for(int i = 0; i <= sqlCheckList.Length - 1; i++)
    {
        if((CheckString.IndexOf(sqlCheckList[i], StringComparison.OrdinalIgnoreCase) >= 0))
        { isSQLInjection = true; }
    }

    for(int i = 0; i <= sqlCheckList2.Length - 1; i++)
    {
        if((CheckString.IndexOf(sqlCheckList2[i], StringComparison.OrdinalIgnoreCase) >= 0))
        { isSQLInjection = true; }
    }

    return isSQLInjection;
}

请记住用于运行此查询的用户帐户是一个只读帐户,所以我应该没有任何问题,但我想通过验证输入。

我最初编写的上述代码很容易被破坏,例如 sqlCheckList2 在单词中包含空格以避免与字段名称不匹配,DeleteDate,UpdatedBy,但是如果我写“(Delete Table...”它不会被上面的脚本阻止。

你对如何正确构建它有什么建议,或者有一个库可以使用吗?

显然我不能使用 SQLParameterEntity Framework 或任何其他此类 ORM项目的数据库模式不固定,查询将来自第三方系统,我没有任何控制权: 用户将编写查询并将其放入他们自己的业务分析系统中,然后该系统将通过 table namewhere 子句[=44= 查询我的] 作为请求中的参数,响应将采用 JSON 格式(基本上是 API)。我之前在问题中描述的是将模拟 第三方系统 的网页,这可能是我无法控制的一切,从自定义网页到 Tableau

谢谢!

请不要尝试实施您自己的安全问题解决方案。使用 SqlCommand.Parameters 避免 SQL 注入或考虑 Entity Framework 而不是经典 ADO.NET.

当你说用户只知道基本的 SQL 那么为什么不通过下拉列表/复选框列表等来限制他们的选择呢?显然,如果他们需要编写复杂的查询,那么这将行不通,而且允许肯定不会安全,但是如果他们需要这样做,他们可能会知道比基本知识更多的东西 SQL。

第一部分是 select 在复选框列表或类似的查询中需要的表。您可以根据 select 离子将逻辑写入 return 可用列。

第二步是限制操作,例如select,通过下拉列表更新、删除等。

最后一步是通过下拉菜单强制用户进入 select 列来限制他们的 where 子句,并指定他们的参数类型。然后,您可以根据用户输入的内容对这些进行参数化。

说了这么多,还是觉得有风险

更新

根据您的最终评论,您似乎正在处理一个不太理想的情况。但是,使用您当前的方法,您实际上只是将 WHERE 子句与黑名单进行比较。这是一个有风险的策略,因为它会假设您的黑名单中没有的任何内容都是可以的。尝试与白名单(可接受的值)进行比较可能会更好,因此将其他一切视为风险。

可能您可以更进一步,首先检查白名单,然后检查黑名单,如果仍然没有定义为正常或不正常,则将其添加到查询队列中以供查看。