experimental_taintObjectReference
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
で定義したものに置き換えられます。特定のTypedArrayインスタンスがobject
としてtaintObjectReference
に渡された場合、TypedArrayの他のコピーは汚染されません。
戻り値
experimental_taintObjectReference
は undefined
を返します。
注意事項
- 汚染されたオブジェクトを再作成または複製すると、機密データを含む可能性のある新しい非汚染オブジェクトが作成されます。たとえば、汚染された
user
オブジェクトがある場合、const userInfo = {name: user.name, ssn: user.ssn}
または{...user}
によって、汚染されていない新しいオブジェクトが作成されます。taintObjectReference
は、オブジェクトがクライアントコンポーネントに変更されずに渡された場合の単純なミスからしか保護しません。
使用方法
ユーザーデータが意図せずクライアントに到達するのを防ぐ
クライアントコンポーネントは、機密データを含むオブジェクトを受け入れるべきではありません。理想的には、データ取得関数は、現在のユーザーがアクセスすべきではないデータを公開すべきではありません。リファクタリング中にミスが発生することがあります。このようなミスが将来発生するのを防ぐために、データ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
オブジェクトをクライアントコンポーネントに渡そうとすると、渡されたエラーメッセージと共にエラーがスローされます。