使用 C# 检测破坏性 SQL 查询

本文关键字:SQL 查询 破坏性 检测 使用 | 更新日期: 2024-11-04 17:29:14

所以我正在寻找一种更有效的方法来确定我编写的这个 C# 代码中数组中字符串的所有变体。我可以遍历整个字符串,并将 sqltext 中的每个字符与它前面的字符进行比较,使其过于复杂,或者我可以尝试学习新的东西。我在想必须有一种更有效的方法。我向一位同事展示了这个,她建议我使用正则表达式。我已经研究了一点正则表达式,但我似乎找不到正确的表达式。

我正在寻找的是一个版本,它采用此代码中数组索引的所有变体:

public bool securitycheck(String sqltext)
        {
            string[] badSqlList = new string[] {"insert","Insert","INSERT",
                                                "update","Update","UPDATE",
                                                "delete","Delete","DELETE",
                                                "drop","Drop", "DROP"};
            for (int i = 0; i < badSqlList.Count(); i++)
            {
                if (sqltext.Contains(badSqlList[i]) == true)
                {
                    return true;
                }
            }
            return false;
        }

但考虑到替代拼写。 例如,此代码没有考虑"iNsert,UpDate,dELETE,DrOP",但根据我的同事的说法,有一种方法可以使用正则表达式来考虑这一点。

在您看来,最好的方法是什么?

[更新]

谢谢大家,这里有很多非常好的信息,它确实让我对以编程方式处理 SQL 大开眼界。 我正在构建的这个工具的范围非常小,任何有权访问此工具并意图恶意的人无论如何都是可以直接访问数据库的人。 这些检查或多或少地防止懒惰。用例不允许参数化查询,否则我会这样做。您的见解非常有教育意义,感谢您的所有帮助!

使用 C# 检测破坏性 SQL 查询

你可以做:

if (badSqlList.Any(r => sqltext.IndexOf(r, StringComparison.InvariantCultureIgnoreCase) >= 0))
{
    //bad SQL found
}

具有StringComparison枚举值的IndexOf将确保不区分大小写的比较。

另一种方法是:

return sqltext.Split()
        .Intersect(badSqlList,StringComparer.InvariantCultureIgnoreCase)
        .Any()

在空白处Split Sql,然后将每个单词与白名单数组进行比较。如果您的法定表名称具有关键字,例如INESRTEDStudents


不太确定您的要求,但通常,更好的选择是首先使用参数化查询。你不能100%确定你的白名单,仍然有办法绕过它。

不要重新发明轮子 - 只需使用这里的每个人都告诉您的参数化查询(修复的问题比您当前意识到的还要多),您将来会感谢所有人......

但是,请使用它来清理WHERE子句中的所有过滤器字符串:

    public static string EscapeSpecial(string s)
    {
        Contract.Requires(s != null);
        var sb = new StringBuilder();
        foreach(char c in s)
        {
            switch(c)
            {
                case '[':
                case ']':
                case '%':
                case '*':
                {
                    sb.AppendFormat(CultureInfo.InvariantCulture, "[{0}]", c);
                    break;
                }
                case '''':
                {
                    sb.Append("''");
                    break;
                }
                default:
                {
                    sb.Append(c);
                    break;
                }
            }
        }
        return sb.ToString();
    }