taintObjectReference
를 사용하면 user
객체와 같은 특정한 객체 인스턴스를 클라이언트 컴포넌트로 전송하는 것을 방지할 수 있습니다.
experimental_taintObjectReference(message, object);
키, 해시 또는 토큰이 전달되는 것을 방지하는 방법은 taintUniqueValue
를 참고하세요.
레퍼런스
taintObjectReference(message, object)
클라이언트로 전달되지 않아야 할 객체를 taintObjectReference
와 함께 호출하여 React에 등록합니다.
import {experimental_taintObjectReference} from 'react';
experimental_taintObjectReference(
'환경 변수는 클라이언트로 전달하지 마세요.',
process.env
);
매개변수
-
message
: 객체가 클라이언트 컴포넌트로 전달될 때 표시할 메시지. 객체가 클라이언트 컴포넌트로 전달될 때 발생하는 에러 객체에 포함되어 나타나는 메시지입니다. -
object
: 오염(taint)될 객체. 함수와 클래스 인스턴스도object
로서taintObjectReference
에 전달될 수 있습니다. 함수와 클래스는 클라이언트 컴포넌트로 전달되지 않도록 이미 막혀있지만 React의 기본 에러 메시지 대신message
에 설정한 메시지를 보여줄 수 있습니다. 타입 배열(Typed Array)의 인스턴스를object
로서taintObjectReference
에 전달하면 같은 타입 배열의 다른 인스턴스가 오염되지 않습니다.
반환값
experimental_taintObjectReference
는 undefined
를 반환합니다.
주의 사항
- 오염된 객체를 다시 작성하거나 복제하면 오염되지 않은 객체가 새로 만들어집니다. 새로 만들어진 객체는 민감한 데이터를 포함할 수 있습니다. 예를 들어, 오염된
user
객체가 있다고 할 때,const userInfo = {name: user.name, ssn: user.ssn}
혹은{...user}
를 실행하면 오염되지 않은 새로운 객체를 작성합니다.taintObjectReference
는 객체가 변경되지 않은 상태에서 클라이언트 컴포넌트로 그대로 전달되는 것만 방지합니다.
사용법
사용자 데이터가 의도하지 않게 클라이언트로 전달되는 것을 방지하기
클라이언트 컴포넌트에는 민감한 데이터를 담은 객체가 전달되어서는 안 됩니다. 이상적으로, 데이터 페치 함수는 현재 사용자가 접근할 수 없는 데이터를 노출하면 안 됩니다. 하지만 리팩토링 도중 가끔 실수가 발생하기도 합니다. 데이터 API에서 사용자 객체를 “오염(taint)“시켜서 이러한 실수를 방지할 수 있습니다.
import {experimental_taintObjectReference} from 'react';
export async function getUser(id) {
const user = await db`SELECT * FROM users WHERE id = ${id}`;
experimental_taintObjectReference(
'user 객체 전체를 클라이언트로 전달하지 마세요.' +
'필요하다면 일부 특정한 프로퍼티만 뽑아서 사용하는 것이 좋습니다.',
user,
);
return user;
}
이제 누군가 이 객체를 클라이언트 컴포넌트로 전달하려고 하면 전달된 에러 메시지와 함께 에러가 발생됩니다.
Deep Dive
민감한 데이터에 접근할 수 있는 서버 컴포넌트 환경을 실행하고 있다면 객체를 그대로 전달할 때 주의를 기울여야 합니다.
// 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
객체가 클라이언트 컴포넌트로 전달되는 것을 방지하려면 사용자 객체를 “오염(taint)“시켜야 합니다.
// api.js
import {experimental_taintObjectReference} from 'react';
export async function getUser(id) {
const user = await db`SELECT * FROM users WHERE id = ${id}`;
experimental_taintObjectReference(
'user 객체 전체를 클라이언트로 전달하지 마세요. ' +
'필요하다면 일부 특정한 프로퍼티만 뽑아서 사용하는 것이 좋습니다.',
user,
);
return user;
}
이제 누군가 user
객체를 클라이언트 컴포넌트로 전달하려고 하면 설정한 에러 메시지와 함께 에러가 발생합니다.