چرا بعد از SSL بعضی فایل‌ها با HTTP باز می‌شوند، یکی از پرتکرارترین مشکلاتی است که مدیران سایت‌های وردپرسی پس از فعال‌سازی HTTPS با آن روبرو می‌شوند و می‌تواند تجربه کاربری را به‌طور جدی تحت تأثیر قرار دهد. برخلاف تصور رایج، نصب گواهی SSL و ریدایرکت HTTP به HTTPS، پایان کار نیست؛ آغاز فرآیندی است که در آن باید تمام منابع سایت، از تصاویر و CSS تا JavaScript و iframeها، به‌روزرسانی شوند. اگر بخشی از این منابع همچنان با پروتکل HTTP بارگذاری شوند، پدیده‌ای به‌نام محتوای ترکیبی (Mixed Content) رخ می‌دهد که مرورگرها آن را به‌عنوان خطای امنیتی تلقی می‌کنند و ممکن است قفل امن را از URL حذف کنند. در این مقاله، چارچوبی عملی برای شناسایی و رفع این مشکل ارائه می‌شود.

در پروژه‌های متعدد وردپرسی، دیده‌ام که محتوای ترکیبی، یکی از آن مشکلاتی است که اگر به‌طور کامل رفع نشود، همواره به‌عنوان یک بدهی امنیتی باقی می‌ماند. رفع کامل آن نیازمند رویکردی سیستماتیک است.

محتوای ترکیبی چیست؟

محتوای ترکیبی (Mixed Content) به وضعیتی گفته می‌شود که در آن، صفحه‌ای که با HTTPS بارگذاری می‌شود، بخشی از منابع خود را از طریق HTTP درخواست می‌کند. این پدیده، امنیت صفحه را به‌طور کلی زیر سؤال می‌برد چون مهاجم می‌تواند محتوای HTTP را دستکاری کند.

چرا مرورگرها آن را بلاک می‌کنند؟

مرورگرها دو نوع محتوای ترکیبی را تشخیص می‌دهند:

  • محتوای ترکیبی فعال: منابعی که می‌توانند اجرا شوند یا DOM را تغییر دهند (JavaScript، CSS، iframe، SWF).
  • محتوای ترکیبی غیرفعال: منابعی که تنها نمایش داده می‌شوند (تصاویر، ویدئو، صدا).
«محتوای ترکیبی، نه یک مشکل بصری، بلکه یک شکاف امنیتی است که کل HTTPS را بی‌اثر می‌کند.»

چرا بعد از SSL، فایل‌ها با HTTP باز می‌شوند؟

  1. URLهای قدیمی در دیتابیس: محتوای نوشته‌شده پیش از انتقال، با URLهای HTTP ذخیره شده است.
  2. URLهای Hardcoded در قالب: کد قالب شامل URLهای HTTP است.
  3. افزونه‌های ناسازگار: برخی افزونه‌ها URLها را با HTTP تولید می‌کنند.
  4. Serialized Data: داده‌های سریالایز شده که با جستجوی ساده خراب می‌شوند.
  5. Widgetها و منوها: تنظیمات ذخیره‌شده با URLهای قدیمی.
  6. محتوای Embed: ویدئوها، نقشه‌ها و iframeهایی که با HTTP امبد شده‌اند.
  7. فونت‌های خارجی: منابع بارگذاری‌شده از سرورهای HTTP.
  8. CSS و JS قالب: فایل‌هایی که با پروتکل صریح HTTP بارگذاری می‌شوند.
  9. CDN پیکربندی‌نشده: در صورت پیکربندی نادرست CDN.
  10. محتوای وارد‌شده از منابع خارجی: کپی‌شده از سایت‌های دیگر.

انواع محتوای ترکیبی

نوعنمونهسطح خطر
اسکریپتscript src="http://..."بحرانی
استایلlink href="http://..."بالا
iframeiframe src="http://..."بالا
تصویرimg src="http://..."متوسط
ویدئوvideo src="http://..."متوسط
فونت@font-face src="http://..."متوسط
فرمform action="http://..."بالا
XHR و Fetchدرخواست‌های HTTP از JavaScriptبالا

شناسایی محتوای ترکیبی

ابزارهای مرورگر

  • Chrome DevTools → Console: نمایش خطاهای Mixed Content.
  • Firefox Developer Tools: مشابه Chrome.
  • Network Tab: نمایش تمام درخواست‌ها با پروتکل HTTP.

ابزارهای آنلاین

  • Why No Padlock: شناسایی کامل محتوای ترکیبی.
  • SSL Labs: تحلیل جامع SSL و منابع.
  • Mixed Content Scanner: افزونه مرورگر.
  • JitBit SSL Checker: بررسی سریع.

روش دستی

با View Source و جستجوی 'http://' در کد صفحه:

curl -s https://example.com | grep -o 'http://[^"]*' | sort -u

جستجو و جایگزینی در دیتابیس

اولین و مهم‌ترین گام، به‌روزرسانی URLها در دیتابیس است.

روش WP-CLI (توصیه‌شده)

wp search-replace 'http://example.com' 'https://example.com' --all-tables --precise

مزیت: مدیریت خودکار Serialized Data.

روش افزونه Better Search Replace

  1. نصب افزونه.
  2. ورود به Tools → Better Search Replace.
  3. URL قدیمی: http://example.com
  4. URL جدید: https://example.com
  5. انتخاب همه جدول‌ها.
  6. اجرای Dry Run برای بررسی.
  7. اجرای واقعی.

روش SQL دستی (با احتیاط)

UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://example.com', 'https://example.com');
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, 'http://example.com', 'https://example.com') WHERE meta_value LIKE '%http://example.com%';
UPDATE wp_options SET option_value = REPLACE(option_value, 'http://example.com', 'https://example.com');

نکات مهم

  • هرگز جستجوی صرف 'http://' انجام ندهید؛ URLهای خارجی خراب می‌شوند.
  • همیشه URL کامل با دامنه را جستجو کنید.
  • پیش از اجرا، بکاپ دیتابیس بگیرید.
  • Serialized Data را با احتیاط مدیریت کنید.

Serialized Data و خطر آن

داده‌های سریالایز شده، رشته‌هایی هستند که طول داده در آنها ذخیره شده است. اگر جستجو و جایگزینی ساده انجام شود، طول رشته تغییر می‌کند و داده سریالایز خراب می‌شود.

مثال

a:2:{s:4:"home";s:22:"http://example.com";...}

اگر http:// به https:// تغییر کند، طول از ۲۲ به ۲۳ تغییر می‌کند و مقدار s:22 باید به s:23 تغییر کند.

راهکارها

  • استفاده از WP-CLI با پرچم --precise.
  • استفاده از افزونه‌های تخصصی که Serialized Data را می‌فهمند.
  • پرهیز از کوئری SQL ساده برای جداول حاوی Serialized Data (wp_options، wp_postmeta).
«در Serialized Data، یک کاراکتر اختلاف در طول، کل داده را خراب می‌کند.»

اصلاح در قالب

پس از به‌روزرسانی دیتابیس، باید قالب و فایل‌های آن بررسی شوند.

محل‌های مشکوک در قالب

  • فایل header.php — URLهای فونت و CSS.
  • فایل functions.php — URLهای Hardcoded.
  • فایل‌های CSS — url(http://...) در استایل‌ها.
  • فایل‌های JS — URLهای API خارجی.
  • فایل footer.php — اسکریپت‌های خارجی.

راهکار

  • جستجوی 'http://' در تمام فایل‌های قالب.
  • جایگزینی با URLهای HTTPS یا پروتکل نسبی (//).
  • استفاده از توابع وردپرس: home_url()، site_url()، get_template_directory_uri().

اصلاح در افزونه‌ها

افزونه‌های ناسازگار، می‌توانند URLهای HTTP تولید کنند.

افزونه‌های پرخطر

  • افزونه‌های کش.
  • افزونه‌های SEO که Sitemap با HTTP تولید می‌کنند.
  • افزونه‌های Page Builder.
  • افزونه‌های فرم‌ساز.
  • افزونه‌های ایمیل مارکتینگ.

راهکارها

  • به‌روزرسانی افزونه‌ها به آخرین نسخه.
  • بررسی تنظیمات افزونه‌ها برای URLهای HTTP.
  • پاک‌سازی کش افزونه پس از تغییرات.
  • در صورت لزوم، تماس با پشتیبانی افزونه.

فایل‌های CSS و JavaScript

فایل‌های CSS

در CSS، URLها معمولاً برای تصاویر یا فونت‌ها استفاده می‌شوند:

background: url(http://example.com/image.jpg);

باید جایگزین شوند با:

background: url(https://example.com/image.jpg);

فایل‌های JavaScript

URLها در JS برای API یا اسکریپت‌های خارجی:

fetch('http://api.example.com/data')

راهکار

  • جستجوی http:// در تمام فایل‌های CSS و JS.
  • جایگزینی با HTTPS یا URL نسبی.
  • پاک‌سازی کش CDN و مرورگر پس از تغییرات.

تصاویر و رسانه

تصاویری که با HTTP بارگذاری می‌شوند، نمایش داده می‌شوند اما مرورگر قفل امن را حذف می‌کند.

راهکار

  • جستجو و جایگزینی URLهای تصاویر در دیتابیس.
  • بررسی فایل‌های CSS برای background-image.
  • بررسی تنظیمات افزونه گالری.
  • بررسی تصاویر امبد از سایت‌های دیگر.

iframeها و امبدها

iframeها، یکی از پرتکرارترین منابع محتوای ترکیبی هستند.

منابع رایج

  • ویدئوهای YouTube یا Vimeo.
  • نقشه‌های Google Maps.
  • محتوای Embed از شبکه‌های اجتماعی.
  • فرم‌های امبد از سرویس‌های خارجی.

راهکار

  • استفاده از HTTPS در URL امبد.
  • جایگزینی کد Embed قدیمی با نسخه HTTPS.
  • بررسی خودکار محتوای Embed با اسکریپت.

فونت‌ها و منابع خارجی

فونت‌های بارگذاری‌شده از سرورهای HTTP، منبع دیگری از محتوای ترکیبی هستند.

راهکار

  • استفاده از HTTPS در URL فونت‌ها.
  • Self-Hosting فونت‌ها روی سرور خودی.
  • بررسی تنظیمات Google Fonts.

برای درک عمیق‌تر، مقاله چگونه سایت را برای موبایل بهینه کنیم؟ را مطالعه کنید.

Content Security Policy

CSP یک هدر HTTP است که به مرورگر اعلام می‌کند کدام منابع مجاز به بارگذاری هستند.

هدر پیشنهادی

Content-Security-Policy: upgrade-insecure-requests

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

مزایا

  • رفع خودکار محتوای ترکیبی در مرورگر.
  • بدون نیاز به تغییر کد یا دیتابیس.
  • راهکار موقت یا مکمل.

محدودیت‌ها

  • در همه مرورگرهای قدیمی پشتیبانی نمی‌شود.
  • به‌عنوان راهکار اصلی توصیه نمی‌شود.
  • مشکل ریشه‌ای را حل نمی‌کند.

محتوای ترکیبی در CDN

در صورت استفاده از CDN، تنظیمات نادرست می‌تواند به محتوای ترکیبی منجر شود.

راهکار

  • فعال‌سازی Automatic HTTPS Rewrites در Cloudflare.
  • تنظیم SSL روی Full (Strict).
  • پاک‌سازی کش CDN پس از تغییرات.
  • بررسی URLهای منابع در پنل CDN.

ابزارهای شناسایی و رفع

  • Why No Padlock: شناسایی کامل محتوای ترکیبی.
  • Chrome DevTools: شناسایی زنده.
  • Better Search Replace: رفع در دیتابیس.
  • Really Simple SSL: رفع خودکار پایه.
  • SSL Insecure Content Fixer: رفع محتوای ترکیبی.
  • WP-CLI: رفع در مقیاس بزرگ.

رویکردهای توصیه‌شده

  • بکاپ کامل پیش از هر تغییر.
  • جستجو و جایگزینی URLهای کامل، نه صرف 'http://'.
  • استفاده از WP-CLI برای Serialized Data.
  • بررسی قالب، افزونه و فایل‌های CSS و JS.
  • پاک‌سازی کش چندلایه پس از تغییرات.
  • استفاده از CSP به‌عنوان لایه دفاعی اضافی.
  • پایش مستمر پس از رفع.

اشتباهات رایج

اشتباهاثر عملیاتی
جستجوی صرف 'http://'خرابی URLهای خارجی
نادیده گرفتن Serialized Dataخرابی داده‌ها
نبود بکاپ پیش از تغییراز دست رفتن داده
عدم بررسی قالبمحتوای ترکیبی باقی می‌ماند
نادیده گرفتن iframeهاخطای امنیتی
عدم پاک‌سازی کشمحتوای قدیمی
نبود پایش پس از رفععدم تشخیص باقی‌مانده
اتکا صرف به CSPمشکل ریشه‌ای حل نمی‌شود
نادیده گرفتن CDNمحتوای HTTP از CDN
نبود مستندسازیسردرگمی در آینده

پرسش‌های پرتکرار

محتوای ترکیبی چیست؟

بارگذاری منابع HTTP در صفحه HTTPS که مرورگر آن را به‌عنوان خطای امنیتی تلقی می‌کند.

چگونه محتوای ترکیبی را شناسایی کنم؟

با Chrome DevTools → Console، Why No Padlock یا SSL Labs.

چگونه محتوای ترکیبی را رفع کنم؟

با جستجو و جایگزینی URLهای کامل در دیتابیس، بررسی قالب و افزونه‌ها و پاک‌سازی کش.

Serialized Data چیست و چرا خطرناک است؟

داده‌ای که طول رشته در آن ذخیره شده. جستجوی ساده آن را خراب می‌کند.

چگونه Serialized Data را به‌درستی تغییر دهم؟

با WP-CLI (--precise) یا افزونه‌های تخصصی.

آیا CSP راه‌حل مناسبی است؟

به‌عنوان لایه مکمل مفید است اما جایگزین رفع ریشه‌ای نیست.

آیا محتوای ترکیبی بر سئو اثر دارد؟

بله، از طریق اعتماد کاربر و تجربه امنیتی.

چرا بعد از پاک‌سازی کش، مشکل بازگشت؟

احتمالاً بخشی از منابع هنوز با HTTP در دیتابیس یا قالب باقی مانده است.

پایان‌بندی

رفع محتوای ترکیبی پس از فعال‌سازی SSL، یکی از گام‌های حیاتی در انتقال کامل به HTTPS است که نباید نادیده گرفته شود. با رویکردی سیستماتیک و استفاده از ابزارهای مناسب، می‌توان این مشکل را به‌طور کامل برطرف کرد.

از منظر مهندسی سطح ارشد، سه اصل در رفع محتوای ترکیبی تعیین‌کننده است: جستجو و جایگزینی URLهای کامل (نه صرف پروتکل)، مدیریت دقیق Serialized Data، و بررسی همه لایه‌های سایت (دیتابیس، قالب، افزونه، CDN).

برای درک عمیق‌تر، مقاله راه‌اندازی SSL در وردپرس و انتقال سایت به HTTPS و مقاله رفع مشکل سایت بعد از فعال‌سازی HTTPS را مطالعه کنید.

اگر در پروژه‌های خود تجربه‌ای از رفع محتوای ترکیبی داشته‌اید، تجربه‌تان را در دیدگاه‌ها بنویسید. 🔒