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

时间:2019-05-10 20:53:05

标签: java prepared-statement sql-injection

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

我们正在将Java 8 / spring boot与Postgres 10.6数据库一起使用。据我所知,我玩过SQL和一条准备好的语句,只能用于更新,删除和更新之类的查询。我尝试摆弄代码以尝试从用户输入中删除一些表,但是幸运的是,它没有用,但是我想向您保证应用程序不会受到攻击。

button.calendar, button.calendar:active {
  width: 2.75rem;
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAcCAYAAAAEN20fAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEUSURBVEiJ7ZQxToVAEIY/YCHGxN6XGOIpnpaEsBSeQC9ArZbm9TZ6ADyBNzAhQGGl8Riv4BLAWAgmkpBYkH1b8FWT2WK/zJ8ZJ4qiI6XUI3ANnGKWBnht2/ZBDRK3hgVGNsCd7/ui+JkEIrKtqurLpEWaphd933+IyI3LEIdpCYCiKD6HcuOa/nwOa0ScJEnk0BJg0UTUWJRl6RxCYEzEmomsIlPU3IPW+grIAbquy+q6fluy/28RIBeRMwDXdXMgXLj/B2uimRXpui4D9sBeRLKl+1N+L+t6RwbWrZliTTTr1oxYtzVWiTQAcRxvTX+eJMnlUDaO1vpZRO5NS0x48sIwfPc87xg4B04MCzQi8hIEwe4bl1DnFMCN2zsAAAAASUVORK5CYII=') !important;
  background-repeat: no-repeat;
  background-size: 23px;
  background-position: center;
}

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"

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

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

要么只允许使用a-zA-Z0-9,要么可以使用escapeLiteral

答案 2 :(得分:0)

不允许您使用PREPARE语法创建数据库:

statement
Any SELECT, INSERT, UPDATE, DELETE, or VALUES statement.

Postgresql 10 docs)(顺便说一句:现在是10.8。或11.3)

因此,您将必须在常规语句中创建数据库。

问题的标题与问题本身无关,因为您已对数据库名称进行了硬编码,从而避免了任何攻击。您最有可能要处理用户提供的数据库名称。如果是这种情况,请that part of your question is a duplicate