使用 C# 检测破坏性 SQL 查询
Posted
技术标签:
【中文标题】使用 C# 检测破坏性 SQL 查询【英文标题】:detectecting destructive SQL queries with C# 【发布时间】:2015-05-11 01:10:28 【问题描述】:因此,我正在寻找一种更有效的方法来确定我编写的这段 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 大开眼界。我正在构建的这个工具的范围非常小,任何有权访问这个工具并且有恶意的人都是可以直接访问数据库的人。这些检查或多或少是为了防止懒惰。用例不允许参数化查询,否则我会这样做。您的见解很有教育意义,感谢您的所有帮助!
【问题讨论】:
如果将输入文本转换为小写,则需要检查的关键字很少,拼写排列也没有问题 您为什么要这样做?只需使用参数化查询,问题就消失了。 我会使用参数化查询......但如果你必须采用这种方法,你就会错过 truncate 语句。 不可能将操纵数据的查询完全列入黑名单。例如,用户可以编写诸如DECLARE @sql varchar(1000); SET @sql = 'TRUN' + 'CATE TABLE Foo'; EXEC (@sql);
之类的查询来绕过您提出的任何黑名单。用于访问 SQL Server 的帐户的受限权限将是防止未经授权的操作的唯一故障安全方法。
Regex 在这里也不会真正为您做更多的事情。即使你让它捕获了你所有的黑名单词,它也会拒绝像SELECT * FROM Report WHERE ReportTitle LIKE '%March Data Insert%'
这样的合法查询,并让像@John Bledsoe's这样的潜在恶意查询
【参考方案1】:
你可以这样做:
if (badSqlList.Any(r => sqltext.IndexOf(r, StringComparison.InvariantCultureIgnoreCase) >= 0))
//bad SQL found
IndexOf
和 StringComparison
枚举值将确保不区分大小写的比较。
另一种方法可能是:
return sqltext.Split()
.Intersect(badSqlList,StringComparer.InvariantCultureIgnoreCase)
.Any()
Split
您的 Sql 在空白处,然后将每个单词与您的白名单数组进行比较。如果您的 legal 表名包含 INESRTEDStudents
不太确定您的要求,但是,通常,更好的选择是首先使用参数化查询。您不能 100% 确定您的白名单,但仍有办法绕过它。
【讨论】:
谢谢!我今晚回家时会试试这个。不幸的是,这个工具的用例接受了大量不同类型的查询信息和参数,这会限制工具的使用。该工具的预期范围非常特定于管理管理员,因此破坏性查询不是一个大问题,但它仍然是一个问题。感谢此代码 sn-p。【参考方案2】:不要重新发明*** - 只需使用这里每个人都告诉您的参数化查询(修复比您目前意识到的更多的问题),您将在未来感谢所有人...
但请务必使用它来清理您在 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();
【讨论】:
谢谢你。今晚我将使用这段代码。以上是关于使用 C# 检测破坏性 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章
django-debug-toolbar在获取sql统计信息时破坏管理员