stored-procedures - CallableStatement 真的不受 SQL 注入(inject)的影响吗?

标签 stored-procedures jdbc sql-injection callable-statement

我们有一个 Java 应用程序可以与同一台服务器上的多个 SQL Server 数据库进行通信 盒子。这些数据库的数量和名称各不相同。总的来说,我们几乎完全使用带有 CallableStatement 的存储过程来访问数据库。我们非常擅长避免 SQL 注入(inject)和使用绑定(bind)变量。

唯一需要关注的是数据库名称本身连接到我们传递给 CallableStatement 的 SQL 中:

"{call [" + dbName + ".dbo." + procName + "(?, ?, ?)}"

procName 使用模板方法模式硬编码到子类中,因此可以保证字符串的安全。

dbName 是外部定义的。我尝试将 dbName 设置为各种模式以转义语法并在我的开发环境中利用它,但没有成功。

我已将其设置为以下内容以生成以下 SQL 调用(更改表和过程名称以保护无辜者):

securitytest].nx_proc()};delete from poor_victim_table;

成为

{call [securitytest].nx_proc()};delete from poor_victim_table;].dbo.proper_proc_name()}

securitytest].nx_proc()};exec('delete from poor_victim_table');

成为

{call [securitytest].nx_proc()};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}

导致 ')' 附近的语法不正确。poor_victim_table 仍然有行。我使用过truncate tabledrop tabledrop database,当它们不起作用时,我切换到简单的delete 排除安全设置。

如果我使用带有绑定(bind)参数的过程,我总是会在预期参数的数量和提供的参数之间出现不匹配,例如 The index 1 is out of range.

securitytest]};exec('delete from poor_victim_table');

成为

{call [securitytest]};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}

条条大路似乎都导致运行时错误,SQL不执行。当然,这很棒。但我想确保它失败是因为它不能成功,而不是因为我没有尝试正确的组合而失败。

流行的观点/都市神话是,使用存储过程可以让您免受 SQL 注入(inject)的影响,但在安全性方面,我宁愿不要相信这样的绝对陈述。

研究了一段时间后,我想到的最好的是这个 stackoverflow 问题:SQL injection - no danger on stored procedure call (on iSeries)? .它似乎支持使用 CallableStatement,因为它可以保护您免受 SQL 注入(inject)除非您的过程代码本身从输入参数中生成动态 SQL

因此,我向社区提出的问题是,假设 proc 中的 SQL 代码是安全的,那么在 JDBC 中使用 CallableStatement 真的能防止 SQL 注入(inject)吗?或者 SQL Server 驱动程序是否以阻止它的方式解析字符串,但其他驱动程序可能不会?还是我不够努力?

如果是安全的,如何保证?是否由于使用 { call blah(?) } 的抽象语法不是真正的 SQL,而是被转换为 SQL?

最佳答案

应该是安全的,但就像您一样,我不相信这一点,尤其是当您使用不同的 JDBC 驱动程序等连接到不同的数据库时。

如果我是你,在你发布声明之前,我会确保检查 dbName 是否包含除字母、数字和可能的下划线之外的任何内容。这应该允许所有有效的 dbNames,并防止各种困惑。

关于stored-procedures - CallableStatement 真的不受 SQL 注入(inject)的影响吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21053535/

相关文章:

tomcat - 我应该如何在基于 servlet 的应用程序中连接到 JDBC 数据库/数据源?

azure - Azure 函数中针对 Cosmos DB 的 SQL 注入(inject)

php - 即使使用 SQLite3::escapeString() 并且不要求用户输入,是否存在 SQL 注入(inject)漏洞?

SQL注入(inject)漏洞检查

mysql - 有关 MySQL 合并和存储过程的帮助

.net - 保留存储过程时先使用EF代码

excel - 使用 Excel 2010 通过存储过程读取/写入 SQL Server 2008 数据库

sql - 如何通过批处理将SQL存储过程保存到.sql文件

java - Java 中的安全 MySQL 连接?

sql - 两个 SELECT 和一个 SELECT 加 JOIN 的性能差异