如何将 NpgsqlParameter 与 ExecuteSqlCommand 结合使用来避免注入攻击?获取 NpgsqlException 错误 42601: \"(\"" 处或附近的语法错误

How to use NpgsqlParameter with ExecuteSqlCommand to avoid injection attacks? Getting NpgsqlException Error 42601: syntax error at or near \"(\""

我正在使用 Entity Framework 和 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

error 42601: syntax error at or near \"(\"".

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

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

如您所见,查询出现了严重错误。在我的测试中,我使用了一个人实体并添加了一个类型为 "varchar" 的列 "name"。我只希望查询像这样:

"ALTER TABLE dbo.person_entity ADD name varchar"

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

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

为了对您的情况进行更技术性的解释,Npgsql Entity Framework 提供程序将您的参数占位符(例如@fieldName)替换为 文本文字 - 并且(('dbo.person_entity')::text) 是一个完全有效的文字。问题是列名和类型不是文本文字:您没有用引号将它们括起来。