Безопасность атрибутов

FAST Element — это современная библиотека для создания Web Components на JavaScript, которая обеспечивает высокую производительность и гибкость. Одной из критически важных особенностей при работе с компонентами является безопасность атрибутов, так как неконтролируемое взаимодействие с DOM может привести к уязвимостям, таким как XSS (Cross-Site Scripting).


Связь атрибутов и свойств

В FAST Element атрибуты HTML и свойства компонента тесно связаны. Любой публичный свойство компонента, объявленное с помощью @attr, автоматически синхронизируется с соответствующим HTML-атрибутом. Это означает:

  • Изменение свойства в коде обновляет атрибут в DOM.
  • Изменение атрибута через HTML обновляет свойство компонента.

Пример:

import { FASTElement, attr } from "@microsoft/fast-element";

export class UserCard extends FASTElement {
  @attr name;
  @attr age;
}

HTML:

<user-card name="Alice" age="30"></user-card>

Если пользователь попытается вставить в атрибут name вредоносный код, например <script>alert('xss')</script>, это не должно автоматически выполняться в браузере. FAST Element не экранирует значение свойства, но предотвращает автоматическое выполнение как HTML.


Автоматическое экранирование

FAST Element не рендерит строку как HTML по умолчанию. Если значение свойства выводится через шаблон с ${}, оно интерпретируется как текст:

import { html, FASTElement } from "@microsoft/fast-element";

export class UserCard extends FASTElement {
  name = '';
}

const template = html<UserCard>`
  <div>Name: ${x => x.name}</div>
`;

Даже если name содержит HTML или скрипт, он будет отображён как текст, а не выполнен. Это ключевой механизм защиты от XSS.


Привязка атрибутов к DOM-элементам

FAST Element поддерживает динамическое связывание свойств с DOM-атрибутами через директивы. Например:

const template = html<UserCard>`
  <input type="text" value="${x => x.name}">
`;

В этом случае важно понимать, что FAST автоматически экранирует значение при установке атрибута value. Непосредственная вставка через innerHTML требует ручного контроля безопасности.


Контроль допустимых значений

Для повышения безопасности рекомендуется валидировать или фильтровать значения атрибутов перед их применением. Это можно делать через getter/setter свойства:

import { FASTElement, attr } from "@microsoft/fast-element";

export class UserCard extends FASTElement {
  @attr
  get age() {
    return this._age;
  }
  set age(value) {
    const numericValue = Number(value);
    this._age = isNaN(numericValue) ? 0 : numericValue;
  }
}

Такой подход предотвращает установку невалидных или потенциально опасных значений.


Использование типов и конвертеров

FAST Element позволяет задавать тип свойства и конвертеры при объявлении атрибута. Это повышает безопасность:

import { FASTElement, attr } from "@microsoft/fast-element";

export class ToggleButton extends FASTElement {
  @attr({ mode: 'boolean' }) active;
}
  • mode: 'boolean' гарантирует, что атрибут интерпретируется как логическое значение (true/false).
  • Любые попытки установить строку "jav * ascript:alert(1)" будут преобразованы к true/false, что исключает выполнение кода.

Обработка пользовательского ввода

В FAST Element любые данные, полученные от пользователя или внешнего источника, должны обрабатываться перед применением к DOM. Например:

const unsafeInput = "<img src=x oner ror=alert(1)>";
this.name = unsafeInput.replace(/</g, "&lt;").replace(/>/g, "&gt;");

Использование встроенного механизма привязки ${x => x.property} уже безопасно для отображения текста. Экранование требуется только при прямой вставке в innerHTML.


Атрибуты как источник состояния

Атрибуты в HTML часто служат источником состояния для компонентов. FAST Element позволяет использовать наблюдаемые свойства (@observable) и события изменения, что дает контроль над тем, какие значения действительно применяются к DOM:

import { FASTElement, observable } from "@microsoft/fast-element";

export class Counter extends FASTElement {
  @observable count = 0;

  countChanged(oldValue, newValue) {
    if (newValue < 0) this.count = 0;
  }
}

Это предотвращает установку некорректных значений и повышает безопасность работы с атрибутами.


Практические рекомендации по безопасности

  • Использовать привязку через ${} вместо innerHTML.
  • Валидировать значения атрибутов через setter или конвертер.
  • Для булевых и числовых атрибутов задавать mode при объявлении @attr.
  • Никогда не вставлять пользовательский ввод в DOM без экранирования.
  • Использовать наблюдаемые свойства для контроля состояния компонентов.

Эти механизмы делают FAST Element безопасным инструментом для создания Web Components, минимизируя риск XSS и других атак через неконтролируемые атрибуты.