experimental_taintObjectReference

Цей API є експериментальним і поки що недоступний у стабільній версії React.

Ви можете спробувати, оновивши пакунки React до останньої експериментальної версії:

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

Експериментальні версії React можуть містити помилки. Не використовуйте їх у виробництві.

Цей API доступний лише всередині Компонентів сервера React.

taintObjectReference дозволяє запобігти передачі певного екземпляра об'єкта клієнтському компоненту, наприклад, об'єкта user.

experimental_taintObjectReference(message, object);

Щоб запобігти передачі ключа, хешу або токена, дивіться taintUniqueValue.


Довідник

taintObjectReference(message, object)

Викликайте taintObjectReference з об'єктом, щоб зареєструвати його в React як щось, що не можна передавати клієнту як є:

import {experimental_taintObjectReference} from 'react';

experimental_taintObjectReference(
  'Do not pass ALL environment variables to the client.',
  process.env
);

Дивіться більше прикладів нижче.

Параметри

  • message: Повідомлення, яке ви хочете відобразити, якщо об'єкт буде передано клієнтському компоненту. Це повідомлення буде показано як частина помилки, яка буде згенерована, якщо об'єкт буде передано клієнтському компоненту.

  • об'єкт: об'єкт, який буде зіпсовано. Функції та екземпляри класів можуть бути передані до taintObjectReference як object. Функції та класи вже заблоковано для передачі клієнтським компонентам, але стандартне повідомлення про помилку React буде замінено на те, що ви визначили в message. Коли конкретний екземпляр типізованого масиву передається до taintObjectReference як об'єкт, будь-які інші копії типізованого масиву не будуть зіпсовані.

Повернення

experimental_taintObjectReference повертає undefined.

Застереження

  • Відтворення або клонування зіпсованого об'єкта створює новий незаплямований об'єкт, який може містити конфіденційні дані. Наприклад, якщо у вас є пошкоджений об'єкт user, const userInfo = {name: user.name, ssn: user.ssn} або {...user} створять нові об'єкти, які не будуть пошкоджені. taintObjectReference захищає лише від простих помилок, коли об'єкт передається клієнтському компоненту без змін.

Не покладайтеся лише на псування для безпеки. Псування об'єкта не запобігає витоку всіх можливих похідних значень. Наприклад, клон зіпсованого об'єкта створить новий незаплямований об'єкт. Використання даних із зіпсованого об'єкта (наприклад, {secret: taintedObj.secret}) створить нове значення або об'єкт, який не є зіпсованим. Пошкодження - це рівень захисту; безпечна програма матиме декілька рівнів захисту, добре розроблені API та шаблони ізоляції.


Використання

Запобігти ненавмисному потраплянню даних користувача до клієнта

Клієнтський компонент ніколи не повинен приймати об'єкти, які містять конфіденційні дані. В ідеалі, функції отримання даних не повинні відкривати дані, до яких поточний користувач не повинен мати доступу. Іноді під час рефакторингу трапляються помилки. Щоб захиститися від таких помилок у майбутньому, ми можемо "заплямувати" об'єкт користувача у нашому API даних.

import {experimental_taintObjectReference} from 'react';

export async function getUser(id) {
  const user = await db`SELECT * FROM users WHERE id = ${id}`;
  experimental_taintObjectReference(
    'Do not pass the entire user object to the client. ' +
      'Instead, pick off the specific properties you need for this use case.',
    user,
  );
  return user;
}

Тепер при спробі передати цей об'єкт клієнтському компоненту буде згенеровано помилку із повідомленням про передану помилку.

Захист від витоків при отриманні даних

Якщо ви використовуєте середовище серверних компонентів, яке має доступ до конфіденційних даних, вам слід бути обережними і не передавати об'єкти безпосередньо:

// api.js
export async function getUser(id) {
  const user = await db`SELECT * FROM users WHERE id = ${id}`;
  return user;
}
import { getUser } from 'api.js';
import { InfoCard } from 'components.js';

export async function Profile(props) {
  const user = await getUser(props.userId);
  // DO NOT DO THIS
  return <InfoCard user={user} />;
}
// components.js
"use client";

export async function InfoCard({ user }) {
  return <div>{user.name}</div>;
}

В ідеалі, getUser не повинен показувати дані, до яких поточний користувач не повинен мати доступу. Щоб запобігти передачі об'єкта user клієнтському компоненту далі по лінії, ми можемо "зіпсувати" об'єкт користувача:

// api.js
import {experimental_taintObjectReference} from 'react';

export async function getUser(id) {
  const user = await db`SELECT * FROM users WHERE id = ${id}`;
  experimental_taintObjectReference(
    'Do not pass the entire user object to the client. ' +
      'Instead, pick off the specific properties you need for this use case.',
    user,
  );
  return user;
}

Тепер, якщо хтось спробує передати об'єкт user клієнтському компоненту, буде згенеровано помилку з повідомленням про помилку.