我有一个这样的查询:
"SELECT * FROM MyTable_" + myID + " WHERE variable = @variable";
SQL 参数化适用于变量,但如何让它适用于表名?myID 是我传入并更改的 int(可以转换为字符串),但是如何防止此处的 sql 注入?
我有一个这样的查询:
"SELECT * FROM MyTable_" + myID + " WHERE variable = @variable";
SQL 参数化适用于变量,但如何让它适用于表名?myID 是我传入并更改的 int(可以转换为字符串),但是如何防止此处的 sql 注入?
只要myID
是数值变量,就不能包含任何有害代码。
您需要做的唯一另一件事是确保尝试读取不存在的表时的错误消息不会泄漏有关可能有助于某种其他类型攻击的数据库布局信息.
我质疑您为什么要这样做,但您可以查看sys.tables
一个确凿的白名单。
DECLARE @TableName VARCHAR(100) = 'Table to Look for';
DECLARE @Exists BIT = ( SELECT CAST( COUNT(1) AS BIT ) FROM sys.tables WHERE name = @TableName AND type = 'U' );
您可以参数化初始输入,但白名单方法仍然很重要。否则,恶意用户可以传递整个数据库中的任何有效表名,并且查询将针对它运行(假设他们具有 SELECT 权限)。
获取数据库中的表列表并检查该"MyTable_" + myID
列表中的表。
REDESIGN是答案,没有动态表名。在表内有一个值来指示您的原始表名称,并且只有一个表用于所有当前表。
如果您遇到必须与系统其他部分向后兼容的现有内容,您可以(并且应该)组合方法。转义、白名单或引用都是可行的,我会说选择两个。
当我说“引用”时 - 将所有有效名称放在一个列表中,传递一个整数索引来选择一个。