Предотвращение внедрения SQL с помощью PostgreSQL COPY JDBC - PullRequest
4 голосов
/ 08 апреля 2019

У меня есть следующий код для загрузки таблицы в виде файла, используя 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 голосов
/ 08 апреля 2019

Помимо общего внедрения 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...