2

我有以下代码

public DataSet GetProject(string projectID)
{
   DataSet dataTable = new DataSet(); 
   DataAccess dataAccess = new DataAccess();
   OracleCommand commandOb = new OracleCommand();
   strQuery.Append("select projectName, managerName");
   strQuery.Append("from project ");
   strQuery.Append("where projectID = '" + projectID + "'");

   cmd.CommandText = strQuery.ToString();
   dataTable = dataAccess.ExecuteDataAdapter(commandOb);

   return dataTable;
}

这是构建查询并执行它的好方法吗?这是否容易受到 SQL 注入攻击?

在动态构建查询时是否有推荐的方法。任何帮助,将不胜感激。

4

2 回答 2

3

以这种方式构建查询确实使其容易受到 SQL 注入攻击,除非您手动转义了您的输入(IE 使“projectID”的值无法通过使用数据库引擎特定的转义序列来更改查询的结构)。但是,推荐的方法是使用参数化查询(有时称为“准备好的语句”)。使用参数化查询,您只需定义查询的结构,然后将输入值作为参数单独提供,从而防止您的查询结构通过 SQL 注入被更改。

这是您的示例,已更改为使用参数化:

public DataSet GetProject(string projectID)
{
   DataSet dataTable = new DataSet(); 
   DataAccess dataAccess = new DataAccess();
   OracleCommand commandOb = new OracleCommand();
   strQuery = @"select projectName, managerName
                  from project
                  where projectID = :ProjectID"

   cmd.CommandText = strQuery;
   cmd.Parameters.AddWithValue("ProjectID", projectID);
   dataTable = dataAccess.ExecuteDataAdapter(commandOb);

   return dataTable;
}

查询中的参数“:ProjectID”将替换为“AddWithValue”方法中给出的值。无论 'projectID' 变量中的值是什么,它都将始终作为 WHERE 子句的一部分进行评估。而之前,类似于 ['; DELETE FROM project;--] 通过将查询更改为如下所示可能会产生不良影响:

select projectName, managerName
  from project
  where projectID = ''; DELETE FROM project;--'
于 2013-07-24T03:04:20.163 回答
0

是的,查询容易被sql注入。如果projectID在您的应用程序中通过其他查询在内部检索,则它不太容易受到攻击,因为没有直接的用户输入。

但是,如果是某些用户输入:"=1' OR 'a'=a'",则将检索所有项目,允许在未经适当授权的情况下访问数据。更糟糕的是,可能会执行意外命令,例如删除所有记录。

尽管如此,最好的做法是使用参数化查询或绑定参数以获得更好的性能和防止注入的安全性。参数化查询转义保留字符,但您仍然必须手写所有查询。替代方案包括使用 ORM 等。

请参阅https://www.owasp.org/了解更多信息和关于注射的有用的.net特定博客系列,以及更多: http ://www.troyhunt.com/2010/05/owasp-top-10-for-net-开发人员-part-1.htmlsql

using (var cn = new OracleConnection(connString))
{
  var sql = "select projectName, managerName from project where projectID = :p1";
  using (var cmd = new OracleCommand(sql, cn))
  {
    cmd.BindByName = true; 
    cmd.Parameters.Add(new OracleParameter(":p1", OracleDbType.Varchar2, projectID,
                                            ParameterDirection.Input));
    using (var adapter = new OracleDataAdapter(cmd))
    {
      cn.Open();
      var dataSet = new DataSet();
      adapter.Fill(dataSet);
      return dataSet;
    }
  }
}

注意:这是与odp.net

于 2013-07-24T03:07:12.950 回答