如何将表名作为参数放入SQL查询的安全方法是什么?您不能使用PreparedStatement将表名作为参数。可以使用Statement连接字符串以使用动态表名执行查询,但不建议使用SQL注入的风险。这样做的最佳方法是什么?
答案 0 :(得分:3)
最好的方法是:
因此,例如在MySQL
的情况下,表名的分隔符是反引号字符,我们通过简单地加倍来逃避它。
如果您的查询是SELECT foo from bar
,则可以将查询重写为下一个:
String query = String.format("SELECT foo from `%s`", tableName.replace("`", "``"));
通过这种方式,您可以注入表的名称,而不会冒着看到注入恶意代码的风险。
答案 1 :(得分:2)
我会尝试解决设计问题,因此您不必动态设置表名。如果这是不可能的,我会去设计一个管理可用表列表的设计,用户从那里选择一个BY ID,这样你就可以从所选的id中检索真实的表名,并用它替换表名占位符。 ,避免在表名替换中有任何sql注入的机会。
答案 2 :(得分:1)
在动态JDBC查询中仅允许实际参数背后有一个基本原理:参数可以来自外部并且可以取任何值,而表和列名称是 static 。
可以有用于参数化表或列名的用例,主要是当不同的表具有几乎相同的结构时,并且由于DRY原则,您不希望重复多次相同的查询,只更改表(或列)名称。但在该用例中,程序员可以完全控制将被替换的名称,并且应该仔细测试其中任何一个中没有拼写错误=>这里没有SQL注入的可能性,可以安全地替换查询字符串中的表名。
对于在互联网上公开的Web应用程序来说,这是完全不同的,其中查询将使用在表单字段中输入的内容,因为这里可能发生任何事情,包括用于终止原始无害查询的分号并伪造新的有害数据= >如果您只是连接字符串而不是正确构建参数化查询,则使用SQL注入。
我无法想象一个用例,其中表名或列名可以是用户在表单字段中键入的字符串,这是允许参数化它们的唯一原因。