Bu blog yayını, yakın zamanda kullanıma sunulan Sorunlar sekmesinin yardımıyla İçerik Güvenliği Politikası (İGP) sorunlarında hata ayıklama için DevTools desteğinin uygulanmasıyla ilgilidir.
Uygulama çalışmaları 2 staj sırasında gerçekleştirildi: 1. İlkinde genel raporlama çerçevesini oluşturduk ve 3 CSP ihlali sorunu için sorun mesajlarını tasarladık. 2. İkinci sürümde, Güvenilir Tür hata ayıklama için bazı özel DevTools özelliklerinin yanı sıra Güvenilir Tür sorunları da ekledik.
İçerik Güvenliği Politikası nedir?
İçerik Güvenliği Politikası (İGP), güvenliği artırmak için web sitesindeki belirli davranışları kısıtlamaya olanak tanır. Örneğin, satır içi komut dosyalarına veya eval
öğesine izin vermemek için CSP kullanılabilir. Bu iki seçenek de Siteler Arası Komut Dosyası Çalıştırma (XSS) saldırılarının saldırı yüzeyini azaltır. CSP ile ilgili ayrıntılı bir giriş için burayı okuyun.
Özellikle yeni bir CSP olan Trusted Types(TT) politikası, web sitelerinde büyük bir sınıfa ait yerleştirme saldırılarını sistematik olarak önleyebilen dinamik bir analiz sağlar. TT, bu amaca ulaşmak için web sitelerinin JavaScript kodlarını denetleyerek yalnızca belirli türde öğelerin innerHTML gibi DOM alıcılarına atanmasına izin vermesini sağlar.
Web siteleri, belirli bir HTTP üst bilgisi ekleyerek içerik güvenliği politikasını etkinleştirebilir. Örneğin, content-security-policy: require-trusted-types-for 'script'; trusted-types default
başlığı bir sayfa için TT politikasını etkinleştirir.
Her politika aşağıdaki modlardan birinde çalışabilir:
- Zorunlu mod: Her politika ihlalinin hata olarak değerlendirildiği moddur.
- Yalnızca raporlama modu: Hata mesajını uyarı olarak bildirir ancak web sayfasında hataya neden olmaz.
Sorunlar sekmesinde İçerik Güvenliği Politikası sorunlarını uygulama
Bu çalışmanın amacı, CSP sorunları için hata ayıklama deneyimini iyileştirmekti. Geliştirici Araçları ekibi, yeni sorunları değerlendirirken kabaca şu süreci uygular:
- Kullanıcı hikayelerini tanımlama. Geliştirici Araçları ön ucunda, bir web geliştiricisinin sorunu nasıl incelemesi gerektiğini kapsayan bir dizi kullanıcı hikayesi belirleyin.
- Kullanıcı arabirimi uygulaması. Kullanıcı hikayelerine göre, sorunun ön uçta incelenmesi için hangi bilgi parçalarının gerekli olduğunu belirleyin (ör.ilgili istek, çerezin adı, komut dosyası veya html dosyasındaki bir satır vb.).
- Sorun algılama. Chrome'da sorunun tarayıcıda tespit edilebileceği yerleri belirleyin ve (2) numaralı adımdaki ilgili bilgileri de dahil ederek sorunu bildirmek için yeri donanımlandırın.
- Sorunları kaydedip görüntüleme Sorunları uygun bir yerde saklayın ve DevTools açıldıktan sonra kullanılabilir hale getirin.
- Sorun metnini tasarlama. Web geliştiricisinin sorunu anlamasına ve daha da önemlisi düzeltmesine yardımcı olacak açıklayıcı bir metin oluşturun.
1. adım: CSP sorunları için kullanıcı hikayelerini tanımlama
Uygulama çalışmamıza başlamadan önce, yapmamız gerekenleri daha iyi anlamak için kullanıcı hikayeleri içeren bir tasarım dokümanı oluşturduk. Örneğin, aşağıdaki kullanıcı hikayesini yazdık:
Web sitemin bir kısmının engellendiğini fark eden bir geliştirici olarak şunu yapmak istiyorum:- - ...CSP'nin web sitemdeki engellenen iframe'lerin / resimlerin nedeni olup olmadığını öğrenmek istiyorum - ...Belirli bir kaynağın engellenmesine hangi CSP yönergesinin neden olduğunu öğrenmek istiyorum - ...Şu anda engellenen kaynakların gösterilmesine / şu anda engellenen js'nin yürütülmesine izin vermek için web sitemin CSP'sini nasıl değiştireceğimi öğrenmek istiyorum.
Bu kullanıcı hikayesini keşfetmek için ilgilendiğimiz CSP ihlallerini gösteren bazı basit örnek web sayfaları oluşturduk ve sürece aşina olmak için örnek sayfaları inceledik. Örnek web sayfalarından bazıları aşağıda verilmiştir (demoyu Sorunlar sekmesi açıkken açın):
Bu süreci kullanarak, CSP sorunlarını ayıklamak için en önemli bilginin kaynak konum olduğunu öğrendik. Ayrıca, bir kaynak engellendiğinde ilişkili iframe'i ve isteği hızlı bir şekilde bulmanın ve DevTools'un Öğeler panelindeki HTML öğesine doğrudan bağlantı oluşturmanın da yararlı olabileceğini tespit ettik.
2. adım: ön uç uygulama
Bu analizleri, Chrome Geliştirici Araçları Protokolü (CDP) aracılığıyla DevTools'a sunmak istediğimiz bilgilerin ilk taslağı haline getirdik:
third_party/blink/public/devtools_protocol/browser_protocol.pdl dosyasından alınan alıntı aşağıda verilmiştir.
type ContentSecurityPolicyIssueDetails extends object
properties
# The url not included in allowed sources.
optional string blockedURL
# Specific directive that is violated, causing the CSP issue.
string violatedDirective
boolean isReportOnly
ContentSecurityPolicyViolationType contentSecurityPolicyViolationType
optional AffectedFrame frameAncestor
optional SourceCodeLocation sourceCodeLocation
optional DOM.BackendNodeId violatingNodeId
Yukarıdaki tanım temel olarak bir JSON veri yapısını kodlar. PDL (protokol veri dili) adlı basit bir dilde yazılmıştır. PDL iki amaç için kullanılır. Öncelikle, DevTools ön ucunun kullandığı TypeScript tanımlarını oluşturmak için PDL'yi kullanırız. Örneğin, yukarıdaki PDL tanımı aşağıdaki TypeScript arayüzünü oluşturur:
export interface ContentSecurityPolicyIssueDetails {
/**
* The url not included in allowed sources.
*/
blockedURL?: string;
/**
* Specific directive that is violated, causing the CSP issue.
*/
violatedDirective: string;
isReportOnly: boolean;
contentSecurityPolicyViolationType: ContentSecurityPolicyViolationType;
frameAncestor?: AffectedFrame;
sourceCodeLocation?: SourceCodeLocation;
violatingNodeId?: DOM.BackendNodeId;
}
İkincisi ve muhtemelen daha da önemlisi, bu veri yapılarını C++ Chromium arka ucundan DevTools ön ucuna oluşturma ve gönderme işlemlerini yapan tanımdan bir C++ kitaplığı oluştururuz. Bu kitaplık kullanılarak aşağıdaki C++ kodu parçasıyla bir ContentSecurityPolicyIssueDetails
nesnesi oluşturulabilir:
protocol::Audits::ContentSecurityPolicyIssueDetails::create()
.setViolatedDirective(d->violated_directive)
.setIsReportOnly(d->is_report_only)
.setContentSecurityPolicyViolationType(BuildViolationType(
d->content_security_policy_violation_type)))
.build();
Hangi bilgileri paylaşmak istediğimize karar verdikten sonra, bu bilgileri Chromium'dan nereden alacağımızı araştırmamız gerekiyordu.
3. Adım: Sorun algılama
Bilgileri, son bölümde açıklanan biçimde Chrome DevTools Protokolü'ne (CDP) sunmak için bilgilerin arka uçta gerçekten bulunduğu yeri bulmamız gerekiyordu. Neyse ki CSP kodunda, yalnızca raporlama modu için kullanılan ve bağlantı kurabileceğimiz bir darboğaz zaten vardı: ContentSecurityPolicy::ReportViolation
, sorunları CSP HTTP başlığında yapılandırılabilir bir (isteğe bağlı) raporlama uç noktasına bildirir. Bildirmek istediğimiz bilgilerin çoğu zaten mevcuttu. Bu nedenle, araçlarımızın çalışması için arka uçta büyük bir değişiklik yapılması gerekmedi.
4. adım: Sorunları kaydedip görüntüleyin
Konsol mesajlarının ele alınmasına benzer şekilde, DevTools açılmadan önce oluşan sorunları da bildirmek istememiz küçük bir komplikasyondu. Yani sorunları doğrudan kullanıcı arayüzüne bildirmeyiz. Bunun yerine, DevTools'un açık olup olmadığından bağımsız olarak sorunlarla doldurulan bir depolama alanı kullanırız. DevTools açıldığında (veya bu bağlamda başka bir CDP istemcisi bağlandığında) daha önce kaydedilen tüm sorunlar depolama alanından yeniden oynatılabilir.
Arka uç çalışmaları tamamlandıktan sonra, sorunun ön uçta nasıl gösterileceğine odaklanmamız gerekiyordu.
5. Adım: Sorun metnini tasarlama
Sorun metinlerinin tasarlanması, kendi ekibimizin yanı sıra birkaç ekibin de dahil olduğu bir süreçtir. Örneğin, genellikle bir özelliği uygulayan ekibin (bu durumda CSP ekibi) ve tabii ki web geliştiricilerin belirli bir sorun türüyle nasıl başa çıkacağını tasarlayan DevRel ekibinin bilgilerinden yararlanırız. Sorun metni genellikle tamamlanana kadar bazı iyileştirmelerden geçer.
DevTools ekibi genellikle hayal ettiklerinin kaba bir taslağıyla başlar:
## Header
Content Security Policy: include all sources of your resources in content security policy header to improve the functioning of your site
## General information
Even though some sources are included in the content security policy header, some resources accessed by your site like images, stylesheets or scripts originate from sources not included in content security policy directives.
Usage of content from not included sources is restricted to strengthen the security of your entire site.
## Specific information
### VIOLATED DIRECTIVES
`img-src 'self'`
### BLOCKED URLs
https://imgur.com/JuXCo1p.jpg
## Specific information
https://web.dev/strict-csp/
Yineleme sonrasında şu sonuca vardık:
Gördüğünüz gibi, özellik ekibini ve DevRel'i dahil etmek açıklamayı çok daha net ve kesin hale getiriyor.
Sayfanızdaki CSP sorunlarını özellikle CSP ihlallerine ayrılmış sekmede de bulabilirsiniz.
Trusted Types sorunlarında hata ayıklama
Doğru geliştirici araçları olmadan TT ile büyük ölçekte çalışmak zor olabilir.
Geliştirilmiş konsol baskısı
Güvenilir nesnelerle çalışırken, güvenilir olmayan karşıtıyla en az aynı miktarda bilgi göstermek isteriz. Maalesef şu anda Güvenilir Nesne gösterilirken sarmalanmış nesne hakkında hiçbir bilgi gösterilmiyor.
Bunun nedeni, konsolda görüntülenen değerin varsayılan olarak nesnede .valueOf()
çağrılmasından kaynaklanır. Ancak Güvenilir Tür söz konusu olduğunda döndürülen değer çok yararlı değildir. Bunun yerine, .toString()
numaralı telefondan aradığınızda gördüğünüz bir sayfaya yönlendirilmek istiyoruz. Bunu başarmak için V8 ve Blink'i, güvenilir tür nesneleri için özel işlemler sunacak şekilde değiştirmemiz gerekiyor.
Bu özel işleme, geçmiş nedenlerden dolayı V8'de yapılmış olsa da bu yaklaşımın önemli dezavantajları vardır. Özel görüntüleme gerektiren ancak JS düzeyinde türü aynı olan birçok nesne vardır. V8 saf JS olduğundan, Güvenilir Tür gibi bir Web API'ye karşılık gelen kavramları ayırt edemez. Bu nedenle, V8'in bunları ayırt etmek için yerleştiricisinden (Blink) yardım alması gerekir.
Bu nedenle, kodun bu bölümünü Blink'e veya herhangi bir yerleştiriciye taşımak mantıklı bir seçim gibi görünüyor. Bu sorunun yanı sıra, bu yöntemin birçok avantajı vardır:
- Her yerleşimcinin kendi açıklama oluşturma yöntemi olabilir.
- Açıklamayı Blink API üzerinden oluşturmak çok daha kolaydır.
- Blink, nesnenin orijinal tanımına erişebilir. Bu nedenle, açıklamayı oluşturmak için
.toString()
kullanırsak.toString()
'ün yeniden tanımlanma riski yoktur.
İhlalde durma (yalnızca rapor modunda)
Şu anda TT ihlallerini hata ayıklamanın tek yolu JS istisnalarında kesme noktaları ayarlamaktır. Zorunlu TT ihlalleri istisna tetikleyeceğinden bu özellik bir şekilde faydalı olabilir. Ancak gerçek yaşam senaryolarında, TT ihlalleri üzerinde daha ayrıntılı bir kontrole ihtiyacınız vardır. Özellikle, yalnızca TT ihlallerinde (diğer istisnalar değil) ara vermek, yalnızca rapor modunda da ara vermek ve farklı TT ihlali türlerini ayırt etmek istiyoruz.
DevTools zaten çok çeşitli kesme noktalarını desteklediğinden mimari oldukça genişletilebilir. Yeni bir kesme noktası türü eklemek için arka uçta (Blink), CDP'de ve ön uçta değişiklikler yapılması gerekir.
Yeni bir CDP komutu tanıtmalıyız. Buna setBreakOnTTViolation
adını verelim. Bu komut, arka uçta hangi tür TT ihlallerinin kaldırılması gerektiğini belirtmek için ön uç tarafından kullanılır. Özellikle InspectorDOMDebuggerAgent
olan arka uç, her TT ihlali gerçekleştiğinde çağrılacak bir "prob" (onTTViolation()
) sağlar. Ardından InspectorDOMDebuggerAgent
, bu ihlalin bir kesme noktasını tetikleyip tetiklemeyeceğini kontrol eder ve tetiklemesi gerekiyorsa yürütmeyi duraklatmak için kullanıcı arayüzüne bir mesaj gönderir.
Ne yapıldı ve sırada ne var?
Burada açıklanan sorunlar kullanıma sunulduktan sonra Sorunlar sekmesinde birçok değişiklik yapıldı:
- DevTools'daki diğer panellerle bağlantısı iyileştirildi.
- Düşük kontrast, güvenilir web etkinliği, quirks modu, ilişkilendirme raporlama API'si ve CORS ile ilgili sorunlar gibi diğer sorunların raporlanması Sorunlar sekmesine taşındı.
- Sorunları gizleme seçeneği kullanıma sunuldu
Bundan sonra, daha fazla sorunu göstermek için Sorunlar sekmesini kullanmayı planlıyoruz. Bu sayede, uzun vadede Console'da okunamayan hata mesajı akışı kaldırılabilir.
Önizleme kanallarını indirme
Varsayılan geliştirme tarayıcınız olarak Chrome Canary, Yeni geliştirilenler veya Beta sürümünü kullanabilirsiniz. Bu önizleme kanalları, en son DevTools özelliklerine erişmenizi sağlar, en yeni web platformu API'lerini test etmenize olanak tanır ve sitenizdeki sorunları kullanıcılarınızdan önce bulmanıza yardımcı olur.
Chrome Geliştirici Araçları Ekibi ile iletişime geçme
Yeni özellikler, güncellemeler veya Geliştirici Araçları ile ilgili başka herhangi bir konu hakkında konuşmak için aşağıdaki seçenekleri kullanın.
- crbug.com adresinden bize geri bildirim ve özellik isteği gönderin.
- Geliştirici Araçları'nda Diğer seçenekler > Yardım > Geliştirici Araçları sorunu bildir'i kullanarak bir Geliştirici Araçları sorununu bildirin.
- @ChromeDevTools hesabına tweet gönderin.
- Geliştirici Araçları'ndaki yenilikler veya Geliştirici Araçları'yla ilgili ipuçları konulu YouTube videolarına yorum bırakın.