Sql Injection - 以下是不是容易受到攻击?
Posted
技术标签:
【中文标题】Sql Injection - 以下是不是容易受到攻击?【英文标题】:Sql Injection - Is the following open to attack?Sql Injection - 以下是否容易受到攻击? 【发布时间】:2015-03-11 05:25:12 【问题描述】:我最近开始在一家对 SQL 注入攻击持开放态度的公司工作。因为他们几乎没有输入卫生设施。
在指出问题后,我的任务是修复它。
通常这很容易,用 SQLParamater 对象替换裸变量。 然而,我发现了一些让我感到疑惑的稍微奇怪的代码用法。
似乎我的前任一直在使用存储过程和一些驻留在代码中的 SQL。然而在一个地方,他似乎将两者结合起来。
他正在使用一些裸变量动态构建 SQL,然后将生成的 SQL 作为参数传递给存储过程。
我想知道它的安全性,是否将实际 SQL 作为参数传递来对其进行清理,或者我是否必须重新设计存储过程?
这是他正在做的一个(大大简化的)sn-p:
DataSet ExecuteQuery(string unsanitizedInput)
string dynamicSQL = "WHERE column = " + unsanitizedInput;
mysqlParameter param = new MySqlParameter("param1", dynamicSQL);
string procname = "StoredProc_Name";
DataSet ds = new DataSet();
using (MySql.Data.MySqlClient.MySqlDataAdapter adapter = new MySql.Data.MySqlClient.MySqlDataAdapter(procname, DataUtils.ConnectionStrings["string"]))
adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
adapter.SelectCommand.Parameters.Add(param);
adapter.Fill(ds);
return(ds);
显然,实际查询要复杂得多,参数很多。但这应该让您了解他在做什么。
我的问题是:上述安全吗? 即使是要注入存储过程的更大 SQL 语句的一部分,未清理的输入是否也会被清理?
我知道上面的做法很糟糕,并且几乎不可能弄清楚 SQL 查询,但这就是我现在所处的位置。
所有建议均已采纳,并在此先感谢。
【问题讨论】:
取决于输入,即如果输入是(1 或 1 =1),那么是的,它可以被攻击。 Where 子句将被绕过。 我认为最好的方法是使用参数化查询。并在处理之前将输入验证为查询。如果我们能找到某些类型的 sql 注入语句,则避免该输入。 您没有显示存储的过程,但我假设如果动态 SQL 被传递给它,那么过程正在使用代码构建查询然后执行它(例如,EXECUTE command 在 T -SQL)。在这种情况下,它仍然会受到 SQL 注入攻击。 感谢 cmets。是的,他在动态构建查询后使用“EXECUTE”,他作为参数传递的SQL通常是代码中动态生成的一整套条件子句。我会发布完整的查询,但它大约有 1000 行长,因为我很确定我的前任缺乏理智。我想这意味着我应该安全地重写它。再次感谢 cmets 伙计们,如果您发布答案,我会正确标记... 由于您不能将WHERE
子句作为参数传递,我对这个问题的回答是:不,它既不安全,也不能正常工作。 唯一 可以工作的方式是 SQL 语句是在存储过程中连接的字符串,然后使用 exec
或其他方式执行。这是你能做的最糟糕的事情。
【参考方案1】:
带参数的查询不提供针对 slq 注入攻击的全面保护,也不提供存储过程。两者我都用过,但在 2010 年被站点的 db 严重伤害了 two-step sql injection。
MSDN 强烈建议检查任何输入文本中的可疑元素。查看更多How To: Protect From SQL Injection in ASP.NET。
我使用以下简单代码来检测 sql 注入(使用一些我已经记不起的好资源构建):
public static bool DetectSqlInjection(string Text)
string CleanText = Text.ToUpper().Replace("/**/", " ").Replace("+", " ").Replace(" ", " ");
string[] InjectionPatterns =
"VARCHAR",
"EXEC",
"DECLARE",
"SELECT *",
"SELECT PASSWORD",
"SELECT USERNAME",
"$_GET",
"NULL OR",
"UNION ALL SELECT",
"WAITFOR DELAY",
"SELECT pg_sleep",
"SHOW TABLES FROM"
;
foreach (string Pattern in InjectionPatterns)
if (CleanText.Contains(Pattern))
return true;
return false;
【讨论】:
您正在推荐 2005 年 5 月以来的 .NET 2.0 指南?今天的建议是使用准备好的语句提供的参数化。 变化越多,它们就越保持不变。关于 sql 注入攻击,自 2005 年以来唯一的变化是它们的攻击变得更加全面且难以识别。我也相信参数化,直到 2010 年,当我明白参数化不是万能药,虽然是一种非常不愉快的体验。以上是关于Sql Injection - 以下是不是容易受到攻击?的主要内容,如果未能解决你的问题,请参考以下文章
以下代码片段是不是容易受到 Rails 5 中 SQL 注入的影响?
SQL Server 全文搜索 CONTAINS() 是不是容易受到 SQL 注入的攻击?