繁体   English   中英

.NET中的SQL注入预防

[英]SQL Injection Prevention in .NET

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

sql.Append("SELECT id, code, email FROM mytable WHERE variable = @variable ");

然后做这样的事情:

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

但是当我得到的数据直接来自数据库时,我是否也应该这样做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() + "...");

    ...

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

你应该总是使用参数:

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

不相信

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

性能

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

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

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

这是可以接受的(从某种意义上说,如果你知道限制,你有时可能正常工作)

使用数据库中的值并使用字符串连接构建SQL查询是不错的做法 - 否。

即你的样本,如果“group_id”是"'--"怎么办?

我建议使用存储过程,但这是可以接受的我还建议您在将参数分配给查询之前清理它们

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM