Как избежать проблем XSS при нажатии ссылки HTML, чтобы получить файл из базы данных и отобразить его на новой вкладке?

В обратном вызове успешного запроса AJAX мне нужно добавить ссылку на модальное окно. Атрибут href ссылки указывает на маршрут API, который вызывает метод контроллера Spring Boot, который записывает PDF-файл, хранящийся на серверной стороне, в объект Response. Пользователь может щелкнуть ссылку, чтобы открыть новую вкладку, в которой отображается PDF-файл.

ЯС:

success: function (data) {    
  var fileId = data.id
  $('#modalBody').append(`<a id = "viewFile" target = "_blank" href = "../api/getFile?fileId=${fileId}">View File</a>`)
}

Контроллер:

    @RequestMapping(value = "api/getFile", method = RequestMethod.GET)
    public void getFile(HttpServletResponse response, @RequestParam(value = "fileId") String fileId) {

        Response fileResponse = fileService.getInputStream(fileId);
        if (fileResponse == null) {
            response.setStatus(500);
            return;
        }
    
        InputStream is = response.body().byteStream();
        response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "inline;filename=sampleFile.pdf");
        response.setContentType("application/pdf");
        
        IOUtils.copy(is, response.getOutputStream);
        response.setStatus(202);
        response.flushBuffer();
        is.close();
        fileResponse.close();
    }

Проблема в том, что инструмент сканирования уязвимостей помечает href как проблему XSS, поскольку я передаю непроверенные данные в качестве параметров запроса во внешний интерфейс. Есть ли другой способ открыть файл, полученный из серверной части, при нажатии на ссылку HTML?

Я попробовал использовать обработчик событий щелчка и установить для href маршрут по умолчанию, но он просто открывает текущую страницу вместо файла на новой вкладке. Есть ли у кого-нибудь предложения о том, как избежать передачи параметров запроса по маршруту href и как использовать onclick вместо href?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Эта уязвимость означает, что вам не следует отображать HTML без его предварительного экранирования.

Если вы использовали EJS или какой-либо другой шаблонизатор, он обычно экранирует HTML. Я использую эту функцию, esc_attr:

function esc_attr(string) {
  if (!string) {
    return "";
  }
  return ("" + string).replace(/[&<>"'/\\]/g, function(s) {
    return {
      "&": "&amp;",
      "<": "&lt;",
      ">": "&gt;",
      '"': '&quot;',
      "'": '&#39;',
      "/": '&#47;',
      "\\": '&#92;'
    }[s];
  });
}

// usage:
div.innerHTML = esc_attr("<scr"+"ipt>alert(13)</scr"+"ipt>");
<div id = "div"></div>

Или в вашем случае,

$('#modalBody').append(`<a id = "viewFile" target = "_blank" href = "../api/getFile?fileId=${esc_attr(fileId)}">View File</a>`)

На самом деле, поскольку вы используете его внутри URL-адреса, вам следует пойти дальше и также закодировать его для URL-адреса, используя encodeURIComponent.

Я считаю, что это лучшее сочетание:

$('#modalBody').append(`<a id = "viewFile" target = "_blank" href = "../api/getFile?fileId=${esc_attr(encodeURIComponent(fileId))}">View File</a>`)

Спасибо за подробный ответ! Можете ли вы объяснить, как работает оператор return и что означает s в функции esc_attrs()?

benevolentBanana135 01.06.2024 16:03

это означает «совпадение» с регулярными выражениями в функции replace (документация), в данном случае один «злой» символ, который будет заменен его HTML-кодировкой.

IT goldman 01.06.2024 16:36

ОБНОВЛЕНИЕ: я создал свой собственный метод проверки, который принимает строку URL-адреса, создает новую строку с теми же символами с нуля и возвращает эту новую чистую строку. Использование этого валидатора вместе с экранированными символами помогло мне решить проблему XSS. Большое спасибо!

benevolentBanana135 02.06.2024 02:46

Другие вопросы по теме