# Kevert tartalom

> A teszt azt nézi, tölt-e be az https-en érkező oldal erőforrást http:// címről; írd át a címeket https-re.

Kevert tartalomról akkor beszélünk, ha az oldal maga `https://`-en érkezik, de egyes részeit (képet, szkriptet, stíluslapot) titkosítatlan `http://` címről tölti be. Az MDN szerint a böngészők a kevert tartalmat két csoportra osztják: a „frissíthető” tartalmat (például képek, videók) automatikusan `https`-re cserélik, a „blokkolandót” (például szkriptek) pedig letiltják. Ezért hiányozhat egy kép vagy egy szkript, és az oldal egy része nem működik.

A web.dev megkülönbözteti a passzív (kép, videó, hang) és az aktív kevert tartalmat (szkript, stíluslap, iframe). Az aktív tartalomra irányuló támadással a támadó szinte bármit megtehet az oldalon.

## Hogyan mérjük

Ez a teszt böngészős: a riport egy valódi, fej nélküli böngészőben (Lighthouse, mobil emulációval) betölti az oldalt, és a Lighthouse `is-on-https` ellenőrzésének találatait nézi. Ez a Chrome dokumentációja szerint azt jelzi, ha az oldal https-en érkezik, de védtelen (HTTP) erőforrást kér. A riport azokat a találatokat számolja, amelyek `http:` címűek, legfeljebb 20-ig.

| Eredmény | Mikor |
|---|---|
| Megfelelő | nincs `http://` című erőforrás (0 darab) |
| Hiba | legalább egy erőforrás `http://` címről töltődik be (a riport a darabszámot és legfeljebb 10 címet mutatja) |
| Nem értékelhető | a végső oldal nem `https://` (akkor kevert tartalomról nincs értelme beszélni) |

Amit a teszt nem csinál:

- Csak a kezdőoldalt tölti be, az aloldalakat nem.
- A darabszám legfeljebb 20: ha a riport 20-at mutat, az „húsz vagy több”.
- Amit az oldal csak interakcióra (kattintás, görgetés, űrlap) tölt be, azt nem biztos, hogy látja.

## Hogyan javítsd

A cél az, hogy minden erőforrás `https://` címről jöjjön. A riport által kiírt `http://` címeket keresd meg a forrásban, és írd át.

1. Nézd meg a riportban a mutatott `http://` címeket. Az azonos domain alatti címek általában a saját tartalmadban vannak (régi bejegyzések, a téma, bővítmények), a külső címek harmadik fél beágyazásai.
2. Írd át a címeket `https://`-re. Külső erőforrásnál ellenőrizd, hogy a szolgáltató elérhetővé teszi-e https-en. Az MDN figyelmeztet: ha a kért erőforrás nem érhető el https-en, a kérés sikertelen lesz, nem esik vissza http-re.
3. Ha sok a hibás cím, használd az alábbi platformonkénti megoldásokat. Az `upgrade-insecure-requests` és a Cloudflare átírása a hibás címek javítása nélkül is segít, de a forrás javítása a tartós megoldás.

### HTML

```html title="HTML"
<!-- Hibás -->
<img src="http://pelda.hu/kep.webp" alt="Kép">

<!-- Helyes -->
<img src="https://pelda.hu/kep.webp" alt="Kép">
```

### WordPress

A hibás címek jellemzően az adatbázisban vannak (bejegyzések, beállítások). A WP-CLI `search-replace` parancsa kicseréli őket. A kódrészlet az adatbázist a home-mappádba menti (ne a WordPress mappájába, mert onnan letölthető), utána csak megmutatja, mi változna (`--dry-run`):

```bash title="Terminál"
(umask 077; wp db export ~/before-update-mixed-content.sql) &&
wp search-replace 'http://pelda.hu' 'https://pelda.hu' --skip-columns=guid --dry-run &&
wp search-replace 'http://www.pelda.hu' 'https://pelda.hu' --skip-columns=guid --dry-run
```

Cseréld a `pelda.hu` helyére a saját domainedet (és a fő címnek megfelelően a `www`-t). A `--skip-columns=guid` a `guid` oszlopot hagyja ki; a WP-CLI dokumentációja is ezt mutatja a kapcsoló példájaként. Ha a lista rendben van, futtasd le ugyanezeket a parancsokat `--dry-run` nélkül:

```bash title="Terminál"
wp search-replace 'http://pelda.hu' 'https://pelda.hu' --skip-columns=guid
wp search-replace 'http://www.pelda.hu' 'https://pelda.hu' --skip-columns=guid
```

A mentést ellenőrzés után töröld. Ellenőrizd a WordPress beállításaiban is (Beállítások, Általános), hogy a WordPress- és a webhelycím `https://`-sel kezdődik. A téma és a bővítmények fájljaiban beégetett `http://` címeket a fájlokban kell javítani (Bedrocknál is ugyanez a parancs fut, a WordPress mappájából).

### nginx

A böngészőt az `upgrade-insecure-requests` CSP-direktíva utasítja, hogy az oldal minden `http://` címét `https://`-ként kezelje. Az MDN szerint ennek a kérések a hálózatra sem jutnak ki titkosítatlanul. A server blokkba:

```nginx title="nginx"
add_header Content-Security-Policy "upgrade-insecure-requests" always;
```

Ha a [Content-Security-Policy](https://hub.hellowp.io/hu/report/biztonsag/content-security-policy/) kártyáját is megcsinálod, ezt utána add hozzá: az MDN szerint a CSP-mechanizmus több szabályt is megenged egy erőforráshoz, és a böngésző mindegyiket betartja. Ha egy location blokkban is van `add_header`, oda is kell, mert az nginx csak akkor örököl, ha az adott szinten nincs `add_header`.

### Apache (.htaccess)

```apache title=".htaccess"
<IfModule mod_headers.c>
    Header always append Content-Security-Policy "upgrade-insecure-requests"
</IfModule>
```

### Cloudflare

Cloudflare: SSL/TLS, Edge Certificates, **Automatic HTTPS Rewrites: On**. A Cloudflare dokumentációja szerint ez az oldalad azon erőforrásait és hivatkozásait írja át `http`-ről `https`-re, amelyek https-en is kiszolgálhatók.

Ha a CSP-direktívát is a Cloudflare-rel adnád hozzá, használd az **Add static** műveletet (nem a **Set static**-ot), különben felülírnád a meglévő azonos nevű fejlécet. Cloudflare: Rules, Overview, Create rule, Response Header Transform Rule:

```text title="Cloudflare"
Add static: Content-Security-Policy = upgrade-insecure-requests
```

## Hogyan ellenőrizd

Futtasd újra a riportot. Gyors első ellenőrzés a kiszolgált HTML-ben (ez csak a HTML forrásában lévő címeket találja meg, a szkript vagy a stíluslap által később betöltöttet nem):

```bash title="Terminál"
curl -s "https://pelda.hu/?v=1" | grep -oE 'http://[^"'"'"' )]+' | sort -u
```

Ha a parancs nem ír ki semmit, a HTML-ben nincs `http://` cím.
