我试图截断一个表使用Java与Oracle数据库。我的目标是在避免SQL注入漏洞的同时实现这一点。下面是我尝试过的代码:
String tableName = "employee";
String truncateQuery = "TRUNCATE TABLE ?";
try (PreparedStatement statement = connection.prepareStatement(truncateQuery)) {
statement.setString(1, tableName);
statement.executeUpdate();
}
然而,当我执行这段代码时,我遇到了一个“无效的表名”错误。我知道将表名直接连接到查询字符串(“TRUNCATE TABLE”+ tableName)可能会导致命令注入漏洞。
我还确认了表名是有效的,因为直接在数据库中执行“TRUNCATE TABLE employee”可以正常工作。
我的问题是:在这种情况下,是否有一种方法可以有效地使用查询参数,以避免SQL注入,同时使用Java中的预准备语句和Oracle数据库截断表?
我感谢任何关于如何安全地实现这一目标的指导或建议。
2条答案
按热度按时间dhxwm5r41#
我不懂Java。但是,由于涉及到Oracle数据库,并且如果您可以使用存储过程,则可以将表名传递给它,并让过程截断作为参数传递的表。
大概是这样的:
测试:
dbms_assert.sql_object_name
验证输入参数字符串是否为现有SQL对象的限定SQL标识符
这意味着它可以防止你担心的SQL注入。
如果您接受了这个建议,那么剩下的就是了解如何从Java程序调用存储过程; A帮不上忙。
ycggw6v22#
在这种情况下,是否有一种方法可以有效地使用查询参数,以避免SQL注入,同时使用Java中的预准备语句和Oracle数据库截断表?
不你不能这么做正如评论者所说,SQL表名(或列名、表达式等)不能参数化为
PreparedStatment
。只有值可以参数化。AFAIK,对于所有其他数据库产品的JDBC驱动程序也是如此。
如何避免SQL注入和截断表?
您可以完全避免生成SQL字符串,并预先填充(比如说)一个
Map
来将用户提供的表名转换为每个(已知)表的TRUNCATE
语句,这对于用户来说是安全的。或者,您可以创建一个“安全截断”表的列表,并根据该列表验证用户提供的表名。然后为
TRUNCATE
生成SQL。或者,您可以确保用户不能提供表名。
底线是,在
PreparedStatement
中参数化SQL表名只会给您给予错误的安全感。坏人仍然可以通过传递一个 * 不应该 * 被截断的表名来造成混乱。