Trusted Types در وردپرس (انواع مورد اعتماد) چطور XSS را ریشه‌کن می‌کند؟ این پرسشی است که در مرز میان امنیت سنتی و امنیت مدرن وب قرار می‌گیرد. Trusted Types یک API مرورگری است که به‌عنوان بخشی از CSP (Content Security Policy - سیاست امنیتی محتوا) معرفی شده و هدف آن، ریشه‌کن کردن DOM-based XSS (Cross-Site Scripting - اسکریپت‌نویسی میان‌سایتی مبتنی بر DOM) است. برخلاف رویکردهای سنتی که بر پاک‌سازی ورودی و escape خروجی تکیه می‌کنند، Trusted Types با استفاده از یک «دروازه اجباری» در سطح مرورگر، اطمینان می‌دهد که فقط داده‌های مورد اعتماد به sinkهای خطرناک مانند innerHTML، eval() و document.write() می‌رسند. در بستر وردپرس، Trusted Types از دو جهت مهم است: اول، پیشخوان وردپرس که به‌شدت از JavaScript استفاده می‌کند؛ دوم، افزونه‌ها و قالب‌های شخص‌ثالث که اغلب از sinkهای خطرناک بدون محافظت استفاده می‌کنند. پیاده‌سازی Trusted Types در وردپرس نیازمند تغییرات در سطح CSP، بازنویسی کد JavaScript و استفاده از پالیسی‌های سفارشی است. مزیت اصلی آن، «ریشه‌کن کردن» XSS به‌جای فقط «کاهش» آن است. چالش‌ها شامل عدم پشتیبانی در همه مرورگرها، نیازمند بازنویسی کد قدیمی و سازگاری با کتابخانه‌های شخص‌ثالث است. در این نوشتار، از ریشه‌های فنی تا پیاده‌سازی عملی Trusted Types در وردپرس را بررسی می‌کنیم.

نخستین‌باری که با Trusted Types روبه‌رو شدم، در یک پروژه امنیتی بود که در آن تیم توسعه تصمیم گرفته بود به‌جای «کاهش XSS»، آن را «ریشه‌کن» کند. این تصمیم، ما را با چالش‌های جالبی روبه‌رو کرد و در نهایت به یک معماری امنیتی پایدارتر رسیدیم. در این نوشتار، از ریشه‌های فنی تا پیاده‌سازی عملی Trusted Types در وردپرس را بررسی می‌کنیم.

Trusted Types چیست؟

Trusted Types یک API مرورگری است که به‌عنوان بخشی از CSP Level 3 معرفی شد و هدف آن، جلوگیری از DOM-based XSS با «اجباری کردن» استفاده از داده‌های مورد اعتماد در sinkهای خطرناک است. این API توسط گوگل توسعه یافت و امروزه در مرورگرهای مبتنی بر Chromium (Chrome، Edge، Opera) پشتیبانی می‌شود.

مکانیزم اصلی Trusted Types ساده است: وقتی فعال باشد، مرورگر اجازه نمی‌دهد یک رشته معمولی به sinkهای خطرناک مانند innerHTML، outerHTML، eval()، Function()، document.write() و setTimeout(string) منتقل شود. به‌جای آن، فقط «Trusted Type» — یعنی یک شیء ساخته‌شده توسط پالیسی مورد اعتماد — پذیرفته می‌شود.

برای درک عمیق‌تر جایگاه این مفهوم در امنیت وب، اصول امنیت وب را ببینید.

Trusted Types یک «قفل مرورگری» است: حتی اگر کد شما اشتباه باشد، مرورگر اجازه نمی‌دهد داده خطرناک به sinkهای خطرناک برسد. این تفاوت بین «کاهش» و «ریشه‌کن کردن» است.

چرا Trusted Types برای وردپرس مهم است؟

وردپرس به‌شدت از JavaScript استفاده می‌کند — از پیشخوان گرفته تا ویرایشگر بلوک گوتنبرگ و REST API. این استفاده گسترده، سطح حمله DOM-based XSS را بزرگ می‌کند. سه دلیل اصلی برای اهمیت Trusted Types در وردپرس وجود دارد:

  • پیشخوان پویا: پیشخوان وردپرس از React و jQuery استفاده می‌کند و صدها sink خطرناک در آن وجود دارد.
  • افزونه‌ها و قالب‌ها: بسیاری از افزونه‌ها از innerHTML و document.write() بدون محافظت استفاده می‌کنند.
  • REST API: پاسخ‌های JSON در JavaScript پردازش می‌شوند و می‌توانند به sinkهای خطرناک برسند.

نکته مهم این است که وردپرس هسته در نسخه‌های اخیر گام‌هایی برای سازگاری با Trusted Types برداشته، اما پیاده‌سازی کامل آن نیازمند تلاش مشترک هسته، افزونه‌ها و قالب‌ها است. برای مرور کلی امنیت وردپرس، امنیت وردپرس را ببینید.

Trusted Types و CSP

Trusted Types از طریق دایرکتیو require-trusted-types-for در CSP فعال می‌شود:

Content-Security-Policy: require-trusted-types-for 'script';

این دایرکتیو به مرورگر می‌گوید که برای همه sinkهای JavaScript، فقط Trusted Type پذیرفته شود. علاوه بر آن، دایرکتیو trusted-types مشخص می‌کند چه پالیسی‌هایی مجاز هستند:

Content-Security-Policy: require-trusted-types-for 'script'; trusted-types my-policy default;

در وردپرس، می‌توانید این هدر را با فیلتر wp_headers اضافه کنید:

add_filter( 'wp_headers', function( $headers ) {
  $headers['Content-Security-Policy'] = "require-trusted-types-for 'script'; trusted-types default";
  return $headers;
} );

برای درک جامع‌تر CSP، راهنمای هدرهای امنیتی HTTP را ببینید.

پالیسی‌های Trusted Types

پالیسی Trusted Types یک شیء JavaScript است که متدهای ساخت Trusted Type را فراهم می‌کند. سه نوع Trusted Type وجود دارد:

  • TrustedHTML: برای innerHTML، outerHTML و document.write().
  • TrustedScript: برای eval()، Function() و setTimeout(string).
  • TrustedScriptURL: برای script.src و Worker().

ساخت یک پالیسی ساده:

if ( window.trustedTypes && window.trustedTypes.createPolicy ) {
  const myPolicy = trustedTypes.createPolicy( 'my-policy', {
    createHTML: ( input ) => {
      // پاک‌سازی و escape
      return input.replace( /<script>/gi, '' );
    },
    createScript: ( input ) => input,
    createScriptURL: ( input ) => {
      // فقط URLهای مجاز
      const allowed = ['https://example.com'];
      const url = new URL( input );
      if ( ! allowed.includes( url.origin ) ) {
        throw new Error( 'Invalid URL' );
      }
      return input;
    },
  } );
  
  // استفاده:
  element.innerHTML = myPolicy.createHTML( '<p>Hello</p>' );
}

نکته مهم: پالیسی default به‌طور خودکار توسط مرورگر استفاده می‌شود اگر پالیسی مشخصی تعریف نشده باشد. توصیه می‌شود از پالیسی default اجتناب کنید و پالیسی‌های مشخص با نام تعریف کنید. برای درک عمیق‌تر DOM، کار با DOM در جاوااسکریپت را ببینید.

Sinkهای خطرناک و نقش Trusted Types

جدول زیر مهم‌ترین sinkهای خطرناک را نشان می‌دهد:

Sinkنوع Trusted Typeخطر
innerHTMLTrustedHTMLXSS
outerHTMLTrustedHTMLXSS
document.write()TrustedHTMLXSS
eval()TrustedScriptRCE
Function()TrustedScriptRCE
setTimeout(string)TrustedScriptRCE
script.srcTrustedScriptURLبارگذاری اسکریپت خارجی

وقتی Trusted Types فعال است، اگر کد شما سعی کند یک رشته معمولی را به این sinkها منتقل کند، مرورگر یک TypeError پرتاب می‌کند. این رفتار «اجباری» است و امکان دور زدن آن وجود ندارد. برای مرور نمونه‌های مشابه، راهنمای پیشگیری از حملات XSS را ببینید.

پیاده‌سازی در وردپرس

پیاده‌سازی Trusted Types در وردپرس نیازمند سه گام است:

گام ۱: فعال‌سازی CSP با report-only

ابتدا در حالت report-only فعال کنید تا ببینید چه خطاهایی رخ می‌دهد:

Content-Security-Policy-Report-Only: require-trusted-types-for 'script'; trusted-types default; report-uri /csp-report

گام ۲: بازنویسی کد JavaScript

هر جا از sinkهای خطرناک استفاده می‌کنید، به Trusted Type منتقل کنید:

// قبل:
element.innerHTML = userInput;

// بعد:
const policy = trustedTypes.createPolicy( 'my-policy', {
  createHTML: ( input ) => DOMPurify.sanitize( input ),
} );
element.innerHTML = policy.createHTML( userInput );

استفاده از کتابخانه‌هایی مانند DOMPurify توصیه می‌شود. برای مرور اصول امنیت، نوشتن کد PHP امن برای وردپرس را ببینید.

گام ۳: فعال‌سازی کامل

پس از رفع خطاها، حالت report-only را به حالت اجباری تغییر دهید:

add_filter( 'wp_headers', function( $headers ) {
  $headers['Content-Security-Policy'] = "require-trusted-types-for 'script'; trusted-types my-policy default";
  return $headers;
} );

برای درک عمیق‌تر ساختار هدرها، راهنمای هدرهای امنیتی HTTP را ببینید.

چالش‌ها و محدودیت‌ها

  • پشتیبانی مرورگر: فقط Chromium-based (Chrome، Edge، Opera). Firefox و Safari هنوز پشتیبانی کامل ندارند.
  • سازگاری با کتابخانه‌ها: بسیاری از کتابخانه‌های شخص‌ثالث (jQuery، React در برخی نسخه‌ها) با Trusted Types سازگار نیستند.
  • پیچیدگی بازنویسی: بازنویسی کد قدیمی می‌تواند زمان‌بر باشد.
  • افزونه‌های شخص‌ثالث: بسیاری از افزونه‌ها کد JavaScript دارند که با Trusted Types سازگار نیست.
  • گوتنبرگ: ویرایشگر بلوک گوتنبرگ از sinkهای متعدد استفاده می‌کند و سازگاری کامل آن زمان‌بر است.
  • REST API: داده‌های JSON که در JavaScript پردازش می‌شوند، نیازمند escape سختگیرانه هستند.

نکته مهم این است که Trusted Types یک «راه‌حل کامل» نیست، اما یکی از قوی‌ترین لایه‌های دفاعی در برابر DOM-based XSS است. برای مرور آسیب‌پذیری‌های مشابه، انواع آسیب‌پذیری‌های رایج وب را ببینید.

اشتباهات رایج در پیاده‌سازی Trusted Types

  • فعال‌سازی بدون report-only: ابتدا باید در حالت report-only آزمایش کنید.
  • استفاده از پالیسی default: بهتر است پالیسی‌های مشخص با نام تعریف کنید.
  • نادیده گرفتن TrustedScriptURL: این نوع نیز مهم است و باید محدود شود.
  • اتکای صرف به Trusted Types: باید با Output Escaping و Sanitization ترکیب شود.
  • عدم استفاده از DOMPurify: پاک‌سازی HTML بدون کتابخانه معتبر خطرناک است.
  • فعال‌سازی روی همه صفحات به‌یک‌بار: ممکن است برخی قابلیت‌ها را بشکند.
  • نادیده گرفتن CSP report-uri: بدون آن، خطاها را نمی‌بینید.
  • عدم بازنویسی کتابخانه‌های شخص‌ثالث: این کتابخانه‌ها ممکن است خطا ایجاد کنند.

برای مرور خطاهای مشابه در پیکربندی، اشتباهات امنیتی رایج در وردپرس را ببینید.

پرسش‌های پرتکرار درباره Trusted Types

آیا Trusted Types XSS را کامل ریشه‌کن می‌کند؟ DOM-based XSS را بله، اما انواع دیگر XSS (ذخیره‌شده و بازتابی) همچنان نیازمند Output Escaping هستند.

آیا وردپرس هسته از Trusted Types پشتیبانی می‌کند؟ وردپرس در نسخه‌های اخیر گام‌هایی برای سازگاری برداشته، اما پشتیبانی کامل نیازمند زمان است. برای مرور کلی، امنیت وردپرس را ببینید.

آیا افزونه‌های امنیتی Trusted Types را فعال می‌کنند؟ برخی افزونه‌ها گزینه‌هایی برای فعال‌سازی CSP دارند، اما Trusted Types نیازمند بازنویسی کد است. برای مرور گزینه‌ها، بهترین افزونه‌های امنیتی وردپرس را ببینید.

آیا Trusted Types روی Firefox و Safari کار می‌کند؟ در حال حاضر فقط Chromium-based پشتیبانی می‌کنند. Firefox در حال توسعه است، اما Safari هنوز پشتیبانی رسمی ندارد.

چطور بفهمم سایت من با Trusted Types سازگار است؟ با فعال‌سازی حالت report-only و بررسی گزارش‌ها می‌توانید خطاها را ببینید.

آیا Trusted Types روی عملکرد سایت تأثیر دارد؟ تأثیر آن حداقلی است، زیرا بررسی در سطح مرورگر و به‌صورت native انجام می‌شود.

برای مطالعه بیشتر درباره این مفهوم، صفحه Content Security Policy در ویکی‌پدیا مفید است.

خط پایان

Trusted Types یکی از آن لایه‌های امنیتی است که در مرز میان امنیت سنتی و امنیت مدرن وب قرار می‌گیرد و هدف آن، «ریشه‌کن کردن» DOM-based XSS به‌جای فقط «کاهش» آن است. در بستر وردپرس، این API از دو جهت مهم است: پیشخوان پویا و افزونه‌های شخص‌ثالث. پیاده‌سازی Trusted Types نیازمند CSP، بازنویسی کد JavaScript و استفاده از پالیسی‌های سفارشی است. چالش‌ها شامل پشتیبانی محدود مرورگرها، سازگاری با کتابخانه‌های قدیمی و پیچیدگی بازنویسی است. اما اگر می‌خواهید امنیت سایت خود را به سطح بعدی ببرید، Trusted Types یکی از مؤثرترین گام‌ها است. اگر سایت شما JavaScript سنگین دارد، همین امروز بررسی کنید.

اگر در پروژه‌ای Trusted Types را پیاده کرده‌اید یا با چالش‌هایی روبه‌رو شده‌اید، تجربه خود را در دیدگاه‌ها بنویسید؛ به‌خصوص اگر کتابخانه یا افزونه خاصی عامل بوده، این اطلاعات برای خواننده بعدی بسیار ارزشمند است.