# XSS, CSP ve SOP'da Iframe'ler {{#include ../../banners/hacktricks-training.md}} ## XSS'de Iframe'ler 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) - `data:` protokolünü kullanarak içeriği belirten `src` aracılığıyla - İçeriği belirten `srcdoc` aracılığıyla **Ana ve Çocuk değişkenlerine Erişim** ```html ``` ```html ``` 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. ### CSP ile Iframe'ler > [!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. `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.\ Bu nedenle, bir sayfanın CSP'sini aşmak mümkündür: ```html ``` Not edin ki **önceki CSP yalnızca inline script'in çalışmasına izin veriyor**.\ Ancak, **yalnızca `if1` ve `if2` script'leri çalıştırılacak, fakat yalnızca `if1` ana gizli veriye erişebilecek**. ![](<../../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**. 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 import flask from flask import Flask app = Flask(__name__) @app.route("/") def index(): resp = flask.Response('') resp.headers['Content-Security-Policy'] = "script-src 'self'" resp.headers['Set-Cookie'] = 'secret=THISISMYSECRET' return resp @app.route("/cookie_s.html") def cookie_s(): return "" if __name__ == "__main__": app.run() ``` ### Diğer Yükler doğada bulundu ```html ``` ### Iframe sandbox Iframe içindeki içerik, `sandbox` niteliği kullanılarak ek kısıtlamalara tabi tutulabilir. Varsayılan olarak, bu nitelik uygulanmaz, yani hiçbir kısıtlama yoktur. 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. - 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. - ``, ``, `` 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. 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 ``` ### 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. Bu, iframe'in, ana sayfada yüklenen aynı SOP'deki başka bir iframe'den hassas bilgilere erişmesine olanak tanır: ```javascript window.top[1].document.body.innerHTML = 'Hi from credentialless'; alert(window.top[1].document.cookie); ``` - Exploit ö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): ```html
``` - 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: ```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 ş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. ```javascript var req = new Request("/change_rights",{method:"POST",body:JSON.stringify({username:"victim", rights: "admin"}),credentials:"include"}) const minute = 60000 let arr = [minute, minute * 60, minute * 60 * 24, ...] for (let timeout of arr) fetchLater(req,{activateAfter: timeout}) ``` ## SOP'de Iframe'ler Aşağıdaki sayfaları kontrol edin: {{#ref}} ../postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md {{#endref}} {{#ref}} ../postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md {{#endref}} {{#ref}} ../postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage.md {{#endref}} {{#ref}} ../postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location.md {{#endref}} {{#include ../../banners/hacktricks-training.md}}