string[] theParms = ['parm1', 'parm2'];
string theQuery = "SELECT something, somethingAgain " +
"FROM aDBTable " +
"WHERE something = '{?}'" +
"AND something <> '{?}'";
我需要将{?}替换为 theParms 中定义的参数。
C#中是否存在某种类型的循环,我可以使用它来遍历字符串并将每个找到的{?}替换为相应的parm值?< / p>
这样的事情:
第一循环:
SELECT something, somethingAgain
FROM aDBTable
WHERE something = 'parm1' AND something <> '{?}'
第二次循环:
SELECT something, somethingAgain
FROM aDBTable
WHERE something = 'parm1' AND something <> 'parm2'
是否有某种类型的 REGEX 或通用框架功能可以执行上述操作?
sql注入检查
bool injectionCheckin = new injectionCheck().inCheck(theFinalQuery);
public class injectionCheck
{
public bool inCheck(string queryString)
{
var badWords = new[] {
"EXEC", "EXECUTE", ";", "-", "*", "--", "@",
"UNION", "DROP","DELETE", "UPDATE", "INSERT",
"MASTER", "TABLE", "XP_CMDSHELL", "CREATE",
"XP_FIXEDDRIVES", "SYSCOLUMNS", "SYSOBJECTS",
"BC_HOME_ADDRESS1", "BC_HOME_ADDRESS2", "BC_HOME_CITY", "BC_HOME_COUNTY", "BC_HOME_POSTAL", "BC_MAIL_ADDRESS1",
"BC_MAIL_ADDRESS2", "BC_MAIL_CITY", "BC_MAIL_COUNTY", "BC_MAIL_POSTAL", "BC_MAIL_STATE", "FLSA_STATUS", "GRADE",
"GRADE_ENTRY_DT", "HIGHEST_EDUC_LVL", "LAST_INCREASE_DT", "BC_SALP_DESCR", "BC_SALP_DESCRSHORT", "SAL_ADMIN_PLAN"
};
string pattern = "(?<!\\w)(" + Regex.Escape(badWords[0]);
foreach (var key in badWords.Skip(1))
{
pattern += "|" + Regex.Escape(key);
}
pattern += ")(?!\\w)";
dynamic _tmpCount = Regex.Matches(queryString, pattern, RegexOptions.IgnoreCase).Count;
if (_tmpCount >= 1)
return true;
else
return false;
}
}
答案 0 :(得分:2)
为什么不使用String.Format
?
string[] theParms = new string[] { "parm1", "parm2" };
string theQuery = @"SELECT something, somethingAgain
FROM aDBTable
WHERE something = '{0}'
AND something <> '{1}'";
var res = string.Format(theQuery, theParms);
结果:
SELECT something, somethingAgain
FROM aDBTable
WHERE something = 'parm1'
AND something <> 'parm2'
答案 1 :(得分:2)
始终按parameterized queries创建Sql命令:
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
using (SqlCommand cmd = conn.CreateCommand())
{
var @params = new Dictionary<string, object>{
{ "something", myValue },
{ "somethingDifferent", anotherValue },
};
cmd.CommandText = "SELECT something, somethingAgain " +
"FROM aDBTable " +
"WHERE something = @something'" +
"AND something <> @somethingDifferent'";
foreach (KeyValuePair<string, object> item in values)
{
cmd.Parameters.AddWithValue("@" + item.Key, item.Value);
}
DataTable table = new DataTable();
using (var reader = cmd.ExecuteReader())
{
table.Load(reader);
return table;
}
}
}
这可以防止所有类型的SqlInjection,并且你不会因为你的坏名单而进行任何奇怪的检查,这是非常混乱而且并没有真正阻止你,你可以通过一些转义来轻松绕过列表。特别是:当你已经准备就绪的方法完全符合你的要求时,你为什么要编写自己的验证呢?
答案 2 :(得分:1)
如果你想在任何一种情况下都这样做,你可以按照以下方式进行循环。
string theQuery = String.Format( "SELECT something, somethingAgain " +
"FROM aDBTable " +
"WHERE something = '{0}'" +
"AND something <> '{1}'",
theParams[0], theParams[1] );
答案 3 :(得分:1)
好的,为了避免注射以及所有这些,你为什么不这样做:
string[] theParms = // initialization
string theQuery = // initialization
SqlCommand cmd = new SqlCommand(/* enter connection string */, theQuery)
for(int i = 0; i < theParams.Length; i++)
{
int index = cmd.Text.IndexOf("{?}");
if(index > -1)
{
string pName = string.Format("@p{0}", i);
cmd.Text = cmd.Text.Remove(index, 3).Insert(index, pName);
cmd.Parameters.Add(new SqlParameter() { Name = pName, Value = theParms[i] });
}
}
这应该完全避免任何手动注入检查...至少如果你不能预先编译查询并且必须在运行时加载它。否则只需适当地制定SqlCommand的文本,你就不需要循环或任何东西。只是一个简单的初始化:
SqlCommand cmd = new SqlCommand(/* enter connection string */, "SELECT something, somethingAgain FROM aDBTable WHERE something = @p0 AND something <> @p1");
cmd.Parameters.Add(new SqlParameter() { Name = "@p0", Value = theParms[0] });
cmd.Parameters.Add(new SqlParameter() { Name = "@p1", Value = theParms[1] });
答案 4 :(得分:0)
您可以使用IndexOf
和子字符串查找每个实例
for(int i = 0; i < theParms.GetLength(0); i++)
{
string[] tempStrings = new string[]{ theQuery.Substring(0,theQuery.IndexOf("{?}") - 1),
theQuery.Substring(theQuery.IndexOf("{?}"), 3),
theQuery.Substring(theQuery.IndexOf("{?}") + 4) }
tempStrings[1] = tempStrings[1].Replace("{?}", theParms[i]);
theQuery = String.Join("", tempStrings);
}
虽然看到你之后检查注射,但使用String.Format
答案 5 :(得分:-1)
你不必自己处理它。相反,ADO.NET
允许您定义参数并设置其值。请参阅此处的示例。MSDN