我想要cach输入,这似乎就像SQL注入一样。所以我写了这个方法:
public static bool IsInjection(string inputText)
{
bool isInj = false;
string regexForTypicalInj = @"/\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix";
Regex reT = new Regex(regexForTypicalInj);
if (reT.IsMatch(inputText))
isInj = true;
string regexForUnion = @"/((\%27)|(\'))union/ix";
Regex reUn = new Regex(regexForUnion);
if (reUn.IsMatch(inputText))
isInj = true;
string regexForSelect = @"/((\%27)|(\'))select/ix";
Regex reS = new Regex(regexForSelect);
if (reS.IsMatch(inputText))
isInj = true;
string regexForInsert = @"/((\%27)|(\'))insert/ix";
Regex reI = new Regex(regexForInsert);
if (reI.IsMatch(inputText))
isInj = true;
string regexForUpdate = @"/((\%27)|(\'))update/ix";
Regex reU = new Regex(regexForUpdate);
if (reU.IsMatch(inputText))
isInj = true;
string regexForDelete = @"/((\%27)|(\'))delete/ix";
Regex reDel = new Regex(regexForDelete);
if (reDel.IsMatch(inputText))
isInj = true;
string regexForDrop = @"/((\%27)|(\'))drop/ix";
Regex reDr = new Regex(regexForDrop);
if (reDr.IsMatch(inputText))
isInj = true;
string regexForAlter = @"/((\%27)|(\'))alter/ix";
Regex reA = new Regex(regexForAlter);
if (reA.IsMatch(inputText))
isInj = true;
string regexForCreate = @"/((\%27)|(\'))create/ix";
Regex reC = new Regex(regexForCreate);
if (reC.IsMatch(inputText))
isInj = true;
return isInj;
}
但似乎我犯了一些错误,因为我的代码没有检测到注射。我做错了什么?我想在定义Regex表达式时有问题吗?
答案 0 :(得分:15)
不要尝试使用RegEx执行此操作 - 有太多方法可以解决它。请参阅this classic SO关于使用RegEx解析的答案 - 它特定于HTML,但仍适用。
您应该使用Parameters,这些都在BCL中并且内置了反SQL注入措施。
更新:(以下评论)
如果您真的必须解析SQL,请不要使用RegEx,原因是链接文章中列出的原因。 RegEx不是解析器,不应该用作解析器。
使用SQL解析器 - 这应该有助于清理尝试。以下是one,此处为another。
您可以继续进行科学调查。
答案 1 :(得分:3)
不要使用字符串解析或正则表达式来处理这类事情。 SQL语法过于复杂,无法使用正则表达式进行可靠的解析。
而是使用带占位符的参数化查询,并完全避免字符串连接。这将从根本上打败SQL注入。
var command = new SqlCommand(connection);
command.Text = "INSERT INTO foo (a, b, c) VALUES (@a, @b, @c)";
command.Parameters.AddWithValue("a", "this is invulnerable");
command.Parameters.AddWithValue("b", "to any sort of SQL injection");
command.Parameters.AddWithValue("c", "--'; DROP DATABASE");
command.ExecuteNonQuery();
答案 2 :(得分:2)
如果你真的想帮助你的“不那么有经验的程序员”,你最好不要试图检测他们在代码中执行内联sql的时间。写一个FxCop规则来发现它应该不会太困难。如果您将其作为后期构建过程的一部分包含在内,或者如果您拥有团队系统,请将规则设置为使构建失败,他们很快就会掌握它。
答案 3 :(得分:0)
SQL注入的问题是,用户输入用作SQL语句的一部分。通过使用预准备语句,您可以强制将用户输入作为参数的内容进行处理(而不是作为SQL命令的一部分)。查询参数通过将文字值与SQL语法分开来帮助避免此风险。
大多数客户端API(包括.NET)都支持查询的参数化。这允许将用户输入嵌入为参数。参数是用户输入值的占位符,在执行时替换。这样,用户无法注入SQL代码,因为整个用户条目被视为参数的值,而不是作为追加到查询的字符串。
参数化是SQL注入攻击的最佳解决方案。