Post или pre лучше и где применяется
Перейти к содержимому

Post или pre лучше и где применяется

Памятка и туториал по HTTP-заголовкам, связанным с безопасностью веб-приложений

В этой статье я хочу поделиться с вами результатами небольшого исследования, посвященного HTTP-заголовкам, которые связаны с безопасностью веб-приложений (далее — просто заголовки).

Сначала мы с вами кратко разберем основные виды уязвимостей веб-приложений, а также основные виды атак, основанные на этих уязвимостях. Далее мы рассмотрим все современные заголовки, каждый — по отдельности. Это в теоретической части статьи.

В практической части мы реализуем простое Express-приложение, развернем его на Heroku и оценим безопасность с помощью WebPageTest и Security Headers . Также, учитывая большую популярность сервисов для генерации статических сайтов, мы настроим и развернем приложение с аналогичным функционалом на Netlify .

Исходный код приложений находится здесь.

Демо Heroku-приложения можно посмотреть здесь, а Netlify-приложения — здесь.

Основными источниками истины при подготовке настоящей статьи для меня послужили следующие ресурсы:

Заголовки безопасности

Все заголовки условно можно разделить на три группы.

Заголовки для сайтов, на которых обрабатываются чувствительные (sensitive) данные пользователей

  • Content Security Policy (CSP) ;
  • Trusted Types .

Заголовки для всех сайтов

  • X-Content-Type-Options ;
  • X-Frame-Options ;
  • Cross-Origin Resource Policy (CORP) ;
  • Cross-Origin Opener Policy (COOP) ;
  • HTTP Strict Transport Security (HSTS) .

Заголовки для сайтов с продвинутыми возможностями

Под продвинутыми возможностями в данном случае понимается возможность использования ресурсов сайта другими источниками (origins) или возможность встраивания или внедрения (embedding) сайта в другие приложения. Первое относится к сервисам вроде CDN (Content Delivery Network — сеть доставки и дистрибуции содержимого), второе к сервисам вроде песочниц — специально выделенные (изолированные) среды для выполнения кода. Под источником понимается протокол, хост, домен и порт.

  • Cross-Origin Resource Sharing (CORS) ;
  • Cross-Origin Embedder Policy (COEP) .

Угрозы безопасности, существующие в вебе

Защита сайта от внедрения кода (injection vulnerabilities)

Угрозы, связанные с возможностью внедрения кода, возникают, когда непроверенные данные, обрабатываемые приложением, могут оказывать влияние на поведение приложения. В частности, это может привести к выполнению скриптов, управляемых атакующим (принадлежащих ему). Наиболее распространенным видом атаки, связанной с внедрением кода, является межсайтовый скриптинг (Cross-Site Scripting, XSS; к слову, сокращение XSS было выбрано во избежание путаницы с CSS ) в различных формах, включая отраженные или непостоянные XSS (reflected XSS), хранимые или постоянные XSS (stored XSS), XSS , основанные на DOM (DOM XSS) и т.д.

XSS может предоставить атакующему полный доступ к пользовательским данным, которые обрабатываются приложением, и к другой информации в пределах источника.

Традиционными способами защиты от XSS являются: автоматическое экранирование шаблонов HTML с помощью специальных инструментов, отказ от использования небезопасных JavaScript API (например, eval() или innerHTML ), хранение данных пользователей в другом источнике и обезвреживание или обеззараживание (sanitizing) данных, поступающих от пользователей, например, через заполнение ими полей формы.

  • используйте CSP для определения того, какие скрипты могут выполняться в вашем приложении;
  • используйте Trusted Types для обезвреживания данных, передаваемых в небезопасные API ;
  • используйте X-Content-Type-Options для предотвращения неправильной интерпретации браузером MIME-типов загружаемых ресурсов.

Изоляция сайта

Открытость веба позволяет сайтам взаимодействовать друг с другом способами, которые могут привести к нарушениям безопасности. Это включает в себя отправку «неожиданных» запросов на аутентификацию или загрузку данных из приложения в документ атакующего, что позволяет последнему читать или даже модифицировать эти данные.

Наиболее распространенными уязвимостями, связанными с общей доступностью приложения, являются кликджекинг (clickjacking), межсайтовая подделка запросов (Cross-Site Request Forgery, XSRF), межсайтовое добавление или включение скриптов (Cross-Site Script Inclusion, XSSI) и различные утечки информации между источниками.

  • используйте X-Frame-Options для предотвращения встраивания вашего документа в другие приложения;
  • используйте CORP для предотвращения возможности использования ресурсов вашего сайта другими источниками;
  • используйте COOP для защиты окон (windows) вашего приложения от взаимодействия с другими приложениями;
  • используйте CORS для управления доступом к ресурсам вашего сайта из других источников.

Безопасность сайтов со сложным функционалом

Spectre делает любые данные, загруженные в одну и ту же группу контекста просмотра (browsing context group), потенциально общедоступными, несмотря на правило ограничения домена. Браузеры ограничивают возможности, которые могут привести к нарушению безопасности с помощью среды выполнения кода под названием «межсайтовая изоляция» (Cross-Origin Isolation). Это, в частности, позволяет безопасно использовать такие мощные возможности, как SharedArrayBuffer .

  • используйте COEP совместно с COOP для обеспечения межсайтовой изоляции вашего приложения.

Шифрование исходящего трафика

Недостаточное шифрование передаваемых данных может привести к тому, что атакующий, в случае перехвата этих данных, получит информацию о взаимодействии пользователей с приложением.

Неэффективное шифрование может быть обусловлено следующим:

  • использование HTTP вместо HTTPS ;
  • смешанный контент (когда одни ресурсы загружаются по HTTPS , а другие — по HTTP );
  • куки без атрибута Secure или соответствующего префикса (также имеет смысл определять настройку HttpOnly );
  • слабая политика CORS .
  • используйте HSTS для обслуживания всего контента вашего приложения через HTTPS .

Перейдем к рассмотрению заголовков.

Content Security Policy (CSP)

XSS — это атака, когда уязвимость, существующая на сайте, позволяет атакующему внедрять и выполнять свои скрипты. CSP предоставляет дополнительный слой для отражения таких атак посредством ограничения скриптов, которые могут выполняться на странице.

Инженеры из Google рекомендуют использовать строгий режим CSP . Это можно сделать одним из двух способов:

  • если HTML-страницы рендерятся на сервере, следует использовать основанный на случайном значении (nonce-based) CSP ;
  • если разметка является статической или доставляется из кеша, например, в случае, когда приложение является одностраничным ( SPA ), следует использовать основанный на хеше (hash-based) CSP .

Пример использования nonce-based CSP:

Использование CSP

Обратите внимание: CSP является дополнительной защитой от XSS-атак, основная защита состоит в обезвреживании данных, вводимых пользователем.

1. Nonce-based CSP

nonce — это случайное число, которое используется только один раз. Если у вас нет возможности генерировать такое число для каждого ответа, тогда лучше использовать hash-based CSP.

Генерируем nonce на сервере для скрипта в ответ на каждый запрос и устанавливаем следующий заголовок:

Затем в разметке устанавливаем каждому тегу script атрибут nonce со значением строки :

Хорошим примером использования nonce-based CSP является сервис Google Фото .

В данном случае можно использовать только встроенные скрипты, поскольку большинство браузеров в настоящее время не поддерживает хеширование внешних скриптов.

CSP Evaluator — отличный инструмент для оценки CSP .

  • https: — это резервный вариант для Firefox , а unsafe-inline — для очень старых браузеров;
  • директива frame-ancestors защищает сайт от кликджекинга, запрещая другим сайтам использовать контент вашего приложения. X-Frame-Options является более простым решением, но frame-ancestors позволяет выполнять тонкую настройку разрешенных источников;
  • CSP можно использовать для обеспечения загрузки всех ресурсов по HTTPS . Это не слишком актуально, поскольку в настоящее время большинство браузеров блокирует смешанный контент;
  • CSP можно использовать в режиме только для чтения (report-only mode);
  • CSP может быть установлен в разметке как мета-тег.

В рассматриваемом заголовке можно использовать следующие директивы:

Директива Описание
base-uri Определяет базовый URI для относительных
default-src Определяет политику загрузки ресурсов всех типов при отсутствии специальной директивы (политику по умолчанию)
script-src Определяет скрипты, которые могут выполняться на странице
object-src Определяет, откуда могут загружаться ресурсы — плагины
style-src Определяет стили, которые могут применяться на странице
img-src Определяет, откуда могут загружаться изображения
media-src Определяет, откуда могут загружаться аудио и видеофайлы
child-src Определяет, откуда могут загружаться фреймы
frame-ancestors Определяет, где (в каких источниках) ресурс может загружаться во фреймы
font-src Определяет, откуда могут загружаться шрифты
connect-src Определяет разрешенные URI
manifest-src Определяет, откуда могут загружаться файлы манифеста
form-action Определяет, какие URI могут использоваться для отправки форм (в атрибуте action )
sandbox Определяет политику песочницы (sandbox policy) HTML , которую агент пользователя применяет к защищенному ресурсу
script-nonce Определяет, что для выполнения скрипта требуется наличие уникального значения
plugin-types Определяет набор плагинов, которые могут вызываться защищенным ресурсом посредством ограничения типов встраиваемых ресурсов
reflected-xss Используется для активации/деактивации эвристических методов браузера для фильтрации или блокировки отраженных XSS-атак
block-all-mixed-content Запрещает загрузку смешанного контента
upgrade-insecure-requests Определяет, что небезопасные ресурсы (загружаемые по HTTP ) должны загружаться по HTTPS
report-to Определяет группу (указанную в заголовке Report-To ), в которую отправляются отчеты о нарушениях политики

Возможные значения директив для нестрогого режима CSP :

  • ‘self’ — ресурсы могут загружаться только из данного источника;
  • ‘none’ — запрет на загрузку ресурсов;
  • * — ресурсы могут загружаться из любого источника;
  • example.com — ресурсы могут загружаться только из example.com .

В данном случае изображения могут быть загружены из любого источника, другие медиафайлы — только с media1.com и media2.com (исключая их поддомены), скрипты — только с example.com .

Trusted Types

XSS , основанный на DOM — это атака, когда вредоносный код передается в приемник, который поддерживает динамическое выполнение кода, такой как eval() или innerHTML .

Trusted Types предоставляет инструменты для создания, модификации и поддержки приложений, полностью защищенных от DOM XSS . Этот режим может быть включен через CSP . Он делает JavaScript-код безопасным по умолчанию посредством ограничения значений, принимаемых небезопасными API , специальным объектом — Trusted Type .

Для создания таких объектов можно определить политики, которые проверяют соблюдение правил безопасности (таких как экранирование и обезвреживание) перед записью данных в DOM . Затем эти политики помещаются в код, который может представлять интерес для DOM XSS .

Включаем Trusted Types для опасных приемников DOM :

В настоящее время единственным доступным значением директивы require-trusted-types-for является script .

Разумеется, Trusted Types можно комбинировать с другими директивами CSP :

C помощью директивы trusted-types можно ограничить пространство имен для политик Trusted Types , например, trusted-types myPolicy .

Директива require-trusted-types-for ‘script’ делает использование доверенного типа обязательным. Любая попытка использовать строку в небезопасном API завершится ошибкой.

Подробнее о Trusted Types можно почитать здесь.

X-Content-Type-Options

Когда вредоносный HTML-документ обслуживается вашим доменом (например, когда изображение, загружаемое в сервис хранения фотографий, содержит валидную разметку), некоторые браузеры могут посчитать его активным документом и разрешить ему выполнять скрипты в контексте приложения.

X-Content-Type-Options: nosniff заставляет браузер проверять корректность MIME-типа в заголовке полученного ответа Content-Type . Рекомендуется устанавливать такой заголовок для всех загружаемых ресурсов.

X-Frame-Options

Если вредоносный сайт будет иметь возможность встраивать ваше приложение как iframe , это может предоставить атакующему возможность вызывать непреднамеренные действия пользователей через кликджекинг. В некоторых случаях это также позволяет атакующему изучать содержимое документа.

X-Frame-Options является индикатором того, должен ли ваш сайт рендериться в <frame>, <iframe> , <embed> или <object> .

Для того, чтобы разрешить встраивание только определенных страниц сайта, используется директива frame-ancestors заголовка CSP .

Полностью запрещаем внедрение:

Разрешаем создание фреймов только на собственном сайте:

Обратите внимание: по умолчанию все документы являются встраиваемыми.

Cross-Origin-Resource-Policy (CORP)

Атакующий может внедрить ресурсы вашего сайта в свое приложение с целью получения информации о вашем сайте.

CORP определяет, какие сайты могут внедрять ресурсы вашего приложения. Данный заголовок принимает 1 из 3 возможных значений: same-origin , same-site и cross-origin .

Для сервисов вроде CDN рекомендуется использовать значение cross-origin , если для них не определен соответствующий заголовок CORS .

same-origin разрешает внедрение ресурсов страницами, принадлежащими к одному источнику. Данное значение применяется в отношении чувствительной информации о пользователях или ответов от API , которые рассчитаны на использование в пределах данного источника.

Обратите внимание: ресурсы все равно будут доступны для загрузки, поскольку CORP ограничивает только внедрение этих ресурсов в другие источники.

same-site предназначен для ресурсов, которые используются не только доменом (как в случае с same-origin ), но и его поддоменами.

Cross-Origin-Opener-Policy (COOP)

Если сайт атакующего может открывать другой сайт в поп-апе (всплывающем окне), то у атакующего появляется возможность для поиска межсайтовых источников утечки информации. В некоторых случаях это также позволяет реализовать атаку с использованием побочных каналов, описанную в Spectre .

Заголовок Cross-Origin-Opener-Policy позволяет запретить открытие сайта с помощью метода window.open() или ссылки target=»_blank» без rel=»noopener» . Как результат, у того, кто попытается открыть сайт такими способами, не будет ссылки на сайт, и он не сможет с ним взаимодействовать.

Значение same-origin рассматриваемого заголовка позволяет полностью запретить открытие сайта в других источниках.

Значение same-origin-allow-popups также защищает документ от открытия в поп-апах других источников, но позволяет приложению взаимодействовать с собственными попапами.

unsafe-none является значением по умолчанию, оно разрешает открытие сайта в виде поп-апа в других источниках.

Мы можем получать отчеты от COOP :

COOP также поддерживает режим report-only , позволяющий получать отчеты о нарушениях без их блокировки.

Cross-Origin Resource Sharing (CORS)

CORS — это не заголовок, а механизм, используемый браузером для предоставления доступа к ресурсам приложения.

По умолчанию браузеры используют политику одного источника или общего происхождения, которая запрещает доступ к таким ресурсам из других источников. Например, при загрузке изображения из другого источника, даже несмотря на его отображение на странице, JavaScript-код не будет иметь к нему доступа. Провайдер ресурса может предоставить такой доступ через настройку CORS с помощью двух заголовков:

Использование CORS

Начнем с того, что существует два типа HTTP-запросов. В зависимости от деталей запроса он может быть классифицирован как простой или сложный (запрос, требующий отправки предварительного запроса).

Критериями простого запроса является следующее:

  • методом запроса является GET , HEAD или POST ;
  • кастомными заголовками могут быть только Accept , Accept-Language , Content-Language и Content-Type ;
  • значением заголовка Content-Type может быть только application/x-www-form-urlencoded , multipart/form-data или text/plain .

Все остальные запросы считаются сложными.

В данном случае браузер отправляет запрос к другому источнику с заголовком Origin , значением которого является источник запроса:

  • Access-Control-Allow-Origin: https://example.com означает, что https://example.com имеет доступ к содержимому ответа. Если значением данного заголовка является * , ресурсы будут доступны любому сайту. В этом случае полномочия (credentials) не требуются;
  • Access-Control-Allow-Credentials: true означает, что запрос на получение ресурсов должен содержать полномочия (куки). При отсутствии полномочий в запросе, даже при наличии источника в заголовке Access-Control-Allow-Origin , запрос будет отклонен.

Перед сложным запросом выполняется предварительный. Он выполняется методом OPTIONS для определения того, может ли быть отправлен основной запрос:

  • Access-Control-Request-Method: POST — последующий запрос будет отправлен методом POST ;
  • Access-Control-Request-Headers: X-PINGOTHER, Content-Type — последующий запрос будет отправлен с заголовками X-PINGOTHER и Content-Type .
  • Access-Control-Allow-Methods: POST, GET, OPTIONS — последующий запрос может выполняться указанными методами;
  • Access-Control-Allow-Headers: X-PINGOTHER, Content-Type — последующий запрос может содержать указанные заголовки;
  • Access-Control-Max-Age: 86400 — результат сложного запроса будет записан в кеш и будет там храниться на протяжении 86400 секунд.

Cross-Origin-Embedder-Policy (COEP)

Для предотвращения кражи ресурсов из других источников с помощью атак, описанных в Spectre , такие возможности, как SharedArrayBuffer , performance.measureUserAgentSpecificMemory() или JS Self Profiling API , по умолчанию отключены.

Cross-Origin-Embedder-Policy: require-corp запрещает документам и воркерам (workers) загружать изображения, скрипты, стили, фреймы и другие ресурсы до тех пор, пока доступ к ним не разрешен с помощью заголовков CORS или CORP . COEP может использоваться совместно с COOP для настройки межсайтовой изоляции документа.

На данный момент require-corp является единственным доступным значением рассматриваемого заголовка, кроме unsafe-none , которое является значением по умолчанию.

Полная межсайтовая изоляция приложения

Изоляция с отчетами о блокировках

HTTP Strict Transport Security (HSTS)

Данные, передаваемые по HTTP , не шифруются, что делает их доступными для перехватчиков на уровне сети.

Заголовок Strict-Transport-Security запрещает использование HTTP . При наличии данного заголовка браузер будет использовать HTTPS без перенаправления на HTTP (при отсутствии ресурса по HTTPS ) в течение указанного времени ( max-age ).

  • max-age — время в секундах, в течение которого браузер должен «помнить», что сайт доступен только по HTTPS ;
  • includeSubDomains — распространяет политику на поддомены.

Другие заголовки

Referrer-Policy

Заголовок Referrer-Policy определяет содержание информации о реферере, указываемой в заголовке Referer . Заголовок Referer содержит адрес запроса, например, адрес предыдущей страницы, или адрес загруженного изображения, или другого ресурса. Он используется для аналитики, логирования, оптимизации кеша и т.д. Однако он также может использоваться для слежения или кражи информации, выполнения побочных эффектов, приводящих к утечке чувствительных пользовательских данных и т.д.

Значение Описание
no-referrer Заголовок Referer не включается в запрос
no-referrer-when-downgrade Значение по умолчанию. Реферер указывается при выполнении запроса между HTTPS и HTTPS , но не указывается при выполнении запроса между HTTPS и HTTP
origin Указывается только источник запроса (например, реферером документа https://example.com/page.html будет https://example.com )
origin-when-cross-origin При выполнении запроса в пределах одного источника указывается полный URL , иначе указывается только источник (как в предыдущем примере)
same-origin При выполнении запроса в пределах одного источника указывается источник, в противном случае, реферер не указывается
strict-origin Похоже на no-referrer-when-downgrade , но указывается только источник
strict-origin-when-cross-origin Сочетание strict-origin и origin-when-cross-origin
unsafe-url Всегда указывается полный URL

Обратите внимание: данный заголовок не поддерживается мобильным Safari .

Clear-Site-Data

Заголовок Clear-Site-Data запускает очистку хранящихся в браузере данных (куки, хранилище, кеш), связанных с источником. Это предоставляет разработчикам контроль над данными, локально хранящимися в браузере пользователя. Данный заголовок может использоваться, например, в процессе выхода пользователя из приложения (logout) для очистки данных, хранящихся на стороне клиента.

Значение Описание
«cache» Сообщает браузеру, что сервер хочет очистить локально кешированные данные для источника ответа на запрос
«cookies» Сообщает браузеру, что сервер хочет удалить все куки для источника. Данные для аутентификации также будут очищены. Это влияет как на сам домен, так и на его поддомены
«storage» Сообщает браузеру, что сервер хочет очистить все хранилища браузера ( localStorage , sessionStorage , IndexedDB , регистрация сервис-воркеров — для каждого зарегистрированного СВ вызывается метод unregister() , AppCache , WebSQL , данные FileSystem API , данные плагинов)
«executionContexts» Сообщает браузеру, что сервер хочет перезагрузить все контексты браузера (в настоящее время почти не поддерживается)
«*» Сообщает браузеру, что сервер хочет удалить все данные

Обратите внимание: данный заголовок не поддерживается Safari .

Permissions-Policy

Данный заголовок является заменой заголовка Feature-Policy и предназначен для управления доступом к некоторым продвинутым возможностям.

В данном случае мы полностью запрещаем доступ к камере (видеовходу) устройства, разрешаем доступ к методу requestFullScreen() (для включения полноэкранного режима воспроизведения видео) для всех, а к информации о местонахождении устройства — только для источников example.com и another.example.com .

Директива Описание
accelerometer Управляет тем, может ли текущий документ собирать информацию об акселерации (проекции кажущегося ускорения) устройства с помощью интерфейса Accelerometer
ambient-light-sensor Управляет тем, может ли текущий документ собирать информацию о количестве света в окружающей устройство среде с помощью интерфейса AmbientLightSensor
autoplay Управляет тем, может ли текущий документ автоматически воспроизводить медиа, запрошенное через интерфейс HTMLMediaElement
battery Определяет возможность использования Battery Status API
camera Определяет возможность использования видеовхода устройства
display-capture Определяет возможность захвата экрана с помощью метода getDisplayMedia()
document-domain Определяет возможность установки document.domain
encrypted-media Определяет возможность использования Encrypted Media Extensions API (EME)
execution-while-not-rendered Определяет возможность выполнения задач во фреймах без их рендеринга (например, когда они скрыты или их свойство diplay имеет значение none )
execution-while-out-of-viewport Определяет возможность выполнения задач во фреймах, находящихся за пределами области просмотра
fullscreen Определяет возможность использования метода requestFullScreen()
geolocation Определяет возможность использования Geolocation API
gyroscope Управляет тем, может ли текущий документ собирать информацию об ориентации устройства с помощью Gyroscope API
layout-animations Определяет возможность показа анимации
legacy-image-formats Определяет возможность отображения изображений устаревших форматов
magnetometer Управляет тем, может ли текущий документ собирать информацию об ориентации устройства с помощью Magnetometer API
microphone Определяет возможность использования аудиовхода устройства
midi Определяет возможность использования Web MIDI API
navigation-override Определяет возможность управления пространственной навигацией (spatial navigation) механизмами, разработанными автором приложения
oversized-images Определяет возможность загрузки и отображения больших изображений
payment Определяет возможность использования Payment Request API
picture-in-picture Определяет возможность воспроизведения видео в режиме «картинка в картинке»
publickey-credentials-get Определяет возможность использования Web Authentication API для извлечения публичных ключей, например, через navigator.credentials.get()
sync-xhr Определяет возможность использования WebUSB API
vr Определяет возможность использования WebVR API
wake-lock Определяет возможность использования Wake Lock API для запрета переключения устройства в режим сохранения энергии
screen-wake-lock Определяет возможность использования Screen Wake Lock API для запрета блокировки экрана устройства
web-share Определяет возможность использования Web Share API для передачи текста, ссылок, изображений и другого контента
xr-spatial-tracking Определяет возможность использования WebXR Device API для взаимодействия с сессией WebXR
  • =() — полный запрет;
  • =* — полный доступ;
  • (self «https://example.com») — предоставление разрешения только указанному источнику.

Спецификация рассматриваемого заголовка находится в статусе рабочего черновика, поэтому его поддержка оставляет желать лучшего:

Перейдем к практической части.

Разработка Express-приложения

Создаем директорию для проекта, переходим в нее и инициализируем проект:

Формируем структуру проекта:

Иконку можно найти здесь.

Набросаем какой-нибудь незамысловатый код.

В public/index.html мы подключаем иконку, стили, скрипт, Google-шрифты, Bootstrap и Boostrap Icons через CDN , создаем элементы для заголовка, даты, времени и кнопок:

Добавляем стили в public/style.css

В public/script.js мы делаем следующее:

  • определяем политику доверенных типов;
  • создаем утилиты для получения ссылки на DOM-элемент, форматирования даты и времени и регистрации обработчика (по умолчанию одноразового и запускающего колбэк при возникновении события click );
  • получаем ссылки на DOM-элементы;
  • определяем настройки для форматирования даты и времени;
  • добавляем дату и время в качестве текстового содержимого соответствующих элементов;
  • определяем колбэки для обработчиков: для остановки таймера, добавления HTML-шаблона с потенциально вредоносным кодом и получения HTTP-заголовков;
  • регистрируем обработчики.
    — Node.js-фреймворк, упрощающий разработку сервера; — утилита для запуска сервера для разработки и его автоматического перезапуска при обновлении соответствующего файла; — утилита для автоматического открытия вкладки браузера по указанному адресу.

Определяем в package.json команды для запуска серверов:

Приступаем к реализации сервера.

Справедливости ради следует отметить, что в экосистеме Node.js имеется специальная утилита для установки HTTP-заголовков, связанных с безопасностью веб-приложений — Helmet . Шпаргалку по работе с этой утилитой вы найдете здесь.

Также существует специальная утилита для работы с CORS — Cors . Шпаргалку по работе с этой утилитой вы найдете здесь.

Большинство заголовков можно определить сразу:

Также добавим заголовок Expect-CT :

Блокируем доступ к камере, микрофону, информации о местонахождении и Payment Request API :

Директивы для CSP :

Обратите внимание: все директивы должны быть указаны в одну строку без переносов. Мы не определяем директивы для стилей и шрифтов, поскольку они загружаются из других источников.

Также обратите внимание, что мы не используем nonce для скриптов, поскольку мы не рендерим разметку на стороне сервера, но я приведу соответствующий код.

Выполняем команду yarn dev или npm run dev (разумеется, на вашей машине должен быть установлен Node.js ). Данная команда запускает сервер для разработки и открывает вкладку браузера по адресу http://localhost:3000 .


Отлично! Теперь развернем приложение на Heroku и проверим его безопасность с помощью Security Headers и WebPageTest .

Деплой Express-приложения на Heroku

Создаем аккаунт на Heroku .

Находясь в корневой директории проекта, инициализируем Git-репозиторий (разумеется, на вашей машине должен быть установлен git ), добавляем и фиксируем изменения (не забудьте добавить node_modules в .gitignore ):

Создаем удаленный репозиторий на Heroku :

Инструкцию по развертыванию приложения на Heroku можно найти здесь.

После выполнения этой команды, в терминале появится URL вашего приложения, развернутого на Heroku , например, https://tranquil-meadow-01695.herokuapp.com/ .

Перейдите по указанному адресу и проверьте работоспособность приложения.

Заходим на Security Headers , вставляем URL приложения в поле enter address here и нажимаем на кнопку Scan :

Получаем рейтинг приложения:

В Supported By читаем Вау, отличная оценка. .

Заходим на WebPageTest , вставляем URL приложения в поле Enter a website URL. и нажимаем на кнопку Start Test -> :

Получаем результаты оценки приложения (нас интересует первая оценка — Security score ):

Похоже, мы все сделали правильно. Круто!

Деплой приложения на Netlify

Переносим файлы favicon.png , index.html , script.js и style.css из папки public в отдельную директорию, например, netlify .

Для настройки сервера Netlify используется файл netlify.toml . Создаем данный файл в директории проекта. Нас интересует только раздел [[headers]] :

  • for = «/*» означает для всех запросов;
  • [header.values] — заголовки и их значения (просто переносим их из Express-сервера с учетом особенностей синтаксиса).

Можно запустить сервер для разработки (это необязательно):

Данная команда запускает приложение и открывает вкладку браузера по адресу http://localhost:8888 .

Разворачиваем приложение в тестовом режиме:

Выбираем Create & configure a new site , свою команду (например, Igor Agapov’s team ), оставляем Site name пустым и выбираем директорию со сборкой приложения (у нас такой директории нет, поэтому оставляем значение по умолчанию — . ):

Получаем URL черновика веб-сайта ( Website Draft URL ), например, https://60f3e6013d0afb2ce71a5623—infallible-pasteur-d015e7.netlify.app . Можно перейти по указанному адресу и проверить работоспособность приложения.

Разворачиваем приложение в продакшен-режиме:

  • -p или —prod означает производственный режим.

Получаем URL приложения ( Website URL ), например, https://infallible-pasteur-d015e7.netlify.app/ . Опять же, можно перейти по указанному адресу и проверить работоспособность приложения.

Инструкцию по развертыванию приложения на Netlify можно найти здесь.

Возвращаемся на Security Headers и WebPageTest и проверяем, насколько безопасным является наше Netlify-приложение:


Кажется, у нас все получилось!

Заключение

Подведем итоги. Мы с вами вкратце изучили все HTTP-заголовки, связанные с безопасностью веб-приложений, разработали серверное и бессерверное приложения с аналогичным функционалом и получили лучшие оценки безопасности для данных приложений на Security Headers и WebPageTest . По-моему, очень неплохо для одной статьи.

Надеюсь, что вы не зря потратили время. Благодарю за внимание и хорошего дня!

Send и Return

Что такое send и return на канале микшерного пульта?

Надеюсь, ты помнишь из школьного курса физики, что в электрическую цепь приборы могут подключаться как последовательно, так и параллельно. Так вот, с аудиосигналами может быть также, и роль параллельно подключенного прибора в маршрутизации (роутинге) аудиосигналов как раз выполняют эффекты, расположенные в return-каналах. Думаю, это понятно, теперь назовём вещи своими именами:

Return (или возврат) — специальный канал микшера, предназначенный не для инструментов, а для эффектов, которые должны применяться к нескольким инструментам микса параллельно. При этом результат работы return-канала не заменяет обрабатываемый звук, а лишь подмешивается к нему. По умолчанию обработанная эффектами возврата копия сигнала возвращается в мастер-канал микшерного пульта.

Как говорится, лучше один раз услышать. Оба семпла ниже обработаны ревербератором с одинаковыми настройками, только в первом случае он подключен последовательно (в insert), а во втором — параллельно (в return):

А, в свою очередь, send (или посыл) — это параметр, который отвечает за количество посылаемого на конкретный return сигнала. Таким образом, классическая схема работы каналов возврата выглядит следующим образом:

пример цепи send-return

Режимы работы return-канала: pre-fader и post-fader

Микшерные пульты современных DAW имеют возможность выбора нужного режима работы каналов возврата. Здесь тоже предельно просто:

  • Режим pre-fader означает, что посыл на return-канал производится ДО регулятора уровня громкости канала с инструментом;
  • В режиме post-fader, наоборот, посыл производится ПОСЛЕ регулятора громкости.

То есть, если ты в pre-fader-ном режиме уберёшь громкость канала, то на return-канал звук всё равно будет поступать.

Преимущества использования каналов возврата

Уверен, ты уже и сам видишь плюсы от активного использования в работе return-ов, но тем не менее:

  1. При переносе наиболее используемых аудиоэффектов на каналы возврата значительно освобождаются ресурсы процессора. Ну это логично: вместо использования, например, 5 требовательных к ресурсам _ревербераторов_ — используется только один;
  2. Использование каналов возврата делает звук более насыщенным;
  3. Обработка нескольких каналов одним набором эффектов делает микс более цельным.

Ну что, убедил в том, что возраты не только можно использовать в работе, но и нужно? Добавлю лишь, что хрестоматийный пример использования return-ов — 3-4 канала, в которых расположено по ревербератору с разными настройками для реализации так называемых планов.

Но это лишь малая часть потенциала возвратов. Не ограничивай себя ни количеством каналов, ни набором эффектов в них, ни количеством эффектов в каждом return-канале. Это такая же творческая вещь как и всё остальное в саундпродакшне. Экспериментируй!

Ну а я сейчас на примере Ableton Live покажу как работать с return-каналами.

Использование return-каналов в Ableton Live

По умолчанию в Live 2 return-канала1, в режиме сессии они расположены справа рядом с мастер-каналом. Итак, как их заставить работать? Да всё максимально просто, смотри гифку:

Кстати, сигнал с возврата можно направить не на мастер-канал, как указано по умолчанию, а на аудио-канал с последующей его обработкой. Но _о маршрутизации в Live_ я расскажу чуть позже, а пока запускай свою DAW и начинай экспериментировать. Удачи!

1 добавить return-каналы в Ableton Live можно комбинацией горячих клавиш CTRL+ALT+T или клик правой кнопкой мыши по свободному от каналов месту в полосе где располагаются названия каналов и выбрать пункт «Insert Return Track».

Комментарии:

Звук не подмешивается, а прибавляется, ты устанавливаешь количество сигнала не отправляемого на канал возврата, а копируемого на канал возврата, то есть в итоге сигнал от одного инструмента становится громче, это нарушает баланс микса. И я уже несколько дней пытаюсь найти решение этого недоразумения. Мне нужно, чтобы он именно ПОДМЕШИВАЛСЯ

разъясните про Pre/Post Fader (1 онлайн

Поискал на форуме. Нашел информацию, но она очень размыта и не понятна )) :tongue:
Кое что я понял из статей на форуме.

Вот что конкретно:
рассмотрю случай с посылом реверба на трек Snare
В случае с Pre Fader, обработанный сигнал будет копироваться непосредственно из самого звукового файла,
минуя всякие эффекты в Insert‘e?
А в случае с Post Fader сигнал (отражение) будет копироваться и вставляться в хвост основного звука после всех эффектов в Insert‘e?

разъясните, желательно в картинках

Alex_HS
Super Moderator
Pavlik
New Member
New Member
supersonic
Well-Known Member
New Member
Vadim_K
Well-Known Member
New Member

я может чего то понял неправильно, но если мне нужно например верб повесить на канал (сенд) а у меня там дилей в инсерте уже есть, то сенд только с дилеем будет чтоли? при том что у меня на 7-8 каналах уже динамика висит, да и автоматизация например на громкости прописана.

з.ы. вопрос чисто познавательный т.к. всёравно в другом хосте работаю и там маршрутизация сендов по другому происходит.

Vadim_K
Well-Known Member
New Member

тоже лишний гемор

з.ы. короче что то смотрю через жопу тут как то всё, сейчас сам нуенду поставлю и посмотрю что и как,

Vadim_K
Well-Known Member

После первых 6-ти и EQ.

Насчёт гемора не согласен вобщем, имхо всё нормально и просто.

З.Ы.
А какая схема в Сонаре ?:gigi:

New Member

как и вположено, инсерт является инсертом в шину, а сенд является сендом с шины. т.е. инсерты вставляются в разрыв шины, а на все сенды идёт чистый сигнал с шины, до инсертов. :tongue:

з.ы. я к чему этот вопрос поднял, у меня такое ощущение что рисунок не совсем соответствует реальному положению дел, я на нуенде иногда работаю но таких хитрых путей там не замечал.

Vadim_K
Well-Known Member

Не, рисунок соответствует. Всё так и есть. Может это и может показаться "через жопу" конечно по началу, если к другом хосту привык, но на самом деле всё удобно и нормально: группу создать для чего либо не проблема, автоматизировать уровень сенда на ревер (если он Pre-Fader) в случае если громкость на канале автоматизирована (как в твоём примере выше) тоже не проблема: найти огибающую автоматизации громкости и скопировать этот участок на огибающую уровня посыла на сенд, "опустив или подняв" эту огибающую до нужного уровня, сохранив её "форму", и всё будет.

Единственная проблема, что не нравится, так это с группами — то что с одной группы на другую можно сендить тока слева направо в микшере (из которой левей, в те которые правее неё), ну об этом уже много писали здесь. То есть вот будет проблематично, если уже все группы созданы, и если понадобилась группа для дилэя новая например, и нужно чтобы сигнал дилэя посылался на группу с ревером, которая до этого была создана — вот это вот реализовать будет геморно. Не понятно почему до сих пор не сделали, чтобы из любой группы, можно было бы сендить в любую другую, независимо от того правее она или левее, то есть позже создана или раньше (хотя Rustami писал, что это как-то связано с компенсацией задержек, если я не ошибаюсь, что иначе было бы сложнее её реализация). Точнее, если работать с группами, и предполагается, что возможна такая ситуация, то порекомендовать можно такой же метод, как и в случаях, когда спрашивают почему инсёрты местами поменять нельзя 🙂 В этом случае рекомендуется оставлять свободным первый слот например, и навешивать их со второго, и также с группами похоже можно — сделать одну-две пустые группы слева вначале, и пусть они будут на всякий случай. А на остальное по поводу роутинга микшера кубейса/нуэнды претензий нет.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *