【发布时间】: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或其他方式执行。这是你能做的最糟糕的事情。
标签: c# mysql asp.net security stored-procedures