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ı, yeni kullanıma sunulan Sorunlar sekmesinin yardımıyla İçerik Güvenliği Politikası (İGP) sorunlarını ayıklamaya yönelik Geliştirici Araçları desteğinin uygulanması hakkındadır.

Uygulama çalışmaları 2 staj sırasında yapıldı: 1. İlk adımda, genel raporlama çerçevesini oluşturduk ve sorun mesajlarını 3 İGP ihlali sorunu için tasarladık. 2. İkinci adımda, Güvenilir Türler hata ayıklaması için bazı özel Geliştirici Araçları özelliklerinin yanı sıra Güvenilir Tür sorunlarını 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, CSP, satır içi komut dosyalarına veya eval'e izin vermemek için kullanılabilir. Bu iki seçenek de Siteler Arası Komut Dosyası Çalıştırma (XSS) saldırılarına yönelik saldırı yüzeyini azaltır. CSP hakkında ayrıntılı bir tanıtım 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 sitesi, 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. Bir sayfanın TT politikasını etkinleştirir.

Her politika şu modlardan birinde çalışabilir:

  • zorunlu kılınan mod: Her politika ihlalinin bir hata olduğu
  • salt rapor 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ı, İGP sorunları için hata ayıklama deneyimini iyileştirmekti. Geliştirici Araçları ekibi, yeni sorunları değerlendirirken kabaca şu süreci izler:

  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 belirleyin ve sorunu bildireceğiniz yeri, 2. adımdaki alakalı bilgilerle birlikte kullanın.
  4. Sorunları kaydedin ve görüntüleyin. Sorunları uygun bir yerde depolayın ve açıldığında Geliştirici Araçları'nın kullanımına sunun.
  5. Sorunlar metnini tasarlama. Web geliştiricisinin sorunu anlamasına ve daha da önemlisi sorunu düzeltmesine yardımcı olacak açıklayıcı bir metin bulun

1. Adım: İGP 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, aşağıdaki kullanıcı hikayesini yazdık:


Web sitemin bir kısmının engellendiğini yeni fark eden bir geliştirici olarak şunları yapmak istiyorum: - ...Web sitemdeki iFrame'lerin / resimlerin engellenmesinin İGP'den kaynaklanıp kaynaklanmadığını öğrenmek - ...hangi CSP yönergesinin belirli bir kaynağın engellenmesine neden olduğunu öğrenin - ...şu anda engellenmiş olan kaynakların görüntülenmesine / şu anda engellenmiş olan js'nin yürütülmesine izin vermek için web sitemin İGP'sini nasıl değiştireceğimi bilmek.


Bu kullanıcı hikayesini araştırmak için, ilgilendiğimiz İGP ihlallerini gösteren birkaç basit örnek web sayfası oluşturduk ve süreci daha iyi tanımak için örnek sayfaları inceledik. Örnek web sayfalarından bazıları aşağıda verilmiştir (Sorunlar sekmesi açıkken demoyu açın):

Bu işlemi kullanarak kaynak konumunun, CSP sorunlarında hata ayıklamak için en önemli bilgi parçası 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 Elements panelinde HTML öğesine doğrudan bir bağlantının da faydalı olabileceğini bulduk.

2. Adım: Kullanıcı arabirimi uygulaması

Bu analizi, Chrome Geliştirici Araçları Protokolü (CDP) aracılığıyla Geliştirici Araçları'na sunmak istediğimiz bilgilerin ilk taslağına dönüştürdük:

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, temelde bir JSON veri yapısını kodlar. Belge, PDL (protokol verileri dili) adı verilen basit bir dilde yazılmıştır. PDL iki amaçla kullanılır. İlk olarak, DevTools kullanıcı arabiriminin 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;
}

İkinci olarak, muhtemelen daha da önemlisi, bu veri yapılarını oluşturma ve C++ Chromium arka ucundan Geliştirici Araçları kullanıcı arabirimine gönderme işlemini işleyen tanımdan bir C++ kitaplığı oluştururuz. Bu kitaplık kullanılarak aşağıdaki C++ kodu parçası kullanılarak 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, Chrome Geliştirici Araçları Protokolü (CDP) tarafından son bölümde açıklanan biçimde sunmak için arka uçta bilgilerin gerçekten bulunduğu yeri bulmamız gerekiyordu. Neyse ki CSP kodunda yalnızca raporlama modu için kullanılan bir performans sorunu halihazırda bulunuyor. Bu sorunu çözmek için şu noktalardan yararlanabiliriz: ContentSecurityPolicy::ReportViolation, sorunları CSP HTTP başlığında yapılandırılabilen (isteğe bağlı) bir raporlama uç noktasına bildirir. Bildirmek istediğimiz bilgilerin çoğu zaten mevcuttu. Bu yüzden, araçlarımızın çalışması için arka uçta büyük bir değişiklik yapılması gerekmiyordu.

4. Adım: Sorunları kaydedin ve görüntüleyin

Konsol mesajlarının işlenme şekline benzer şekilde, Geliştirici Araçları açılmadan önce ortaya çıkan sorunları da bildirmek istedik. 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. Geliştirici Araçları açıldığında (veya başka bir CDP istemcisi eklendiğinde) önceden kaydedilen tüm sorunlar depolama alanından tekrar oynatılabilir.

Böylece arka uç çalışması sona erdi ve artık kullanıcı arabiriminde sorunu nasıl ortaya çıkaracağımıza odaklanmamız gerekiyordu.

5. Adım: Sorunlar metnini tasarlama

Sorun metnini tasarlamak bizim dışımızda birkaç ekibin dahil olduğu bir süreçtir. Örneğin, çoğu zaman bir özelliği uygulayan ekibin (bu durumda İGP ekibidir) ve elbette web geliştiricilerinin belirli bir sorunla nasıl başa çıkmaları gerektiğini tasarlayan DevRel ekibinin analizlerine güveniriz. Sorun metni genellikle bitene kadar biraz ayrıntılandırmadan geçer.

Geliştirici Araçları ekibi genellikle şu hayallerinin 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/

Yinelemeden sonra şu noktaya vardık:

ALT_TEXT_HERE

Gördüğünüz gibi, özellik ekibini ve DevRel'i sürece dahil etmek açıklamayı çok daha net ve net hale getiriyor.

Sayfanızdaki CSP sorunları, özel olarak CSP ihlallerine ayrılmış sekmede de keşfedilebilir.

Güvenilir Türler ile ilgili sorunları ayıklama

Doğru geliştirici araçları olmadan TT ile büyük ölçekte çalışmak zor olabilir.

İyileştirilmiş konsol yazdırma

Güvenilir Nesneler ile çalışırken, güvenilmeyen karşılığı ile en az aynı miktarda bilgi görüntülemek isteriz. Maalesef şu anda bir Güvenilir Nesne görüntülenirken sarmalanmış nesne hakkında bilgi görüntülenmemektedir.

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 pek kullanışlı değildir. Bunun yerine, .toString() numaralı telefonu aradığınızda alacağınıza benzer bir istem kullanmak istiyoruz. Bunu başarmak amacıyla V8 ve Blink'i değiştirerek güvenilir türdeki nesneler için özel bir işlemeyi kullanıma sunmamız gerekir.

Geçmişteki nedenlerden dolayı bu özel işlemenin V8'de yapılmış olması nedeniyle, bu yaklaşımın önemli dezavantajları vardır. Özel görüntüleme gerektiren ancak türü JS düzeyinde aynı olan birçok nesne vardır. V8 tamamen JS olduğundan, Güvenilir Tür gibi bir Web API'sine 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ü Yanıp Söndürme veya herhangi bir yerleştiriciye taşımak mantıklı bir seçim gibidir. Açıklanan sorunun dışında birçok başka faydası daha 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. Dolayısıyla açıklamayı oluşturmak için .toString() kullanılırsa .toString() yeniden tanımlanma riski olmaz.

İhlalde bulunma (yalnızca bildirme modunda)

Şu anda TT ihlallerinde hata ayıklamanın tek yolu JS istisnalarında kesme noktaları ayarlamaktır. Zorunlu TT ihlalleri bir istisnayı tetikleyeceğinden bu özellik bir şekilde yararlı olabilir. Ancak, gerçek senaryolarda TT ihlalleri üzerinde daha ayrıntılı bir kontrole sahip olmanız gerekir. Özellikle, yalnızca TT ihlallerini (diğer istisnaları değil) ihlal etmek, yalnızca rapor modunu açmak ve farklı TT ihlali türlerini birbirinden ayırt etmek istiyoruz.

Geliştirici Araçları, halihazırda çok çeşitli ayrılma noktalarını desteklediğinden mimari oldukça genişletilebilir. Yeni bir ayrılma noktası türü eklemek için arka uçta (Blink), CDP'de ve ön uçta değişiklik yapılması gerekir. Yeni bir CDP komutu kullanmalıyız. setBreakOnTTViolation olarak adlandıralım. Bu komut, ön uç tarafından ne tür TT ihlallerinin bozulması gerektiğini bildirmek için kullanılır. Arka uç, özellikle de InspectorDOMDebuggerAgent, her TT ihlali meydana geldiğinde çağrılacak bir "kontrol" (onTTViolation()) sağlar. Ardından InspectorDOMDebuggerAgent, söz konusu ihlalin bir ayrılma noktasını tetikleyip tetiklemeyeceğini kontrol eder. Böyle bir durumda, ön uca yürütmeyi duraklatması için mesaj gönderir.

Neler 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 sorun ortaya çıkarmak için Sorunlar sekmesini kullanmayı planlıyoruz. Bu sayede, uzun vadede okunamayan hata mesajı akışının Konsolu'nu kaldırabiliriz.

Önizleme kanallarını indirme

Varsayılan geliştirme tarayıcınız olarak Chrome Canary, Dev veya Beta'yı kullanabilirsiniz. Bu önizleme kanalları en yeni Geliştirici Araçları özelliklerine erişmenizi, son teknoloji ürünü web platformu API'lerini test etmenizi ve kullanıcılarınızdan önce sitenizdeki sorunları bulmanızı sağlar.

Chrome Geliştirici Araçları ekibiyle iletişim kurma

Yayındaki yeni özellikleri ve değişiklikleri ya da Geliştirici Araçları ile ilgili diğer her şeyi tartışmak için aşağıdaki seçenekleri kullanın.

  • Öneri veya geri bildirimlerinizi crbug.com adresinden bize iletebilirsiniz.
  • Geliştirici Araçları sorunlarını bildirmek için Diğer seçenekler'i Daha fazla > Yardım > Geliştirici Araçları'nda Geliştirici Araçları ile ilgili sorunları bildirin.
  • @ChromeDevTools adresinden tweet atabilirsiniz.
  • Geliştirici Araçları YouTube videoları veya Geliştirici Araçları ipuçları YouTube videolarına yorum yazın.