如何使用NpgsqlParameter与ExecuteSqlCommand避免注入攻击?获取NpgsqlException错误42601:语法错误在\“(\”“

时间:2015-08-07 04:43:04

标签: c# entity-framework postgresql npgsql

我正在使用PostgreSQL实体框架,这意味着我使用Npgsql作为数据提供者。我想调用context.Database.ExecuteSqlCommandAsync进行查询,我正在尝试使用参数来避免注入攻击。我想要进行的查询的一个示例是alter table add column。这是我的代码设置参数和sql查询的样子:

NpgsqlParameter tableNameParam = new NpgsqlParameter("tableName", NpgsqlDbType.Text);
tableNameParam.Value = entityTableName;
NpgsqlParameter fieldNameParam = new NpgsqlParameter("fieldName", NpgsqlDbType.Text);
fieldNameParam.Value = sqlFieldName;
NpgsqlParameter fieldTypeParam = new NpgsqlParameter("fieldType", NpgsqlDbType.Text);
fieldTypeParam.Value = sqlType;

object[] sqlParams = {tableNameParam, fieldNameParam, fieldTypeParam};

string addColumnQuery = "ALTER TABLE @tableName ADD @fieldName @fieldType";
await _context.Database.ExecuteSqlCommandAsync(addColumnQuery, sqlParams);

当我运行它时,我用

捕获一个NpgsqlException
  

错误42601:\“(\”“。

处或附近的语法错误

我查看了堆栈跟踪,发现ErrorSQL显示:

  

“ALTER TABLE(('dbo.person_entity'):: text)ADD(('name'):: text)(('varchar'):: text)”

正如您所看到的那样,查询出现了可怕的错误。在我的测试中,我正在使用person实体并添加类型为“varchar”的列“name”。我只想让查询像这样:

  

“ALTER TABLE dbo.person_entity ADD name varchar”

但由于某些原因,使用NpgsqlParameters搞砸了。我怀疑它与NpgsqlDbType.Text有关,但似乎NpgsqlParameter构造函数需要一个类型作为第二个参数。

1 个答案:

答案 0 :(得分:1)

首先,PostgreSQL不支持列/表名的参数。这种行为有一些很好的理由:允许用户在数据库中创建任意类型的任意字段通常没有意义 - 即使您清理它们以防止SQL注入。试着考虑重新设计你的应用程序。

有关您案例中发生的事情的更多技术说明,Npgsql Entity Framework提供程序将文本字面替换为参数占位符(例如@fieldName) - 和(&# 39; dbo.person_entity'):: text)是一个完全有效的文字。问题是列名称和类型不是文本文字:你不要用引号括起来。