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: 如果对象被传递到客户端组件,则要显示的消息。如果对象被传递到客户端组件,此消息将作为抛出错误的一部分显示。

  • object: 要被污染的对象。函数和类实例可以作为 object 传递给 taintObjectReference。函数和类已被阻止传递给客户端组件,但 React 的默认错误消息将被您在 message 中定义的内容替换。当 Typed Array 的特定实例作为 object 传递给 taintObjectReference 时,Typed Array 的任何其他副本都不会被污染。

返回值

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 对象传递到客户端组件,则会抛出错误,并显示传入的错误消息。