23 Ağustos 2019 Cuma

SRI - Subresource Integrity


Script ve Link taglarıyla, başka sitelerden Javascript ve Style kaynaklarını yüklemek mümkün.
Üstelik CDN'ler vasıtası ile yaygın olarak kullanılan kütüphaneleri, web sitemize eklediğimizde hatırı sayılır bir performans artışı da sağlayabiliyoruz.
Peki sayfalarımıza dahil ettiğimiz bu kodlar ne kadar güvenli? Ya da güvenliği ilelebet payidar mı?
HTTPS ile bir nebze olsun kendimizi güvende hissedebiliriz. Ama HTTPS teknolojisi yalnızca aktarımdaki güvenliği temin ediyor. Yani X bir hosttan aldığımız dosyalar eğer güvenli protokol ile aktarılıyorsa, bize ulaşana kadar bütünlüğü ve gizliliği korunmuş oluyor.
Peki ya bu kaynakları aldığımız sunucular bir saldırıya uğramış ve yığınla web sitesine servis edilen script ve style dosyaları değiştirilmiş ise?
HTTPS'in bu noktada güvenliğimizi sağlayamayacağı aşikar. Peki bu durumda ne yapabiliriz?
Bu durumda imdadımıza, SRI yani Subresource Integrity özelliği yetişiyor.
Yazının yazıldığı an itibariyle yalnızca Chrome, Firefox ve Opera browserların desteklediği[1], 23 Haziran 2016 itibariyle W3C'nin de tavsiye ettiği SRI sayesinde, farklı kaynaklardan yüklediğimiz script ve style dosyaları ilk günkü kadar temiz :)
Script ve Link taglarına eklenen integrity özelliği ile, harici bir kaynaktan yükleyeceğimiz dosyanın SHA-256, SHA-384, SHA-512 hash değerlerinden birini ya da birkaçını base64 encode olarak belirtiyoruz. Yüklenmek istenen dosyanın hash değeri, bu hashler ile aynı ise dosyalar sitemizin bir parçası olarak yükleniyor, aksi takdirde, yani hash değerleri uyuşmazsa tarayıcı hata vererek bu kaynağın yüklenmesini engelliyor.

Same Origin Policy'i unutmamalı!

Same Origin Policy burada da kendini hissettiriyor. Web Güvenliği'nin merkezinde olan SOP sayesinde biliyoruz ki, farklı bir origin'den script ve style kaynaklarını yükleyerek çalıştırmak mümkün; fakat bu dosyaları satır satır okumak, raw hallerine erişmek SOP tarafından izin verilmeyen bir eylem!
Farklı origin'den yüklenmek istenen bir kaynağın hash'inin hesaplanması için bu kaynağın RAW haline ihtiyaç duyulacak, dolayısı ile SOP'un ihlali demek olan bu eyleme browser izin vermeyecektir!
Peki bir çözümü yok mu? Bu kadar yazıyı boşuna yazmış olmayalım!
Evet var, CORS!
Script ve Link taglarına eklenen crossorigin attribute'ı sayesinde, bu kaynak yüklemesi bir CORS isteği olarak değerlendirlir ve sunucudan eğer Access-Control-Allow-Origin tagı ile birlikte istek yapan URL'e onay veriliir ise, browser tarafından cross domain bir istek olmasına rağmen yanıtın RAW hali okunarak hash'i hesaplanır:
Bu noktada crossorigin özelliğinin alabileceği iki farklı değer mevcut. Bunlardan ilki "anonymous" değeridir, yani istek yapılan kaynağa ait browserda tutulan credentials'lar (Cookie, sertifika, Basic authentication vb.) istekle birlikte gönderilmez.
<script src="http://my2cdn.com/myscript.js" integrity="sha256-0URT8NZXh/hI7oaypQXNjC07bwnLB52GAjvNiCaN7Gc=" crossorigin="anonymous"></script>
Diğeri ise "use-credentials". anonymous'dan farklı olarak, kaynak yükleme isteği ile birlikte, kaynağı host eden siteye ait credentialslar browserda yüklü ise ve server pre-flight isteğe yanıt olarak Access-Control-Allow-Credentials: true döndü ise gönderilir, aksi takdirde istek başarısız kabul edilir ve yapılmaz.

Hash'ler Uyuşmazsa ne olur?

SRI'yi destekleyen bir browser kullandığınız takdirde, script ya da style dosyası yüklenmeyecek ve kullanıcıya uyarı verilecektir. Eğer SRI desteklemeyen bir browser ya da eski bir sürüm browser kullanıyorsanız, script yüklenecektir.

HTTPS hala önemli!

HTTPS hala önemli. Eğer gezindiğimiz sayfalar HTTP üzerinden yükleniyorsa, script ve link taglarındaki integrity attribute'ları kaldırılabilir ya da burada beklenen hash değeri, araya girmiş bir saldırgan tarafından değiştirilebilir.
Peki ya güncellemeler ne olacak?
Eğer yüklediğiniz kaynakları CDN depolarından generik isimlerle örneğin jquery-latest-min.js gibi isimlerle yüklüyorsanız, son güncellemeler ile birlikte (kodun değişmesi ile birlikte) hash değeri de değişecek ve sayfanız bu yeni kaynakları yükleyemeyecektir.
Bunun yerine CDN depolarından kaynakları yüklerken spesifik adlar ile, örneğin versiyon numralarını da içeren isimler ile yüklemek doğru olacaktır:
<script   src="https://code.jquery.com/jquery-2.2.4.min.js"   integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="   crossorigin="anonymous"></script>

Et kokarsa tuzlanır, peki ya tuz kokarsa?

Tüm sitemizi CDN kütüphaneleri üzerine bina ettik, bu kaynakları host eden sitelerin ele geçirilmesi ihtimalini dahi düşünüp, kendi sitemizin güvenliğini sağladık. Güvenlik tamam da peki ya sitemizin işlevselliği? Herhangi bir nedenle yüklediğimiz bu kaynakların bütünlüğü bozulur ve artık bu kaynakların integrity checkleri sağlanmadığı için yükleyemezsek halimiz nice olacak?
Bu tarz durumlara karşı sitemize CDN'ler vasıtası ile yüklediğimiz kütüphanelerin bir kopyalarını da kendi sunucularımızda bulundurarak olası bir durumda, kendi kaynaklarımızdan yüklenmesini sağlayabiliriz. Bunun için aşağıdaki gibi bir kod kullanabiliriz:
<script>window.jQuery || document.write('<script src="local/jquery-X.X.X.min.js"></script>')</script>[2]

[1] http://caniuse.com/#feat=subresource-integrity
[2] http://stackoverflow.com/questions/6115132/loading-jquery-from-google-or-locally-if-not-online

Kaynaklar

https://hacks.mozilla.org/2015/09/subresource-integrity-in-firefox-43/
http://www.srihash.com
https://speakerdeck.com/jdorfman/web-application-security-with-subresource-integrity
https://www.maxcdn.com/one/visual-glossary/subresource-integrity/
https://freedomhacker.net/syrian-electronic-army-hacks-ferrari-forbes-daily-telegraph-independent-intel-and-more-3473/
http://webrazzi.com/2014/11/27/yemeksepeti-suriye-hacker/


0 comentários:

Yorum Gönder