İçeriğe geç
Approvalens

Rehberler · 7 dk okuma

Karışık İçerik (Mixed Content) Hatası: HTTPS Sonrası Çözüm

https:// sayfa neden hâlâ http:// dosya yüklüyor, tarayıcı neyi yükseltir neyi engeller, WordPress'te, CSP ile ya da Cloudflare'de bozmadan nasıl düzeltilir.

Approvalens ekibi

Şu rapor bulgularını düzeltir

  • Karışık içerik
  • http:// sayfalara bağlantılar

SSL sertifikasını kurdun, adres çubuğunda https:// yazıyor, ama bazı görseller yok, bir eklenti yüklenmiyor ya da tarayıcı şikâyet ediyor. Buna karışık içerik (mixed content) deniyor: HTTPS bir sayfanın dosyaları hâlâ düz HTTP üzerinden istemesi. Neredeyse her zaman geçişten önce kaydedilmiş adreslerden geliyor: yazılarda, tema ayarlarında, eklenti seçeneklerinde. Çözüm bu adresleri kaydedildikleri yerde değiştirmek, üstünü örtmek değil.

Karışık içerik nedir?

MDN'in mixed content sayfası (İngilizce) bunu, güvenli yüklenmiş ama kaynaklarını HTTP gibi güvensiz bir protokolle çeken sayfalar olarak tanımlıyor. Risk şu: HTTP ile gelen her şey yolda görülebilir ve bir saldırgan tarafından değiştirilebilir. En tehlikelisi script'ler, çünkü sayfanın her yerini değiştirebilirler.

Tarayıcılar artık sadece uyarmıyor. MDN'e göre tarayıcılar görsel, video ve ses isteklerini HTTP'den HTTPS'ye otomatik yükseltiyor, diğer bütün kaynak türlerindeki güvensiz istekleri ise engelliyor.

Yani iki tür var:

  • Yükseltilebilir. Düz src ile <img>, <audio>, <video>, <source>. Tarayıcı aynı adresi sessizce HTTPS ile dener. Dosya orada varsa yüklenir, yoksa yüklenmez.
  • Engellenebilir. Geri kalan her şey: script'ler, stil dosyaları, iframe'ler, fontlar, fetch() ve XHR çağrıları, srcset ya da <picture> ile yüklenen görseller. Bunlar doğrudan engellenir. Sunucu adı IP adresi olan her şey de engellenir; MDN'in örneğinde http://example.com/image.png yükseltilirken http://93.184.215.14/image.png engelleniyor.

srcset ayrıntısı WordPress sitelerini sürekli yakalıyor. WordPress duyarlı görselleri srcset ile yazıyor; bu yüzden eski bir http:// yükleme bir ekran boyutunda görünüp başka birinde kaybolabiliyor.

AdSense için önemli mi?

AdSense'in siteniz reklam göstermeye hazır değilse sayfası şunu soruyor: "Siteniz tanınmış bir sertifika yetkilisinden (kendinden imzalı sertifika değil) alınmış geçerli bir SSL Sertifikasına sahip mi ve HTTP'yi HTTPS'ye yönlendiriyor mu?" Google karışık içeriği ayrı bir ret sebebi olarak saymıyor. Pratikte inceleyicinin görebileceği bozukluklar olarak çıkıyor: eksik görseller, boş bir gömme alanı, script'i engellendiği için gönderilmeyen bir iletişim formu, kilit simgesinde uyarı. Bunların hiçbiri incelemeye yardım etmez; engellenen script'ler kendi reklam ya da çerez onayı kurulumunu da bozabilir.

Bul: tarayıcı konsolu

Bir sayfa aç, F12 ile DevTools'u aç ve Console sekmesine geç. Chrome her güvensiz istek için iki mesajdan birini yazar. Metinler doğrudan Chromium'un kaynak kodundan ve İngilizce:

Yan yana iki Chrome konsol mesajı. Uyarı, sayfanın HTTPS ile yüklendiğini ama güvensiz bir öğe istediğini ve isteğin otomatik olarak HTTPS'ye yükseltildiğini söylüyor; img src, audio, video ve source için geçerli. Hata, sayfanın güvensiz bir script istediğini ve isteğin engellendiğini söylüyor; script, stil dosyası, iframe, font, fetch, XHR, srcset, picture ve IP adresli sunucular için geçerli. İkisinin de çözümü: adresi kaynağında https yapmak, olmuyorsa dosyayı kendin barındırmak ya da kaldırmak
Sarı uyarı, tarayıcının isteği bu sefer kurtardığı anlamına geliyor. Kırmızı hata, dosyanın hiç yüklenmediği.
  • Yükseltildi: Mixed Content: The page at '…' was loaded over HTTPS, but requested an insecure element '…'. This request was automatically upgraded to HTTPS, For more information see https://blog.chromium.org/2019/10/no-more-mixed-messages-about-https.html
  • Engellendi: Mixed Content: The page at '…' was loaded over HTTPS, but requested an insecure script '…'. This request has been blocked; the content must be served over HTTPS. ("script" kelimesi istenen şeye göre "stylesheet", "frame", "font", "image" gibi değişir.)

web.dev'in karışık içeriği düzeltme rehberi başlamadan önce bilmen gereken bir notu düşüyor: "Karışık içerik hataları ve uyarıları yalnızca şu anda görüntülediğiniz sayfa için gösterilir. JavaScript konsolu, yeni bir sayfaya her gittiğinizde temizlenir." Her sayfa türünden birine bak: ana sayfa, görselli bir yazı, gömme içeren bir sayfa, iletişim sayfası, bir kategori sayfası.

Bul: sayfa kaynağı

Kaynağı görüntüle (Ctrl+U, Mac'te Cmd+Option+U) ve http:// ara. Ya da terminalden birkaç adreste:

curl -s https://ornek.com/bir-yazi/ \
  | grep -oE '(src|srcset|href|data-src)="http://[^"]+"' | sort -u

Her sonuç sorun değil. web.dev'e göre <a> etiketlerinin href özelliğindeki http://, bazı önemli istisnalar dışında genellikle bir karışık içerik sorunu değil. Link tıklanınca yeni bir sayfa açılıyor. İki istisna var: linklenen görseli aynı sayfada açan lightbox script'leri (bu karışık içeriktir) ve kendi sitene http:// ile verilen linkler. Bunlar karışık içerik değil ama her tıklamayı bir yönlendirmeden geçiriyor; onları da değiştir. Fazladan adımın neden önemli olduğunu yönlendirme zinciri rehberi anlatıyor.

CSS dosyalarını unutma. Tema stil dosyasındaki bir background: url(http://…) HTML'de hiç görünmez.

WordPress'te düzelt

1. İki adres ayarını kontrol et

Ayarlar > Genel sayfasında "WordPress Adresi (URL)" ve "Site Adresi (URL)" alanlarının ikisi de https:// ile başlamalı. WordPress'in taşıma belgeleri (İngilizce) iki ayarın da https:// kısmını içermesi ve sonunda eğik çizgi olmaması gerektiğini söylüyor. Alanlar griyse wp-config.php içinde WP_HOME ve WP_SITEURL olarak sabitlenmişlerdir; orada değiştir.

2. Veritabanındaki eski adresleri değiştir

Yazılar, görsel adresleri, bileşen ayarları, sayfa oluşturucu verileri ve tema seçenekleri tam adres saklıyor. Güvenli araç WP-CLI'ın `wp search-replace` komutu; belgesine göre serileştirilmiş PHP verisini akıllıca işliyor. Serileştirilmiş ayarlarda düz bir SQL REPLACE() metin uzunluklarını değiştirip veriyi bozar.

Terminal oturumu: wp db export ile before-https.sql yedeği, ardından guid sütununu atlayan ve deneme modunda çalışan wp search-replace; wp_options option_value'da PHP türünde 4, wp_posts post_content'te 1213, wp_postmeta meta_value'da 87 değişiklik ve Success: 1304 replacements to be made satırı, sonra aynı komutun deneme modu olmadan çalıştırılması
Önce yedek, sonra deneme. Sayılar, komutun beklediğin şeyi yakalayıp yakalamadığını söyler.
wp db export before-https.sql
wp search-replace 'http://ornek.com' 'https://ornek.com' --skip-columns=guid --dry-run
wp search-replace 'http://ornek.com' 'https://ornek.com' --skip-columns=guid

guid neden atlanıyor? WordPress'in belgeleri bu konuda alışılmadık derecede kesin: GUID sütununun içeriği hiçbir koşulda değiştirilmemeli. RSS okuyucular eski yazıyla yeniyi bu alanla ayırıyor.

Siten bir zamanlar www ile çalıştıysa komutu http://www.ornek.com için de çalıştır. Bazı sayfa oluşturucular ve eklentiler WordPress'in kaydetmediği tablolar açıyor; --all-tables-with-prefix onları da kapsar. Belgelerden bir not daha: birincil anahtarı olmayan tablolar atlanıyor.

SSH yok mu? Bazı hosting firmaları cPanel'deki Terminal üzerinden WP-CLI sunuyor; yoksa serileştirilmiş veriyi işlediğini açıkça söyleyen bir ara-değiştir eklentisi kullanabilirsin. İki durumda da önce veritabanını yedekle (cPanel'de phpMyAdmin > Dışa Aktar da olur).

3. Veritabanında olmayanları düzelt

  • http:// sabit yazılmış tema dosyaları (header, footer, functions, CSS).
  • Eski kodla yapıştırılmış üçüncü taraf gömmeler: bir harita ya da video servisinden http:// iframe.
  • Adresleri kendi ayar sayfasından üreten eklentiler.

Sonra bütün önbellekleri temizle: önbellek eklentisi, sunucu önbelleği, CDN önbelleği ve birleştirilmiş ya da küçültülmüş CSS. Yoksa eski adresleri görmeye devam eder, düzeltmenin işe yaramadığını sanırsın.

Dosya HTTPS üzerinden yoksa

web.dev seçenekleri sayıyor: "Mümkünse farklı bir ana makinedeki kaynağı ekleyin", "Yasal olarak izin veriliyorsa içeriği doğrudan sitenize indirip barındırın" ya da "Kaynağı sitenizden tamamen hariç tutun." Test etmek için adres çubuğunda http:// yerine https:// yazıp dosyayı aç.

Güvenlik ağları: CSP ve Cloudflare

Bunlar yardımcı olur ama adresleri düzeltmenin yerini tutmaz.

Content-Security-Policy: upgrade-insecure-requests

Bu başlık tarayıcıya, sayfadaki her http:// kaynak adresini istemeden önce https:// saymasını söylüyor. MDN'in yönerge sayfası bunun, yeniden yazılması gereken çok sayıda eski güvensiz adresi olan siteler için düşünüldüğünü söylüyor.

Content-Security-Policy: upgrade-insecure-requests

Ya da sayfanın <head> bölümünde:

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

MDN'den üç sınır. Kaynak HTTPS'te yoksa istek HTTP'ye geri dönmeden başarısız oluyor. Başka sitelere giden linkler yükseltilmiyor, çünkü bunun bir şeyleri bozma ihtimali çok daha yüksek. Ve yönerge HSTS (Strict-Transport-Security) başlığının yerini tutmuyor. Şu an hangi güvenlik başlıklarını gönderdiğini ücretsiz güvenlik başlıkları kontrolü ile gör; AdSense'i bozmayan bir kurulumu blog için güvenlik başlıkları rehberi anlatıyor.

Bir şeyi zorlamadan önce neyin etkileneceğini görmek istersen, web.dev gerçek ziyaretçilerin tetiklediği her güvensiz istek için sana rapor gönderen bir yalnızca-rapor politikası tarif ediyor:

Content-Security-Policy-Report-Only: default-src https: 'unsafe-inline' 'unsafe-eval'; report-uri https://ornek.com/reportingEndpoint

Cloudflare Automatic HTTPS Rewrites

Cloudflare'de SSL/TLS > Edge Certificates altında Automatic HTTPS Rewrites (İngilizce belge) diye bir anahtar var, her pakette açık. Sitendeki kaynak ve linklerde HTTPS ile sunulabilen adresleri http'den https'ye yeniden yazıyor.

Güvenmeden önce sınırlarını oku. Cloudflare sadece HTTPS'te çalıştığını bildiği adresleri yeniden yazabiliyor; bunun için EFF'nin HTTPS Everywhere verisini ve Chrome'un HSTS ön yükleme listesini kullanıyor. Alan adın bu listelerden hiçbirinde değilse belgeye göre sadece aktif içerik yeniden yazılıyor; görseller gibi pasif içerik yazılmıyor ve karışık içerik hatası vermeye devam ediyor. Sayfa açıldıktan sonra JavaScript'in ürettiği adreslere de hiç dokunulmuyor.

İlgili bir tuzak: Cloudflare'in SSL modu. Flexible modda Cloudflare sunucuna düz HTTP ile bağlanıyor. Cloudflare'in Flexible modu sayfası, karışık içerik hatalarını ya da yönlendirme döngülerini önlemek için ayar yapman gerekebileceğini ve sunucun HTTP'yi HTTPS'ye yönlendiriyorsa Flexible'ın siteyi erişilemez yapan bir yönlendirme döngüsü yarattığını yazıyor. Sunucuya da sertifika kur ve Full (strict) kullan. Hosting panelin (cPanel, Plesk, DirectAdmin) ücretsiz bir sertifika seçeneği sunuyorsa onu kullan; sunmuyorsa firmana sor.

Düzelttikten sonra

  • Aynı sayfa setini konsolda yeniden kontrol et. Ne sarı ne kırmızı.
  • Sertifikanın hem ornek.com hem www.ornek.com adını kapsadığını ücretsiz SSL sertifika kontrolü ile doğrula.
  • Her http:// adresinin tek adımda https:// karşılığına 301 ile yönlendiğinden emin ol.
  • Site haritası ve canonical etiketleri http:// ile üretildiyse onları da güncelle.

Bütün sayfaları tek seferde tara

Ücretsiz Approvalens taraması 50 sayfaya kadar gezer, http:// üzerinden dosya yükleyen ve hâlâ http:// adreslere link veren sayfaları listeler: siteni tara.

Sık sorulan sorular

Görseller neden sadece bazı ekran boyutlarında kayboluyor?

WordPress duyarlı görselleri srcset ile sunuyor ve MDN srcseti engellenebilir durumlar arasında sayıyor. Düz src yükseltiliyor, srcset adayları engelleniyor; gördüğün şey tarayıcının hangi boyutu seçtiğine bağlı.

"Really Simple SSL" türü bir eklenti yetmez mi?

Çıktıda adres yeniden yazan eklentiler sorunu düzeltmiyor, gizliyor; yeniden yazma da her sayfa gösteriminde çalışıyor. Geçici çözüm olarak makul. Fırsat bulunca veritabanı değişikliğini yap ve bu bağımlılıktan kurtul.

//ornek.com/resim.jpg gibi protokolsüz adresler kullanayım mı?

Artık gerek yok. Siten sadece HTTPS ise https:// yaz ya da kendi dosyaların için köke göre yol kullan (/wp-content/uploads/…).

Konsol temiz ama kilitte hâlâ uyarı var. Başka ne olabilir?

Sertifikanın kendisine bak (bitiş tarihi, alan adları, ara sertifika zinciri), http:// adrese gönderilen formlara ve geçişten önce önbelleğe alınmış sayfalara. Sertifika sorunlarını SSL sertifikası süresi doldu rehberi anlatıyor.

Eskimiş ya da yanlış bir şey mi gördün? Bize yaz, düzeltelim.

Bu rehberi İngilizce oku →

Kendi sitende kontrol et. Ücretsiz, kayıt yok.

Bunun için ücretsiz araçlar

Ücretsiz tarama

Kendi siteni kontrol et

Ücretsiz tarama ilk 50 sayfayı okur; puanını ve bulduğu tüm sorunları gösterir.

İlk 50 sayfa ücretsiz · üyelik yok · kart gerekmez

Tüm rehberler