Правило №1: никогда не используйте ненадежные шаблоны
Самое фундаментальное правило безопасности при использовании Vue — никогда не использовать ненадежный контент в качестве шаблона компонента . Это эквивалентно разрешению произвольного выполнения JavaScript в вашем приложении — и, что еще хуже, может привести к нарушениям работы сервера, если код выполняется во время рендеринга на стороне сервера. Пример такого использования:
Шаблоны Vue компилируются в JavaScript, и выражения внутри шаблонов будут выполняться как часть процесса рендеринга. Хотя выражения оцениваются в соответствии с конкретным контекстом рендеринга, из-за сложности потенциальных глобальных сред выполнения непрактично для такой среды, как Vue, полностью защитить вас от потенциального выполнения вредоносного кода без нереальных затрат на производительность. Самый простой способ вообще избежать этой категории проблем — убедиться, что содержимое ваших шаблонов Vue всегда надежно и полностью контролируется вами.
Что делает Vue, чтобы защитить вас
HTML-контент
Независимо от того, используете ли вы шаблоны или функции рендеринга, содержимое автоматически экранируется. В этом шаблоне это означает:
если userProvidedString содержится:
тогда он будет экранирован следующим HTML:
тем самым предотвращая внедрение сценария. Это экранирование осуществляется с использованием встроенных API-интерфейсов браузера, таких как textContent, поэтому уязвимость может существовать только в том случае, если уязвим сам браузер.
# Привязки атрибутов
Аналогично, привязки динамических атрибутов также автоматически экранируются. В этом шаблоне это означает:
если userProvidedString содержится:
тогда он будет экранирован следующим HTML
тем самым предотвращая закрытие атрибута title для внедрения нового произвольного HTML. Это экранирование осуществляется с использованием встроенных API-интерфейсов браузера, таких как setAttribute, поэтому уязвимость может существовать только в том случае, если уязвим сам браузер.
# Потенциальные опасности
В любом веб-приложении разрешение исполнения неочищенного, предоставленного пользователем контента в виде HTML, CSS или JavaScript потенциально опасно, поэтому его следует избегать, где это возможно. Однако бывают случаи, когда некоторый риск может быть приемлемым.
Например, такие сервисы, как CodePen и JSFiddle, позволяют выполнять предоставленный пользователем контент, но в контексте, где это ожидается, и в некоторой степени изолированы внутри iframe. В тех случаях, когда важная функция по своей сути требует определенного уровня уязвимости, ваша команда должна сопоставить важность этой функции с наихудшими сценариями, которые допускает уязвимость.
# HTML-инъекция
Как вы узнали ранее, Vue автоматически экранирует содержимое HTML, предотвращая случайное внедрение исполняемого HTML-кода в ваше приложение. Однако в тех случаях, когда вы уверены, что HTML безопасен , вы можете явно визуализировать HTML-содержимое
Использование шаблона
Использование функции рендеринга:
Использование функции рендеринга с JSX:
ПРЕДУПРЕЖДЕНИЕ
Предоставленный пользователем HTML никогда не может считаться на 100% безопасным, если только он не находится в изолированном iframe или в той части приложения, где только пользователь, написавший этот HTML, может получить к нему доступ. Кроме того, разрешение пользователям писать свои собственные шаблоны Vue сопряжено с аналогичными опасностями.
# URL-инъекция
В таком URL-адресе
Существует потенциальная проблема безопасности, если URL-адрес не был «обработан», чтобы предотвратить выполнение JavaScript с использованием javascript. Существуют библиотеки, такие как sanitize-url, которые помогут в этом, но учтите: если вы когда-либо выполняли очистку URL-адресов во внешнем интерфейсе, у вас уже есть проблема с безопасностью. URL-адреса, предоставленные пользователем, всегда должны обрабатываться вашим сервером еще до того, как они будут сохранены в базе данных. Тогда проблема будет решена для каждого клиента, подключающегося к вашему API, включая собственные мобильные приложения. Также обратите внимание, что даже при использовании очищенных URL-адресов Vue не может гарантировать, что они ведут в безопасные места назначения.
# Внедрение стиля
Глядя на этот пример
Предположим, что он sanitizedUrl был очищен, так что это определенно реальный URL-адрес, а не JavaScript. С помощью userProvidedStyles. злоумышленники по-прежнему могут использовать CSS для «щелкания», например, оформляя ссылку в прозрачное поле над кнопкой «Войти». Тогда, если https://user-controlled-website.com/ он создан так, чтобы напоминать страницу входа в ваше приложение, они могли бы просто захватить реальную информацию для входа пользователя.
Вы можете себе представить, как разрешение предоставления пользовательского контента для styleэлемента создаст еще большую уязвимость, предоставив этому пользователю полный контроль над стилем всей страницы. Вот почему Vue предотвращает рендеринг тегов стиля внутри шаблонов, таких как
Чтобы обеспечить полную безопасность ваших пользователей от кликджекинга, мы рекомендуем разрешать полный контроль над CSS только внутри изолированного iframe. В качестве альтернативы, предоставляя пользовательский контроль через привязку стиля, мы рекомендуем использовать его объектный синтаксис и разрешать пользователям предоставлять значения только для определенных свойств, которыми они могут безопасно управлять, например
# JavaScript-инъекция
Мы настоятельно не рекомендуем выполнять рендеринг scriptэлемента с помощью Vue, поскольку шаблоны и функции рендеринга никогда не должны иметь побочных эффектов. Однако это не единственный способ включения строк, которые во время выполнения будут оцениваться как JavaScript.
Каждый элемент HTML имеет атрибуты со значениями, принимающими строки JavaScript, такие как onclick, onfocus и onmouseenter<>/b>. Привязка предоставленного пользователем JavaScript к любому из этих атрибутов событий представляет собой потенциальную угрозу безопасности, поэтому ее следует избегать.
ПРЕДУПРЕЖДЕНИЕ
Пользовательский JavaScript никогда не может считаться на 100% безопасным, если только он не находится в изолированном iframe или в той части приложения, где только пользователь, написавший этот JavaScript, может получить к нему доступ.
Иногда мы получаем отчеты об уязвимостях о том, как можно выполнять межсайтовый скриптинг (XSS) в шаблонах Vue. В целом, мы не считаем такие случаи реальными уязвимостями, поскольку не существует практического способа защитить разработчиков от двух сценариев, которые допускают XSS
- 1. Разработчик явно просит Vue отображать предоставленный пользователем неочищенный контент в виде шаблонов Vue. Это по своей сути небезопасно, и Vue не может узнать происхождение.
- 2. Разработчик монтирует Vue ко всей HTML-странице, которая содержит контент, отображаемый сервером и предоставленный пользователем. По сути, это та же проблема, что и №1, но иногда разработчики могут делать это, даже не осознавая этого. Это может привести к возможным уязвимостям, когда злоумышленник предоставляет HTML, который безопасен как простой HTML, но небезопасен как шаблон Vue. Лучше всего никогда не монтировать Vue на узлах, которые могут содержать контент, отображаемый сервером или предоставленный пользователем
Лучшие практики
Общее правило заключается в том, что если вы разрешаете выполнение неочищенного, предоставленного пользователем контента (в виде HTML, JavaScript или даже CSS), вы можете открыть себя для атак. Этот совет на самом деле справедлив независимо от того, используете ли вы Vue, другой фреймворк или даже не используете его.
Помимо рекомендаций, данных выше в отношении потенциальных опасностей , мы также рекомендуем ознакомиться с этими ресурсами:
Затем используйте полученные знания для проверки исходного кода ваших зависимостей на наличие потенциально опасных шаблонов, если какие-либо из них включают сторонние компоненты или иным образом влияют на то, что отображается в DOM.
# Внутренняя координация
Уязвимости безопасности HTTP, такие как подделка межсайтовых запросов (CSRF/XSRF) и включение межсайтовых сценариев (XSSI), в первую очередь устраняются на внутренней стороне, поэтому они не являются проблемой Vue. Тем не менее, по-прежнему полезно пообщаться со своей серверной командой, чтобы узнать, как лучше всего взаимодействовать с их API, например, отправляя токены CSRF при отправке форм.
# Серверный рендеринг (SSR)
При использовании SSR возникают некоторые дополнительные проблемы безопасности, поэтому обязательно следуйте рекомендациям, изложенным в нашей документации по SSR, чтобы избежать уязвимостей.