可以在所有情况下保护非DDL语句,防止SQL注入。在JDBC中,这是通过PreparedStatement
和CallableStatement
完成的,它们允许插入参数,但不能用于DDL语句。
第三个是Statement
,它允许DDL语句,但不提供参数插入。我需要对数据库名称进行手动检查,以防止受到x"; DROP DATABASE "customer_data
之类的数据库名称的侵害。进行这种手动检查既感觉像是在重新发明方向盘,又是自己做安全工作,这都是不好的主意。
我缺少JDBC函数吗?以编程方式创建数据库是否有害?存储过程是否提供额外的保护级别?是否有维护良好且经过审核的库,用于检查传递给DDL语句的数据库名称和类似变量。
答案 0 :(得分:2)
即使在确实以预准备语句支持DDL的数据库中(例如,MySQL也支持,请参见https://dev.mysql.com/doc/refman/8.0/en/sql-syntax-prepared-statements.html),仍然确实不能将诸如模式名和列名之类的标识符作为参数。
仅在否则使用常量值(如带引号的字符串,带引号的日期/时间或数字文字)的情况下,才可以使用查询参数。不适用于标识符。
因此,您需要注意标识符。在将它们插入DDL语句之前,将它们列入白名单或在应用程序代码中进行某种模式匹配。不要只接受任何输入或不受信任的内容,而要在DDL中逐字使用它而不用某种方式对其进行过滤。
过滤并不难。我们进行与应用程序代码中正常工作相似的安全检查,例如在假定可以调用对象的方法之前检查对象是否为null
。或在将数字用作除数之前检查数字是否为零。