java - 使用准备好的语句从用户输入创建数据库以防止 SQL 注入(inject)

标签 java prepared-statement sql-injection

在我们的应用程序中,我们接受用户输入(如项目名称),然后使用它为用户创建数据库(以及其他内容)。我想防止 SQL 注入(inject),但无法准备用于创建数据库和授予访问权限的 SQL 语句。有没有一种安全的方法来防止用户 SQL 注入(inject)我们?我所能想到的就是将输入限制为英文字母和空格(对于数据库名称,将它们替换为下划线),如果我们将 SQL 语句括在单引号内,这反过来可以提供保护。这是一个合理的解决方案吗?

我们正在使用带有 Postgres 10.6 数据库的 java 8/spring boot。我玩过 SQL,据我所知,准备好的语句只能用于更新、删除和更新等查询。我曾尝试修改代码以尝试从用户输入中删除一些表,但幸运的是,它没有用,但我想确保该应用程序不会受到攻击。

String createDbSQL = "create database ?";
Connection connection = DriverManager.getConnection(env.getDbUrl(), env.getDbUsername(), env.getDbPassword());
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement(createDbSQL);
preparedStatement.setString(1, "test_db_name");
preparedStatement.execute();

失败并返回 org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"(如果准备好的语句不能用于创建数据库,这是有意义的`

PREPARE foo (text) AS create alter database $1;

期望查询表达式但不起作用

最佳答案

这不是必需的,并且可能会导致超出 sql 注入(inject)可能性的问题。如果您负责提供数据库,则需要负责命名。

您可以让用户提供一个名称,就他们而言,这是数据库的名称,但是您创建和使用数据库的代码可以使用您自己生成和控制的名称。这样,如果出于某种原因你需要给它一个不同的名称,或者创建一个新的数据库副本,或者切换到一个不同的数据库平台,用户提供的名称遵循不同的规则(并且他们选择的名称可能无效) ,您不会受到任何阻碍。

关于java - 使用准备好的语句从用户输入创建数据库以防止 SQL 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56084715/

相关文章:

php - 我可以将数组绑定(bind)到 PDO 查询中的 IN() 条件吗?

java - Websphere Application Server 中的 XAException

java - 找不到运行应用程序模块时出错

Java + MySQL -PreparedStatement 编码遇到问题

python - 使用 psycopg2 : SELECT from a Python list 的参数化查询

php - 如何防止在 Zend Framework 中编程的应用程序中的 SQL 注入(inject)攻击?

go - 防止beego中的SQL注入(inject)

php - 使用数据库级 MD5 函数是否比应用程序级函数具有更大的安全风险?

java - 如何在 webdriver 支持的 Selenium RC 中包含正则表达式?

java - 对固定大小的组件使用覆盖 getPreferredSize() 而不是使用 setPreferredSize()