taintUniqueValue מאפשרת למנוע העברה של מאפיינים ייחודיים ל-Client Components, כמו סיסמ, מפתחות או אסימונים.
taintUniqueValue(errMessage, lifetime, value)כדי למנוע העברה של אובייקט שמכיל מידע ראו taintObjectReference.
הפניה
taintUniqueValue(message, lifetime, value)
קראו ל-taintUniqueValue עם סיסמה, אסימון, מפתח או hash כדי לרשום אותם ב-React כמשהו שאסור להעביר ללקוח כפי שהוא:
import {experimental_taintUniqueValue} from 'react';
experimental_taintUniqueValue(
'Do not pass secret keys to the client.',
process,
process.env.SECRET_KEY
);פרמטרים
-
message: ההודעה שתרצו להציג אםvalueמועברת ל-Client Component. הודעה זו תוצג כחלק מה-שגיאה שיושלך אםvalueמועבר ל-Client Component. -
lifetime: כל אובייקט שמבקש כמה זמן T1 צריך להיות מסומן כ-tainted.valueייחסם משל לכל רכיב לקוח כל עוד האובייקט הזה עדיין קיים. לדוגמה, העברתglobalThisחוסמת את הערך לאורך כל חיי האפליקציה. לרובlifetimeהוא אובייקט את המאפיינים שלו מכיליםvalue. -
value: מחרוזת, bigint או TypedArray.valueחייב להיות רצף ייחודי של תווים או בתים עם אנטרופיה גבוהה, כמו אסימון קריפטוגרפי, מפתח פרטי, hash או סיסמה ארוכה.valueייחסם משליחה לכל רכיב לקוח.
מחזירה
experimental_taintUniqueValue מחזירה undefined.
אזהרות
- גזירת ערכים חדשים מערכים מוכתמים עלולה בהנאה כתמים. ערכים חדשים רוזות מהמרת אותיות לגדולות, שרשור מחרוזות tainted למחרוזת גדולה יותר, המרה ל-base64, חיתוך תת-מחת מערכים tainted וטרנספורמציות דומות, הן taintainted אלא אם קוראים במפורש ל-
taintUniqueValueגם על הערכים החדשים. - אל תשתמשו ב-
taintUniqueValueלהגנה על ערכים בעלי אנטרופיה נמוכה כמו קודי PIN או מספרי טלפון. אם תעשה משהו טוב, הוא יעשה בבקשה איזה ערך מסומן יעבור על כל הערכים האפשריים של הסוד.
שימוש
מניעת העברת אסימון לרכיבי לקוח
כדי לוודא מידע רגיש כמו סיסמאות, אסימוני הפעלה או ערכים ייחודיים אחרים לא מועברים בטעות לרכיבי לקוח, הפונקציה taintUniqueValue מספקת שכבת הגנה. כשערך מסומן כ-tainted, כל הניסיון להעביר אותו לרכיב לקוח יגרום לשגיאה.
הארגומנט lifetime מגדיר את משך הזמן שבו הערך נשאר tainted. לערכים שצריכים נשארים נגועים ללא הגבלת זמן, אובייקטים כמו globalThis או process יכולים לשמש כ-lifetime. לאובייקטים האלה יש אורך חיים שחופף לכל משך הרצת האפליקציה.
import {experimental_taintUniqueValue} from 'react';
experimental_taintUniqueValue(
'Do not pass a user password to the client.',
globalThis,
process.env.SECRET_KEY
);אם אורך החיים של הערך המסומן קשור לאובייקט מסוים, lifetime צריך להיות הערך שעוטף את הערך. כך מובטח שהערך המסומן יישאר מוגן לאורך חיי האובייקט העוטף.
import {experimental_taintUniqueValue} from 'react';
export async function getUser(id) {
const user = await db`SELECT * FROM users WHERE id = ${id}`;
experimental_taintUniqueValue(
'Do not pass a user session token to the client.',
user,
user.session.token
);
return user;
}בדוגמה הזו, האובייקט user משמש כארגומנט lifetime. אם האובייקט הזה נשמר ב-global cache או נבקשה אחרת, אסימון ה-Session נשאר נגוע.
Deep Dive
אם אתם מריצים סביבת רכיבי שרת יש להפנות למפתחים פרטיים או סיסמאות, כמו סיסמת מסד נתונים, צריך להעביר את זה לרכיב לקוח.
export async function Dashboard(props) {
// DO NOT DO THIS
return <Overview password={process.env.API_PASSWORD} />;
}"use client";
import {useEffect} from '...'
export async function Overview({ password }) {
useEffect(() => {
const headers = { Authorization: password };
fetch(url, { headers }).then(...);
}, [password]);
...
}הדוגמה הזו תדליף את סוד ה-API אסימון ללקוח. אם האסימון הזה לשמש יכול לגשת לנתוני המשתמש הזה לא אמורה להיות גישה אליהם, זהונים להוביל לדליפת מידע.
אידיאלית, סודות כאלה יופשטו לקובץ עוזר יחיד אפשרי לייבא רק מתוך כלי עזר מהימנים בצד השרת. אפשר אפילו לתייג את העוזר עם server-only כדי שהקובץ הזה לא מיובא ללקוח.
import "server-only";
export function fetchAPI(url) {
const headers = { Authorization: process.env.API_PASSWORD };
return fetch(url, { headers });
}לפעמים קורות טעויות על ריפאקטורינג וכל חברי הצוות מודעים לכך. כדי להתגונן מפני טעויות כאלה בהמשך, אפשר “לסמן” את הסיסמה עצמה:
import "server-only";
import {experimental_taintUniqueValue} from 'react';
experimental_taintUniqueValue(
'Do not pass the API token password to the client. ' +
'Instead do all fetches on the server.'
process,
process.env.API_PASSWORD
);עכשיו, בכל פעם שמישהו ינסה להעביר את הסיסמה הזו ל-Client Component, או לשלוח אותה ל-Client Component דרך פעולת שרת, תיזרק שגיאה עם ההודעה שהגדרתם בקריאה ל-taintUniqueValue.