使用表名称输入的最安全方式


Safest way to use input for table name?

我在我的网站上工作,目前正在修改我的一些SQL代码。我注意到,我把一个直接的用户输入放到一个代码中,这个代码可以找到一个表。

例如:

$query = 'SELECT NAME, GENDER FROM `' . $last_name . '` ORDER BY NAME';

我知道我不应该使用用户的输入作为表名,但在我的场景中,我没有其他选择。由于我没有其他选择,我想尽量确保它的安全。

我知道prepared语句不适用于表名,它们只适用于列值,所以我有点不知所措我应该使用mysql_real_eescape_string来克服这个问题吗我感谢所有的答案!

tldr:使用用户输入作为表名最安全的方法是什么?

我不喜欢让web程序访问我的数据库模式。我想说,让用户访问表子集的"最安全"的方法是创建一个包含公共表名的表

CREATE TABLE Public_Tables (table_id Int, table_name Varchar2);

您可以从架构中填充Public_Tables。

如果您给每个表一个唯一的整数,那么您将使用UID并减少SQL注入脚本的机会。

当然,在采取这一步骤之前,我会检查并规范我的表结构。我同意答案2。在我看来,LastName应该是表中的一列。

如果我真的必须为每个用户创建一个表,那么使用UID创建表会比使用姓氏创建表感觉更好。表可能是'User_1'、'User_2'而不是"Smith"、"O'Brien"、"Delete*'等。

一个有趣的案例。我会从给定的数据库中选择所有表名:

SELECT TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA='dbName' 

(来自通过SQL查询获取特定数据库的所有表名?

并使用结果创建应用程序可接受的表名白名单。简单而安全。

乍一看,我不得不问是否有必要为每个LAST_NAME都有一个单独的表?将LastName作为列似乎更有用,这将解决问题,因为您可以使用准备好的语句。

此外,使用带引号的表名通常会使其区分大小写,因此用户还必须更正大小写,否则将找不到表。

然而,假设重新设计应用程序以使用LastName作为列是不可能的-在实际运行查询之前,您可以使用准备好的语句在数据库元数据中查找表,例如在Oracle中(这是一种方法):

Select count(*) from USER_TABLES where TABLE_NAME = '?';

然后,您可以预先确定该表确实存在,这使您可以合理地确定它满足数据库语法要求,这反过来意味着它不太可能允许注入。但仍然不能保证,我认为。。。