experimental_taintObjectReference

En construction

Cette API est expĂ©rimentale : elle n’a donc pas encore Ă©tĂ© livrĂ©e dans une version stable de React.

Vous pouvez l’essayer en mettant Ă  jour vos modules React afin d’utiliser la version expĂ©rimentale la plus rĂ©cente :

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

Les versions expérimentales de React sont susceptibles de contenir des bugs. Veillez donc à ne pas les utiliser en production.

Cette API n’est disponible qu’au sein des React Server Components.

taintObjectReference vous permet d’empĂȘcher qu’une instance objet prĂ©cise soit passĂ©e Ă  un Composant Client, comme par exemple un objet user.

experimental_taintObjectReference(message, object);

Pour empĂȘcher le passage d’une clĂ©, d’un hash ou d’un jeton, utilisez taintUniqueValue.


Référence

taintObjectReference(message, object)

Appelez taintObjectReference avec un objet pour indiquer Ă  React qu’il ne doit pas permettre le passage de cet objet tel quel vers le cĂŽtĂ© client :

import { experimental_taintObjectReference } from 'react';

experimental_taintObjectReference(
'Ne passez pas TOUTES les variables d’environnement au client.',
process.env
);

Voir plus d’exemples ci-dessous.

ParamĂštres

  • message : le message que vous souhaitez afficher si l’objet est passĂ© Ă  un Composant Client. Ce message fera partie de l’erreur qui sera levĂ©e si l’objet est passĂ© Ă  un Composant Client.

  • object : l’objet a « ternir Â». Les fonctions et instances de classes peuvent ĂȘtre passĂ©es en tant qu’object Ă  taintObjectReference. React empĂȘche d’entrĂ©e de jeu leur passage aux Composants Clients, mais ça remplacera le message d’erreur par dĂ©faut avec ce que vous aurez passĂ© comme message. Notez que lorsqu’une instance prĂ©cise d’un tableau typĂ© (Typed Array, NdT) est passĂ©e comme object Ă  taintObjectReference, les copies de ce tableau typĂ© ne seront quant Ă  elles pas ternies.

Valeur renvoyée

experimental_taintObjectReference renvoie undefined.

Limitations

  • RecrĂ©er ou cloner un objet terni produit un nouvel objet intact, susceptible de contenir des donnĂ©es sensibles. Si par exemple vous avez un objet user terni, const userInfo = {name: user.name, ssn: user.ssn} ou {...user} produiront de nouveaux objets qui ne seront, eux, pas ternis. taintObjectReference ne protĂšge que contre les bĂ©vues simples lorsque l’objet est passĂ© tel quel Ă  un Composant Client.

PiĂšge

Ne comptez pas sur le ternissement pour garantir la sĂ©curitĂ©. Ternir un objet n’empĂȘche pas la fuite de toute donnĂ©e dĂ©rivĂ©e imaginable. Un clone de l’objet terni crĂ©era par exemple un objet intact. L’utilisation de donnĂ©es d’un objet terni (ex. {secret: taintedObj.secret}) crĂ©e une nouvelle valeur, ou un nouvel objet, qui ne sera pas terni·e. Le ternissement est une couche de protection ; une appli sĂ©curisĂ©e aura plusieurs couches de protection complĂ©mentaires, des API soigneusement conçues et des mĂ©canismes d’isolation en place.


Utilisation

EmpĂȘcher des donnĂ©es utilisateur d’atteindre le client par inadvertance

Un Composant Client ne devrait jamais accepter des objets comportant des donnĂ©es sensibles. Dans l’idĂ©al, les fonctions de chargement de donnĂ©es ne devraient pas exposer des donnĂ©es auxquelles l’utilisateur actif n’a pas accĂšs. Mais des erreurs peuvent survenir lors d’une refonte du code. Pour se protĂ©ger contre des erreurs en aval nous pouvons « ternir Â» l’objet utilisateur dans notre API de donnĂ©es.

import { experimental_taintObjectReference } from 'react';

export async function getUser(id) {
const user = await db`SELECT * FROM users WHERE id = ${id}`;
experimental_taintObjectReference(
'Ne passez pas l’objet utilisateur entier au client. ' +
'Récupérez plutÎt les propriétés spécifiques à votre scénario.',
user,
);
return user;
}

DĂ©sormais, si un code serveur quelconque essaie de passer cet objet Ă  un Composant Client, une erreur sera levĂ©e avec le message d’erreur fourni.

En détail

Se protéger contre les fuites lors du chargement de données

Si votre environnement de Composants Serveur a accĂšs Ă  des donnĂ©es sensibles, vous devez ĂȘtre attentif·ve Ă  ne pas passer des objets directement :

// 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);
// NE FAITES PAS ÇA
return <InfoCard user={user} />;
}
// components.js
"use client";

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

Dans l’idĂ©al, getUser ne devait pas exposer de donnĂ©es auxquelles l’utilisateur courant n’a pas accĂšs. Pour empĂȘcher le passage en aval de l’objet user Ă  un Composant Client, nous pouvons dĂ©cider de « ternir Â» cet objet :

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

export async function getUser(id) {
const user = await db`SELECT * FROM users WHERE id = ${id}`;
experimental_taintObjectReference(
'Ne passez pas l’objet utilisateur entier au client. ' +
'Récupérez plutÎt les propriétés spécifiques à votre scénario.',
user,
);
return user;
}

DĂ©sormais, si un code serveur quelconque essaie de passer cet objet Ă  un Composant Client, une erreur sera levĂ©e avec le message d’erreur fourni.