使用PostgreSQL COPY JDBC防止SQL注入。

4

我有以下代码可使用PG的COPY将表格下载为文件:

    public void download(String table, Writer responseWriter) throws SQLException, IOException {
        try (Connection conn = dataSource.getConnection()) {
            CopyManager copyManager = new CopyManager(conn.unwrap(BaseConnection.class));
            // SQL Injection can happen here!
            String statement = "COPY " + table + " TO STDOUT WITH NULL ''";
            copyManager.copyOut(statement, responseWriter);
        }
    }

显然,此代码容易受到SQL注入攻击(表参数从Spring REST控制器传递)。当然,我可以手动清理数据,但如果在CopyManager中有一种“PreparedStatement”的方式来执行此操作,那将是更好的选择。如果使用Spring的JdbcTemplate,则获得额外的加分。

1个回答

4
除了常规的SQL注入攻击,即恶意尝试将DELETE语句添加到您的COPY命令中之外,还存在另一个问题。因为您的代码允许运行任何有效的表名,所以仍然存在泄露模式中任何表中包含数据的风险。
因此,在这里安全的做法可能是维护一个白名单,列出您想要允许用户访问的表。与列表不匹配的任何输入表名称都将被拒绝。假设您的表列表驻留在一个List中,我们可以对您的代码进行以下更改:
public void download(String table, Writer responseWriter) throws SQLException, IOException {
    // get list of all allowed tables
    List<String> fileList = getAllowedTables();
    if (!fileList.contains(table)) {
        throw new IllegalAccessException("Someone tried to access a forbidden table.");
    }

    try (Connection conn = dataSource.getConnection()) {
        CopyManager copyManager = new CopyManager(conn.unwrap(BaseConnection.class));
        // SQL Injection can happen here!
        String statement = "COPY " + table + " TO STDOUT WITH NULL ''";
        copyManager.copyOut(statement, responseWriter);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接