是否需要验证输入以防止 SQL 注入?
Is it necessary to validate input for preventing SQL injection?
我正在阅读这篇文章:
https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
我将 JPA 与准备好的语句一起使用(这是第一点)。
还有第三点,就是讲白名单的输入验证。
- 我在使用准备好的语句时需要注意输入验证吗?
- 我不明白那个白名单(第 3 点)。比方说,我会有一个输入,您可以在其中写下文档的名称。我将如何验证此输入?你能给我一些如何验证输入以防止 SQL 注入的例子吗?所以我的 JPQL 查询是:
SELECT d FROM Document d WHERE d.user.id=:id AND d.title=:title
您正在为所有 SQL 数据文字(简单地说,字符串和数字)使用预准备语句,以将其放入您的查询中 来自变量。不需要其他验证。相反,在使用准备好的语句的问题上,不应该考虑数据源的问题(无论是用户输入还是其他任何东西)。只准备语句,无条件,不管任何情况。
在极少数情况下,当您需要从变量中添加任何其他 SQL 查询部分(例如标识符或关键字)时,应该实施基于白名单的过滤。该方法仅代表根据程序中硬编码的值列表过滤输入变量。鉴于选择总是有限的(与数据变量相反),这是很合理的。例如,如果 table 顺序基于用户输入,则应根据代码中预先编写的值列表检查字段名称和方向关键字(ASC 或 DESC)。
正如 "Your Common Sense"(希望也是您的常识)所说,您将通过使用准备好的语句(又名参数化查询)。使用准备好的语句时,参数永远不会被解释为 SQL,它们只是由数据库作为数据处理。
但是,只要你能做到,验证总是很好的防御性编码。数据(文档的名称)放入数据库后将如何使用。开发人员经常将数据库中的数据视为 "trusted data" 而没有正确利用编码或准备好的语句,这可能导致各种问题,例如二阶 SQL 注入或存储型 XSS。
值的白名单验证是理想的,但这并不总是可行的。在您的情况下,您如何验证自由格式的文本,例如文档名称?您可能希望将您的名字限制为某些字符(字符白名单),但这可能会受到限制并导致国际化问题。至少:
- 您可以要求大多数字段具有最大长度
- 你通常应该验证任何字符串只包含有效的
其编码的字符(例如,没有 invalid UTF-8 sequences)- 这个
通常可以在 WAF 或 servlet 过滤器中更普遍地完成
- 您可能还想将输入限制为 printable characters
通常 - 您应该始终:
- 在将某些内容放入数据库(或将其传递到任何信任边界)之前尽可能多地验证输入
- 将来自其他来源(例如数据库)的任何数据视为不受信任 - 并确保您使用准备好的语句、编码或以其他方式处理不受信任的数据
我正在阅读这篇文章: https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html 我将 JPA 与准备好的语句一起使用(这是第一点)。 还有第三点,就是讲白名单的输入验证。
- 我在使用准备好的语句时需要注意输入验证吗?
- 我不明白那个白名单(第 3 点)。比方说,我会有一个输入,您可以在其中写下文档的名称。我将如何验证此输入?你能给我一些如何验证输入以防止 SQL 注入的例子吗?所以我的 JPQL 查询是:
SELECT d FROM Document d WHERE d.user.id=:id AND d.title=:title
您正在为所有 SQL 数据文字(简单地说,字符串和数字)使用预准备语句,以将其放入您的查询中 来自变量。不需要其他验证。相反,在使用准备好的语句的问题上,不应该考虑数据源的问题(无论是用户输入还是其他任何东西)。只准备语句,无条件,不管任何情况。
在极少数情况下,当您需要从变量中添加任何其他 SQL 查询部分(例如标识符或关键字)时,应该实施基于白名单的过滤。该方法仅代表根据程序中硬编码的值列表过滤输入变量。鉴于选择总是有限的(与数据变量相反),这是很合理的。例如,如果 table 顺序基于用户输入,则应根据代码中预先编写的值列表检查字段名称和方向关键字(ASC 或 DESC)。
正如 "Your Common Sense"(希望也是您的常识)所说,您将通过使用准备好的语句(又名参数化查询)。使用准备好的语句时,参数永远不会被解释为 SQL,它们只是由数据库作为数据处理。
但是,只要你能做到,验证总是很好的防御性编码。数据(文档的名称)放入数据库后将如何使用。开发人员经常将数据库中的数据视为 "trusted data" 而没有正确利用编码或准备好的语句,这可能导致各种问题,例如二阶 SQL 注入或存储型 XSS。
值的白名单验证是理想的,但这并不总是可行的。在您的情况下,您如何验证自由格式的文本,例如文档名称?您可能希望将您的名字限制为某些字符(字符白名单),但这可能会受到限制并导致国际化问题。至少:
- 您可以要求大多数字段具有最大长度
- 你通常应该验证任何字符串只包含有效的 其编码的字符(例如,没有 invalid UTF-8 sequences)- 这个 通常可以在 WAF 或 servlet 过滤器中更普遍地完成
- 您可能还想将输入限制为 printable characters
通常 - 您应该始终:
- 在将某些内容放入数据库(或将其传递到任何信任边界)之前尽可能多地验证输入
- 将来自其他来源(例如数据库)的任何数据视为不受信任 - 并确保您使用准备好的语句、编码或以其他方式处理不受信任的数据