java - 使用准备好的语句从用户输入创建数据库以防止 SQL 注入
问题描述
在我们的应用程序中,我们接受用户输入(如项目名称),然后使用它为用户创建一个数据库(除其他外)。我想防止 SQL 注入,但无法准备用于创建数据库和授予访问权限的 SQL 语句。有没有一种安全的方法可以防止用户 SQL 注入我们?我所能想到的只是将输入限制为英文字母和空格(对于 DB 名称,用下划线替换它们),如果我们将 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 注入可能性的问题。如果您负责提供数据库,则需要负责命名。
您可以让用户提供一个名称,就他们而言,这是数据库的名称,但是您创建和使用数据库的代码可以使用您自己生成和控制的名称。这样,如果由于某种原因您需要给它一个不同的名称,或者创建数据库的新副本,或者切换到用户提供的名称遵循不同规则的不同数据库平台(并且他们选择的名称可能无效) ,您不会受到任何阻碍。
推荐阅读
- firebase - 没有创建 Firebaase 应用程序
- angular - FormControl 数值已设置,但在触摸之前不显示
- flutter - Flutter - 未来处理
- c# - 在 C# 的代码隐藏中创建具有值的表脚本
- reactjs - 如何将我的代码 ( this.state ) 转换为 useState()?
- python - Pandas Groupby对特定列的聚合函数,显示结果中的所有列
- google-chrome-extension - 我的 Tampermonkey 脚本(或其他用户脚本)可以调用我的 Chrome 扩展程序吗?
- javascript - JavaScript If Else 条件
- javascript - Discord 机器人只回复发起者
- javascript - Javascript 页面:使用 JSON 对象为另一个网站页面打开一个新选项卡