如何以编程方式和注入安全的方式创建数据库?

How to create a database programmatically and injection-safe?

提问人:Kalle Richter 提问时间:9/18/2019 最后编辑:marc_sKalle Richter 更新时间:11/13/2019 访问量:178

问:

非 DDL 语句可以并且在任何情况下都应该受到保护,以防止 SQL 注入。在 JDBC 中,这是通过 和 完成的,它允许参数插入,但不能用于 DDL 语句。PreparedStatementCallableStatement

第三种是允许 DDL 语句,但不提供参数插入。我需要对数据库名称进行手动检查,以防止出现类似 .这种手动检查感觉既像重新发明轮子又像自己做安全,这两者都是坏主意。Statementx"; DROP DATABASE "customer_data

我是否缺少 JDBC 函数?以编程方式创建数据库是邪恶的吗?存储过程是否提供额外的保护级别?是否有维护良好且经过审计的库,用于检查传递给 DDL 语句的数据库名称和类似变量。

Java 数据库 安全性 JDBC SQL 注入

评论

0赞 deceze 9/18/2019
虽然在某些用例中,以编程方式创建数据库是合法的,但你的最后一句话让我相信你不确定你是否真的有这样的用例......?
0赞 Kalle Richter 9/18/2019
我想在数据库中分离客户,这些数据库可以在托管商之间移动。客户(数据)创建是以编程方式完成的,因此数据库创建也是如此。
1赞 deceze 9/18/2019
那么,从根本上准备的语句允许将查询的结构(您希望它在哪些表和哪些列上执行的操作)与特定值分开,从而防止更改查询结构。如果你以编程方式生成结构,那么根据定义,不可能有真正的保护,你要靠自己。
0赞 Your Common Sense 9/18/2019
最近的一个相关问题

答:

2赞 Bill Karwin 9/23/2019 #1

即使在支持DDL作为预处理语句的数据库中(例如,MySQL支持,参见 https://dev.mysql.com/doc/refman/8.0/en/sql-syntax-prepared-statements.html),架构名称和列名称等标识符仍然不能是参数。

只有在使用常量值(如带引号的字符串、带引号的日期/时间或数值文本)的情况下,才能使用查询参数。不适用于标识符。

因此,您需要小心标识符。在将它们插入 DDL 语句之前,将它们列入白名单或在应用程序代码中执行某种模式匹配。不要只接受任何输入或不受信任的内容,并在 DDL 中逐字使用它,而不以某种方式过滤它。

过滤并不难。我们执行与应用程序代码中的正常工作类似的安全检查,例如在假设我们可以对其调用方法之前检查对象是否存在。或者在将数字用作除数之前检查它是否为零。null

评论

0赞 Kalle Richter 9/23/2019
感谢您的输入。关于“过滤并不难”:我的问题不是很难解决问题。我想把事情做好。这是有区别的。我觉得我自己在做安全工作,这在实施此类过滤器和检查时不是一个好主意。像jooq这样的工具是解决方案吗?
0赞 Bill Karwin 9/23/2019
安全开发人员的责任。像 jOOQ 这样的框架具有使其方便的引用标识符的功能(参见 jooq.org/doc/latest/manual/sql-building/names),但使用这些功能取决于您。我的意思是不要盲目地将字符串连接在一起,而不使用提供的函数来引用标识符。