Chrome Geliştirici Araçları'nda İGP ve Trusted Types hata ayıklamasını uygulama

Kateryna Prokopenko
Kateryna Prokopenko
Alfonso Castaño
Alfonso Castaño

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 yapıldı: 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ıklamayla ilgili 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ın kısıtlanmasına 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.

Yeni bir CSP politikası olan Güvenilir Türler(TT) politikası, web sitelerine çok sayıda yerleştirme saldırısını sistematik olarak önleyebilen dinamik analiz yapılmasını sağlamaktadır. TT, bunu başarmak için bir web sitesinin JavaScript kodunu denetlerken innerHTML gibi DOM havuzlarına yalnızca belirli öğelerin atanmasına izin verir.

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 kılınan mod: Her politika ihlalinin bir hata olduğu
  • 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:

  1. Kullanıcı hikayelerini tanımlama. Geliştirici Araçları kullanıcı arabiriminde, bir web geliştiricisinin sorunu nasıl araştırması gerektiğini açıklayan bir dizi kullanıcı hikayesi belirleyin.
  2. Kullanıcı arabirimi uygulaması. Kullanıcı hikayelerine dayanarak, kullanıcı arabiriminde sorunun araştırılması için hangi bilgilerin gerekli olduğunu belirleyin (ör.ilgili bir istek, bir çerezin adı, komut dosyası veya html dosyasındaki bir satır vb.).
  3. Sorun algılama. Tarayıcıda, Chrome'da sorunun algılanabileceği yerleri tanımlayın ve sorunu bildireceğiniz yeri, 2. adımdaki alakalı bilgilerle belirtin.
  4. Sorunları kaydedip görüntüleme Sorunları uygun bir yerde saklayın ve DevTools açıldıktan sonra kullanılabilir hale getirin.
  5. 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ışmalarımıza başlamadan önce, ne yapmamız gerektiğini daha iyi anlamak için kullanıcı hikayeleri içeren bir tasarım dokümanı oluşturduk. Örneğin, şu 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 kaynağın engellenmesi durumunda ilişkili iframe'i ve isteği hızlı bir şekilde bulmayı ve Geliştirici Araçları'nın Öğeler panelindeki HTML öğesine doğrudan bağlantı oluşturmayı da yararlı bulduk.

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:

Aşağıda third_party/blink/public/devtools_protocol/browser_protocol.pdl sayfasından bir alıntı bulunmaktadır.

 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, Geliştirici Araçları ö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 yöneten 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 sunmak istediğimize karar verdikten sonra bu bilgileri Chromium'dan nereden alabileceğimizi 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ı kaydedin ve görüntüleyin

Konsol mesajlarının işlenmesine benzer şekilde, DevTools açılmadan önce oluşan sorunları da bildirmek istememiz küçük bir sorundu. Böylece sorunları doğrudan kullanıcı arabirimine bildirmeziz. Bunun yerine, Geliştirici Araçları'nın açık olup olmamasından bağımsız olarak sorunlarla dolu 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çtaki çalışma tamamlandı ve artık 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:

ALT_TEXT_HERE

Gördüğünüz gibi, özellik ekibini ve DevRel'i dahil etmek, açıklamanın çok daha net ve kesin olmasını sağlar.

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 nesnede varsayılan olarak .valueOf() çağrısından alınmasıdı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ı telefonu 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şlem, 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 istemesi 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ştiren kişinin kendi açıklama oluşturma alanı olabilir
  • Açıklamayı Blink API aracılığıyla 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 bir istisna tetikleyeceğinden, bu özellik bir şekilde yararlı 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. Arka uç (özellikle InspectorDOMDebuggerAgent), her TT ihlali gerçekleştiğinde çağrılacak bir "kontrol" (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 sunulduğundan beri Sorunlar sekmesinde birçok değişiklik yapıldı:

Bundan sonra, daha fazla sorunu göstermek için Sorunlar sekmesini kullanmayı planlıyoruz. Bu sayede, uzun vadede Console'u okunamayan hata mesajı akışından kurtarmış olacağız.

Ö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.