Помимо общего внедрения 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);
}
}