Sobes.tech
Middle+
78

Υπάρχει ένα σύστημα που επιτρέπει στους χρήστες να εργάζονται με αρχεία στον browser. Η τεχνολογική στοίβα είναι στάνταρ: Java, Spring, React, Postgres. Τα αρχεία αποθηκεύονται στο σύστημα αρχείων στο backend, και τα μεταδεδομένα των αρχείων στη βάση δεδομένων. Η ομάδα υλοποίησε μια λειτουργία: μετονομασία αρχείου. Αυτή η μέθοδος είναι ουσιώδης για τη μετονομασία αρχείου στο backend. Πρέπει να πραγματοποιηθεί ανασκόπηση για τον εντοπισμό πιθανών προβλημάτων στον υπάρχοντα κώδικα και να προταθούν λύσεις. @Transactional public void process(String oldName, String newName) { Long id = exec("select id from file where name='" + oldName + "'"); processFile(oldName, newName); // μετονομασία αρχείου στον δίσκο exec("update file set name='" + newName + "' where id = " + id); }

Εταιρείες όπου ρωτήθηκαν
СБЕРСБЕР

Απάντηση από AI

sobes.tech AI

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

  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);
}

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