Spec-Zone.ru › React 18

experimental_taintUniqueValue

В разработке

Этот API находится в стадии разработки и пока не доступен в стабильной версии React.

Вы можете попробовать его, обновив пакеты React до последней экспериментальной версии:

  • react@experimental
  • react-dom@experimental
  • eslint-plugin-react-hooks@experimental

Экспериментальные версии React могут содержать ошибки. Не используйте их в продакшене.

Этот API доступен только внутри React Server Components.

taintUniqueValue позволяет предотвратить передачу уникальных значений в компоненты клиента, таких как пароли, ключи или токены.

taintUniqueValue(errMessage, lifetime, value)

Чтобы предотвратить передачу объекта, содержащего конфиденциальные данные, см. taintObjectReference.

  • Ссылка
    • taintUniqueValue(message, lifetime, value)
  • Использование
    • Предотвращение передачи токена в компоненты клиента

Ссылка

taintUniqueValue(message, lifetime, value)

Вызовите taintUniqueValue с паролем, токеном, ключом или хэшем, чтобы зарегистрировать его в React как значение, которое не должно передаваться в компоненты клиента:

import {experimental_taintUniqueValue} from 'react';

experimental_taintUniqueValue(
  'Do not pass secret keys to the client.',
  process,
  process.env.SECRET_KEY
);

См. дополнительные примеры ниже.

Параметры

  • message: Сообщение, которое вы хотите отобразить, если value передается в компонент клиента. Это сообщение будет отображено как часть ошибки, которая будет выброшена, если value передается в компонент клиента.

  • lifetime: Любой объект, который указывает, как долго value должен быть помечен как конфиденциальный. value будет заблокирован от отправки в любой компонент клиента, пока этот объект существует. Например, передача globalThis блокирует значение на весь срок действия приложения. lifetime обычно является объектом, свойства которого содержат value.

  • value: Строка, целое число большого размера или TypedArray. value должен быть уникальной последовательностью символов или байтов с высокой энтропией, такой как криптографический токен, закрытый ключ, хэш или длинный пароль. value будет заблокирован от отправки в любой компонент клиента.

Возвращаемое значение

experimental_taintUniqueValue возвращает undefined.

Ограничения

  • Вычисление новых значений из помеченных значений может нарушить защиту от подмены. Новые значения, созданные путем преобразования помеченных значений в верхний регистр, конкатенации помеченных строковых значений в большую строку, преобразования помеченных значений в base64, подстроки помеченных значений и другие аналогичные преобразования, не помечаются как конфиденциальные, если вы явно не вызываете taintUniqueValue для этих вновь созданных значений.
  • Не используйте taintUniqueValue для защиты значений с низкой энтропией, таких как PIN-коды или номера телефонов. Если какое-либо значение в запросе контролируется злоумышленником, он может определить, какое значение помечено как конфиденциальное, перечислив все возможные значения секрета.

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

Предотвращение передачи токена в компоненты клиента

Для того, чтобы конфиденциальная информация, такая как пароли, сеансовые токены или другие уникальные значения, не попала непреднамеренно в компоненты клиента, функция taintUniqueValue предоставляет уровень защиты. Когда значение помечено как конфиденциальное, любая попытка передать его в компонент клиента приведет к ошибке.

Аргумент lifetime определяет продолжительность, в течение которой значение остается помеченным как конфиденциальное. Для значений, которые должны оставаться помеченными как конфиденциальные неопределенно долго, объекты, такие как globalThis или process могут служить аргументом lifetime. Эти объекты существуют на протяжении всего выполнения вашего приложения.

import {experimental_taintUniqueValue} from 'react';

experimental_taintUniqueValue(
  'Do not pass a user password to the client.',
  globalThis,
  process.env.SECRET_KEY
);

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

import {experimental_taintUniqueValue} from 'react';

export async function getUser(id) {
  const user = await db`SELECT * FROM users WHERE id = ${id}`;
  experimental_taintUniqueValue(
    'Do not pass a user session token to the client.',
    user,
    user.session.token
  );
  return user;
}

В этом примере объект user используется в качестве аргумента lifetime. Если этот объект хранится в глобальном кэше или доступен другому запросу, сеансовый токен остается помеченным как конфиденциальный.

Опасность

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

import {experimental_taintUniqueValue} from 'react';

const password = 'correct horse battery staple';

experimental_taintUniqueValue(
  'Do not pass the password to the client.',
  globalThis,
  password
);

const uppercasePassword = password.toUpperCase() // `uppercasePassword` is not tainted

В этом примере константа password помечена как конфиденциальная. Затем password используется для создания нового значения uppercasePassword, вызывая метод toUpperCase для password. Новое значение uppercasePassword не помечено как конфиденциальное.

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

Пометка значений как конфиденциальных защищает только от простых ошибок, таких как явное передача секретных значений клиенту. Ошибки при вызове taintUniqueValue (например, использование глобального хранилища за пределами React без соответствующего объекта срока существования) могут привести к тому, что помеченное значение станет непомеченным. Пометка значений как конфиденциальных — это уровень защиты; безопасное приложение будет иметь несколько уровней защиты, хорошо спроектированные API и шаблоны изоляции.

Подробное рассмотрение

Использование server-only и taintUniqueValue для предотвращения утечки секретов

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

export async function Dashboard(props) {
  // DO NOT DO THIS
  return <Overview password={process.env.API_PASSWORD} />;
}
"use client";

import {useEffect} from '...'

export async function Overview({ password }) {
  useEffect(() => {
    const headers = { Authorization: password };
    fetch(url, { headers }).then(...);
  }, [password]);
  ...
}

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

В идеале такие секреты абстрагируются в один вспомогательный файл, который может импортироваться только надёжными утилитами данных на сервере. Вспомогательный файл можно даже пометить server-only для обеспечения того, что этот файл не будет импортирован на клиенте.

import "server-only";

export function fetchAPI(url) {
  const headers = { Authorization: process.env.API_PASSWORD };
  return fetch(url, { headers });
}

Иногда при рефакторинге происходят ошибки, и не все коллеги могут быть в курсе этого. Для защиты от подобных ошибок в будущем можно «пометить» сам пароль:

import "server-only";
import {experimental_taintUniqueValue} from 'react';

experimental_taintUniqueValue(
  'Do not pass the API token password to the client. ' +
    'Instead do all fetches on the server.'
  process,
  process.env.API_PASSWORD
);

Теперь, когда кто-либо попытается передать этот пароль в компонент клиента или отправить его клиенту с помощью Server Action, будет выброшена ошибка с сообщением, которое вы определили при вызове taintUniqueValue.


© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://18.react.dev/reference/react/experimental_taintUniqueValue

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API