sql - 是否有必要验证输入以防止 SQL 注入(inject)?

标签 sql security jpa sql-injection

我正在读这篇文章: https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html 我将 JPA 与准备好的语句一起使用(这是第一点)。 还有第三点,就是关于白名单的输入验证。

  • 使用准备好的语句时是否需要注意输入验证?
  • 我不明白白名单(第 3 点)。可以说,我有一个输入,您可以在其中写入文档的名称。我如何验证这个输入?您能给我一些如何验证输入以防止 SQL 注入(inject)的示例吗?所以我的 JPQL 查询是:

SELECT d FROM Document d WHERE d.user.id=:id AND d.title=:title

最佳答案

正如“您的常识”(希望也是您的常识)所说,通过使用准备好的语句(也称为参数化查询),在示例中将保护您免遭 SQL 注入(inject)。使用准备好的语句时,参数永远不会解释为 SQL,它们只是由数据库作为数据进行处理。

但是,当你可以做到时,验证始终是很好的防御性编码。数据(文档的名称)放入数据库后如何使用。开发人员经常将数据库中的数据视为“可信数据”,而没有正确利用编码或准备好的语句,这可能会导致各种问题,例如二阶 SQL 注入(inject)或存储型 XSS。

值的白名单验证是理想的选择,但这并不总是可行。在您的情况下,如何验证自由格式文本(例如文档名称)?您可能希望将您的名称限制为某些字符(字符白名单),但这可能会受到限制并导致国际化问题。至少:

  • 您可以要求大多数字段都有最大长度
  • 您通常应该验证任何字符串仅包含有效的 其编码的字符(例如, no ​​invalid UTF-8 sequences ) - this 通常可以在 WAF 或 servlet 过滤器中更普遍地完成
  • 您可能还希望将输入限制为 printable characters

通常 - 您应该始终:

  • 在将某些内容放入数据库(或跨任何信任边界传递)之前,尽可能多地验证输入
  • 将来自其他来源(例如数据库)的任何数据视为不受信任 - 并确保您使用准备好的语句、编码或以其他方式处理不受信任的数据

关于sql - 是否有必要验证输入以防止 SQL 注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57945247/

相关文章:

c# - .NET 程序集插件安全

Javax 持久性在生产级别将 IDENTITY 更改为 SEQUENCE

mysql - select 中的 SQL 循环

php - 在 php/sql 中选择不同的列,然后选择相关的列

sql - bigint 表示的最大值

sql - 使用 Shell 脚本和 SQL 查询的结果生成属性文件

ruby-on-rails - 生产服务器上的 Rails 安全性

php - 为什么连接失败时 PDO 会打印我的密码?

java - 从在 hibernate 中创建表中排除一个类

java - 使用@GeneratedValue(strategy=GenerationType.TABLE),sequence_next_hi_value 是一个 int(11) 但我的表有一个 id 列 bigint(20)