我有以下代码将表格下载为文件,使用 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 注入(inject)(表参数从 Spring REST Controller 传递)。当然,我可以进行一些手动清理,但如果在 CopyManager 中有一种“PreparedStatement”方式来执行此操作,我会更喜欢它。使用 Spring 的 JdbcTemplate 的奖励积分。
最佳答案
除了一揽子 SQL 注入(inject),恶意软件会尝试向您的 COPY
命令添加 DELETE
语句,还有另一个问题。因为您的代码允许运行任何有效的表名,所以它仍然存在泄露架构中任何表中包含的数据的风险。
因此,在这里做的安全的事情可能是维护一个您希望允许用户访问的表的白名单。任何与列表不匹配的输入表名都将被拒绝。假设您的表格列表位于 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);
}
}
关于java - 使用 PostgreSQL COPY JDBC 防止 SQL 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55571706/