Sobes.tech
Middle+
62

Van egy rendszer, amely lehetővé teszi a felhasználók számára, hogy fájlokkal dolgozzanak a böngészőben. A technológiai verem szabványos: Java, Spring, React, Postgres. A fájlok a backend fájlrendszerében tárolódnak, a fájl metaadatai az adatbázisban. A csapat implementálta a fájl átnevezésének funkcióját. Ez a módszer alapvető a fájl átnevezéséhez a backenden. Áttekintést kell végezni a meglévő kódban lévő potenciális problémák azonosítására és megoldási javaslatok kidolgozására. @Transactional public void process(String oldName, String newName) { Long id = exec("select id from file where name='" + oldName + "'"); processFile(oldName, newName); // fájl átnevezése a diszken exec("update file set name='" + newName + "' where id = " + id); }

Cégeket kérdeztek
СБЕРСБЕР

Válasz az MI-től

sobes.tech MI

В представленном методе есть несколько проблем:

  1. SQL-инъекция: Использование конкатенации строк для формирования SQL-запросов ("select id from file where name='" + oldName + "'") уязвимо для SQL-инъекций.

  2. Отсутствие обработки ошибок: Если файл с именем oldName не найден, метод exec может вернуть null или вызвать ошибку, что не обрабатывается.

  3. Потенциальная рассинхронизация: Переименование файла на диске и обновление записи в БД не атомарны, несмотря на аннотацию @Transactional, так как файловая система не участвует в транзакции БД.

  4. Отсутствие проверки успешности переименования файла: Если processFile не сработает, база данных уже будет обновлена, что приведет к рассинхронизации.

  5. Небезопасное обновление имени файла: Нет проверки, что newName не конфликтует с уже существующими именами.

Рекомендации по исправлению:

  • Использовать параметризованные запросы или ORM (например, JPA) для безопасного доступа к базе.
  • Добавить проверку существования файла и обработку ошибок.
  • Сделать переименование файла и обновление БД атомарными с помощью механизма компенсации или отложенного обновления.
  • Проверять, что новое имя не занято.
  • Логировать операции и ошибки.

Пример исправленного кода с использованием JPA и обработки ошибок:

@Transactional
public void process(String oldName, String newName) {
    Optional<FileEntity> fileOpt = fileRepository.findByName(oldName);
    if (!fileOpt.isPresent()) {
        throw new FileNotFoundException("File with name " + oldName + " not found");
    }
    if (fileRepository.existsByName(newName)) {
        throw new IllegalArgumentException("File name " + newName + " already exists");
    }
    FileEntity file = fileOpt.get();
    try {
        processFile(oldName, newName); // переименование на диске
    } catch (IOException e) {
        throw new RuntimeException("Failed to rename file on disk", e);
    }
    file.setName(newName);
    fileRepository.save(file);
}

Такой подход повышает безопасность и надежность операции.