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 物件傳遞到客戶端元件,則會拋出一個錯誤,並顯示傳入的錯誤訊息。