.NET中的SQL注入预防

cdu*_*dub 6 .net c# sql ado.net

我通常在.NET中编写我的SQL

sql.Append("SELECT id, code, email FROM mytable WHERE variable = @variable ");
Run Code Online (Sandbox Code Playgroud)

然后做这样的事情:

using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["defaultConnection"]].ConnectionString))
{
    using (SqlCommand myCommand = new SqlCommand(sql.ToString(), conn))
    {
        myCommand.Parameters.AddWithValue("@variable", myVariableName");
        ...
Run Code Online (Sandbox Code Playgroud)

但是当我得到的数据直接来自数据库时,我是否也应该这样做addParameter?

likesql.Append(string.Format("SELECT group_id, like_text FROM likeTerms ORDER BY group_id ASC "));

DataTable dtLike = SqlHelper.GetDataTable(likesql.ToString());

foreach (DataRow dr in dtLike)
{
    buildsql.Append(".... varId = " + dr["group_id"].ToString() + "...");

    ...
Run Code Online (Sandbox Code Playgroud)

这可以接受吗?什么是最佳做法?

Tas*_*ass 17

你应该总是使用参数:

  • 数据库中的值来自哪里?
  • 在您的示例中,您是否可以信任"group_id"未被修改为您不期望的内容?

不相信

具有有限数据库访问权限的人可以直接注入其他地方使用的字段

性能

此外,它有助于提高性能.缓存的执行计划将忽略参数的值,这意味着您每次参数更改时都会保存服务器不重新编译查询.


Kei*_*thS 5

当您使用带参数的DbCommands时,参数永远不会"内联"到查询中.而是将查询和参数数据传递给特殊的系统存储过程sp_executesql.当它以这种方式完成时,无论您拥有什么参数数据都被视为完全相同,并且不会从查询字符串中解析出来; 因此,从未执行过可能已通过验证的注入命令.

使用参数是基于ADO.NET的数据访问层的最佳实践,无论数据来自何处,IMO是在此级别应该完成的唯一方式(如果您不使用ORM).您永远不应该将从Web或Windows窗体中检索的值连接到SQL语句中,如果您遵循该规则,为什么要以不同的方式实现它只是因为您确信或甚至不确定信息不是直接的来自用户?遵循相同的模式,如果您公开该方法以持久保存用户指定的数据,则不会被烧毁.