Angular
The Checklist
Checklist buradan ulaşabilirsiniz.
What is Angular
Angular, Google tarafından sürdürülen güçlü ve açık kaynak bir ön uç framework'tür. Kod okunabilirliğini ve hata ayıklamayı artırmak için TypeScript kullanır. Güçlü güvenlik mekanizmaları ile Angular, XSS ve açık yönlendirmeler gibi yaygın istemci tarafı güvenlik açıklarını önler. Ayrıca sunucu tarafında da kullanılabilir, bu nedenle güvenlik dikkate alınması gereken önemli bir konudur her iki açıdan.
Framework architecture
Angular temellerini daha iyi anlamak için, temel kavramlarına göz atalım.
Ortak bir Angular projesi genellikle şöyle görünür:
According to the documentation, every Angular application has at least one component, the root component (AppComponent
) that connects a component hierarchy with the DOM. Each component defines a class that contains application data and logic, and is associated with an HTML template that defines a view to be displayed in a target environment. The @Component()
decorator identifies the class immediately below it as a component, and provides the template and related component-specific metadata. The AppComponent
is defined in the app.component.ts
file.
Angular NgModules declare a compilation context for a set of components that is dedicated to an application domain, a workflow, or a closely related set of capabilities. Every Angular application has a root module, conventionally named AppModule
, which provides the bootstrap mechanism that launches the application. An application typically contains many functional modules. The AppModule
is defined in the app.module.ts
file.
The Angular Router
NgModule provides a service that lets you define a navigation path among the different application states and view hierarchies in your application. The RouterModule
is defined in the app-routing.module.ts
file.
For data or logic that isn't associated with a specific view, and that you want to share across components, you create a service class. A service class definition is immediately preceded by the @Injectable()
decorator. The decorator provides the metadata that allows other providers to be injected as dependencies into your class. Dependency injection (DI) lets you keep your component classes lean and efficient. They don't fetch data from the server, validate user input, or log directly to the console; they delegate such tasks to services.
Sourcemap configuration
Angular framework translates TypeScript files into JavaScript code by following tsconfig.json
options and then builds a project with angular.json
configuration. Looking at angular.json
file, we observed an option to enable or disable a sourcemap. According to the Angular documentation, the default configuration has a sourcemap file enabled for scripts and is not hidden by default:
Genel olarak, sourcemap dosyaları, üretilen dosyaları orijinal dosyalarına eşleştirdikleri için hata ayıklama amaçları için kullanılır. Bu nedenle, bunların üretim ortamında kullanılması önerilmez. Eğer sourcemap'ler etkinleştirilirse, okunabilirliği artırır ve Angular projesinin orijinal durumunu kopyalayarak dosya analizine yardımcı olur. Ancak, devre dışı bırakıldığında, bir inceleyici, anti-güvenlik desenlerini arayarak derlenmiş bir JavaScript dosyasını manuel olarak analiz edebilir.
Ayrıca, bir Angular projesine ait derlenmiş bir JavaScript dosyası, tarayıcı geliştirici araçları → Kaynaklar (veya Hata Ayıklayıcı ve Kaynaklar) → [id].main.js altında bulunabilir. Etkinleştirilen seçeneklere bağlı olarak, bu dosya sonunda //# sourceMappingURL=[id].main.js.map
satırını içerebilir veya gizli seçeneği true olarak ayarlandığında içermeyebilir. Yine de, scriptler için sourcemap devre dışı bırakıldığında, test daha karmaşık hale gelir ve dosyayı elde edemeyiz. Ayrıca, sourcemap proje derlemesi sırasında ng build --source-map
gibi etkinleştirilebilir.
Veri bağlama
Bağlama, bir bileşen ile ilgili görünümü arasındaki iletişim sürecini ifade eder. Angular çerçevesine veri aktarmak için kullanılır. Veri, olaylar, interpolasyon, özellikler veya iki yönlü bağlama mekanizması gibi çeşitli yollarla iletilebilir. Ayrıca, veri, ilgili bileşenler (ebeveyn-çocuk ilişkisi) ve iki alakasız bileşen arasında Servis özelliği kullanılarak da paylaşılabilir.
Bağlamayı veri akışına göre sınıflandırabiliriz:
Veri kaynağından görünüm hedefine ( interpolasyon, özellikler, nitelikler, sınıflar ve stil içerir); şablonda
[]
veya{{}}
kullanılarak uygulanabilir;Görünüm hedefine veri kaynağından ( olaylar içerir); şablonda
()
kullanılarak uygulanabilir;İki Yönlü; şablonda
[()]
kullanılarak uygulanabilir.
Bağlama, özellikler, olaylar ve nitelikler üzerinde, ayrıca bir kaynak direktifinin herhangi bir genel üyesi üzerinde çağrılabilir:
Özellik
Eleman özelliği, Bileşen özelliği, Direktif özelliği
<img [alt]="hero.name" [src]="heroImageUrl">
Olay
Eleman olayı, Bileşen olayı, Direktif olayı
<button type="button" (click)="onSave()">Kaydet
İki yönlü
Olay ve özellik
<input [(ngModel)]="name">
Nitelik
Nitelik (istisna)
<button type="button" [attr.aria-label]="help">yardım
Sınıf
sınıf özelliği
<div [class.special]="isSpecial">Özel
Stil
stil özelliği
<button type="button" [style.color]="isSpecial ? 'red' : 'green'">
Angular güvenlik modeli
Angular'ın tasarımı, tüm verilerin varsayılan olarak kodlanmasını veya temizlenmesini içerir, bu da Angular projelerinde XSS açıklarını keşfetmeyi ve istismar etmeyi giderek daha zor hale getirir. Veri işleme için iki ayrı senaryo vardır:
İ interpolasyon veya
{{user_input}}
- bağlam duyarlı kodlama gerçekleştirir ve kullanıcı girişini metin olarak yorumlar;
Sonuç: <script>alert(1)</script><h1>test</h1>
2. Özelliklere, niteliklere, sınıflara ve stillere bağlama veya [attribute]="user_input"
- sağlanan güvenlik bağlamına dayalı olarak temizleme gerçekleştirir.
Sonuç: <div><h1>test</h1></div>
6 tür SecurityContext
vardır:
None
;HTML
, değer HTML olarak yorumlandığında kullanılır;STYLE
, CSS'yistyle
özelliğine bağlarken kullanılır;URL
,<a href>
gibi URL özellikleri için kullanılır;SCRIPT
, JavaScript kodu için kullanılır;RESOURCE_URL
, kod olarak yüklenen ve yürütülen bir URL olarak, örneğin,<script src>
içinde.
Açıklar
Güvenlik Güvenini Atlatma yöntemleri
Angular, varsayılan temizleme sürecini atlatmak ve bir değerin belirli bir bağlamda güvenli bir şekilde kullanılabileceğini belirtmek için bir dizi yöntem tanıtır; aşağıdaki beş örnekte olduğu gibi:
bypassSecurityTrustUrl
, verilen değerin güvenli bir stil URL'si olduğunu belirtmek için kullanılır:
bypassSecurityTrustResourceUrl
, verilen değerin güvenli bir kaynak URL'si olduğunu belirtmek için kullanılır:
bypassSecurityTrustHtml
, verilen değerin güvenli HTML olduğunu belirtmek için kullanılır. Bu şekilde DOM ağacınascript
öğeleri eklemenin, ekli JavaScript kodunu yürütmeyeceğini unutmayın, çünkü bu öğeler DOM ağacına bu şekilde eklenir.
bypassSecurityTrustScript
, verilen değerin güvenli JavaScript olduğunu belirtmek için kullanılır. Ancak, bu yöntemi kullanarak şablonlarda JS kodunu yürütme konusunda öngörülemez bir davranış bulduk.
bypassSecurityTrustStyle
, verilen değerin güvenli CSS olduğunu belirtmek için kullanılır. Aşağıdaki örnek CSS enjeksiyonunu göstermektedir:
Angular, verileri görünümlerde görüntülemeden önce temizlemek için bir sanitize
yöntemi sağlar. Bu yöntem, sağlanan güvenlik bağlamını kullanır ve girişi buna göre temizler. Ancak, belirli veri ve bağlam için doğru güvenlik bağlamını kullanmak çok önemlidir. Örneğin, HTML içeriği üzerinde SecurityContext.URL
ile bir temizleyici uygulamak, tehlikeli HTML değerlerine karşı koruma sağlamaz. Bu tür senaryolarda, güvenlik bağlamının yanlış kullanımı XSS açıklarına yol açabilir.
HTML enjeksiyonu
Bu açık, kullanıcı girişi herhangi bir üç özellikten birine bağlandığında meydana gelir: innerHTML
, outerHTML
veya iframe
srcdoc
. Bu niteliklere bağlanırken HTML olduğu gibi yorumlanır, giriş SecurityContext.HTML
kullanılarak temizlenir. Böylece, HTML enjeksiyonu mümkündür, ancak siteler arası komut dosyası (XSS) değildir.
innerHTML
kullanma örneği:
Sonuç <div><h1>test</h1></div>
.
Şablon enjeksiyonu
İstemci Tarafı Render (CSR)
Angular, sayfaları dinamik olarak oluşturmak için şablonları kullanır. Bu yaklaşım, Angular'ın değerlendirmesi için şablon ifadelerini çift süslü parantezler ({{}}
) içinde kapsüllemeyi içerir. Bu şekilde, çerçeve ek işlevsellik sunar. Örneğin, {{1+1}}
gibi bir şablon 2 olarak görüntülenecektir.
Genellikle, Angular, şablon ifadeleriyle karıştırılabilecek kullanıcı girişlerini (örneğin, `< > ' " `` gibi karakterler) kaçışlar. Bu, yasaklı karakterleri kullanmaktan kaçınmak için JavaScript dize nesneleri üreten işlevler gibi bu kısıtlamayı aşmak için ek adımların gerekli olduğu anlamına gelir. Ancak, bunu başarmak için Angular bağlamını, özelliklerini ve değişkenlerini dikkate almamız gerekir. Bu nedenle, bir şablon enjeksiyonu saldırısı şu şekilde görünebilir:
Yukarıda gösterildiği gibi: constructor
, Object constructor
özelliğinin kapsamını ifade eder ve bize String constructor'ı çağırma ve rastgele kod yürütme imkanı tanır.
Sunucu Tarafı Render (SSR)
Tarayıcıdaki DOM'da gerçekleşen CSR'ın aksine, Angular Universal, şablon dosyalarının SSR'sinden sorumludur. Bu dosyalar daha sonra kullanıcıya iletilir. Bu ayrıma rağmen, Angular Universal, SSR güvenliğini artırmak için CSR'da kullanılan aynı sanitizasyon mekanizmalarını uygular. SSR'deki bir şablon enjeksiyon açığı, kullanılan şablon dilinin aynı olması nedeniyle CSR'deki gibi tespit edilebilir.
Elbette, Pug ve Handlebars gibi üçüncü taraf şablon motorları kullanıldığında yeni şablon enjeksiyon açıkları tanıtma olasılığı da vardır.
XSS
DOM arayüzleri
Daha önce belirtildiği gibi, Document arayüzünü kullanarak doğrudan DOM'a erişebiliriz. Kullanıcı girişi önceden doğrulanmazsa, bu, cross-site scripting (XSS) açıklarına yol açabilir.
Aşağıdaki örneklerde document.write()
ve document.createElement()
yöntemlerini kullandık:
Angular sınıfları
Angular'da DOM öğeleriyle çalışmak için kullanılabilecek bazı sınıflar vardır: ElementRef
, Renderer2
, Location
ve Document
. Son iki sınıfın ayrıntılı açıklaması Açık yönlendirmeler bölümünde verilmiştir. İlk iki sınıf arasındaki ana fark, Renderer2
API'sinin DOM öğesi ile bileşen kodu arasında bir soyutlama katmanı sağlamasıdır, oysa ElementRef
yalnızca öğeye bir referans tutar. Bu nedenle, Angular belgelerine göre, ElementRef
API'si yalnızca doğrudan DOM erişimi gerektiğinde son çare olarak kullanılmalıdır.
ElementRef
, DOM öğelerini manipüle etmek için kullanılabileceknativeElement
özelliğini içerir. Ancak,nativeElement
'in yanlış kullanımı, aşağıda gösterildiği gibi bir XSS enjeksiyon açığına yol açabilir:
Renderer2
'nin, yerel öğelere doğrudan erişim desteklenmediğinde bile güvenli bir şekilde kullanılabilecek bir API sağladığı gerçeğine rağmen, bazı güvenlik açıkları vardır.Renderer2
ile,setAttribute()
yöntemi kullanılarak bir HTML öğesine nitelikler ayarlanabilir; bu yöntemin XSS önleme mekanizmaları yoktur.
Bir DOM öğesinin özelliğini ayarlamak için
Renderer2.setProperty()
yöntemini kullanabilir ve bir XSS saldırısını tetikleyebilirsiniz:
Araştırmalarımız sırasında, XSS ve CSS enjeksiyonları ile ilgili olarak setStyle()
, createComment()
ve setValue()
gibi diğer Renderer2
yöntemlerinin davranışını da inceledik. Ancak, işlevsel sınırlamaları nedeniyle bu yöntemler için geçerli saldırı vektörleri bulamadık.
jQuery
jQuery, HTML DOM nesnelerini manipüle etmek için Angular projesinde kullanılabilecek hızlı, küçük ve özellik açısından zengin bir JavaScript kütüphanesidir. Ancak, bilindiği gibi, bu kütüphanenin yöntemleri bir XSS açığı elde etmek için istismar edilebilir. Bazı savunmasız jQuery yöntemlerinin Angular projelerinde nasıl istismar edilebileceğini tartışmak için bu alt bölümü ekledik.
html()
yöntemi, eşleşen öğelerin setindeki ilk öğenin HTML içeriğini alır veya her eşleşen öğenin HTML içeriğini ayarlar. Ancak, tasarım gereği, bir HTML dizesi kabul eden herhangi bir jQuery yapıcı veya yöntemi potansiyel olarak kod çalıştırabilir. Bu,<script>
etiketlerinin enjeksiyonu veya kodu çalıştıran HTML niteliklerinin kullanılmasıyla gerçekleşebilir.
jQuery.parseHTML()
yöntemi, dizeyi bir dizi DOM düğümüne dönüştürmek için yerel yöntemler kullanır; bu düğümler daha sonra belgeye eklenebilir.
Daha önce belirtildiği gibi, HTML dizeleri kabul eden çoğu jQuery API'si, HTML'de dahil edilen betikleri çalıştırır. jQuery.parseHTML()
yöntemi, keepScripts
açıkça true
olmadıkça, ayrıştırılan HTML'deki betikleri çalıştırmaz. Ancak, çoğu ortamda dolaylı olarak betikleri çalıştırmak hala mümkündür; örneğin, <img onerror>
niteliği aracılığıyla.
Açık yönlendirmeler
DOM arayüzleri
W3C belgelerine göre, window.location
ve document.location
nesneleri modern tarayıcılarda takma adlar olarak kabul edilir. Bu nedenle, bazı yöntemlerin ve özelliklerin benzer bir uygulamasına sahiptirler; bu da aşağıda belirtilen javascript://
şeması saldırılarıyla açık yönlendirme ve DOM XSS'e neden olabilir.
window.location.href
(vedocument.location.href
)
Mevcut DOM konum nesnesini almanın kanonik yolu window.location
kullanmaktır. Ayrıca, tarayıcıyı yeni bir sayfaya yönlendirmek için de kullanılabilir. Sonuç olarak, bu nesne üzerinde kontrol sahibi olmak, açık yönlendirme açığını istismar etmemizi sağlar.
Aşağıdaki senaryolar için istismar süreci aynıdır.
window.location.assign()
(vedocument.location.assign()
)
Bu yöntem, pencerenin belirtilen URL'deki belgeyi yüklemesini ve görüntülemesini sağlar. Bu yöntemi kontrol edersek, açık yönlendirme saldırısı için bir hedef olabilir.
window.location.replace()
(vedocument.location.replace()
)
Bu yöntem, mevcut kaynağı sağlanan URL'deki kaynakla değiştirir.
assign()
yönteminden farkı, window.location.replace()
kullandıktan sonra mevcut sayfanın oturum Geçmişi'nde kaydedilmeyecek olmasıdır. Ancak, bu yöntemi kontrol ettiğimizde açık yönlendirme açığını istismar etmek de mümkündür.
window.open()
window.open()
yöntemi, bir URL alır ve tanımladığı kaynağı yeni veya mevcut bir sekmeye veya pencereye yükler. Bu yöntemi kontrol etmek, bir XSS veya açık yönlendirme açığını tetiklemek için de bir fırsat olabilir.
Angular sınıfları
Angular belgelerine göre, Angular
Document
, DOM belgesi ile aynıdır; bu da Angular'da istemci tarafı açıklarını istismar etmek için DOM belgesi için ortak vektörlerin kullanılabileceği anlamına gelir.Document.location
özellikleri ve yöntemleri, aşağıdaki örnekte gösterildiği gibi başarılı açık yönlendirme saldırıları için hedef olabilir:
Araştırma aşamasında, açık yönlendirme açıkları için Angular
Location
sınıfını da inceledik, ancak geçerli vektörler bulunamadı.Location
, uygulamaların bir tarayıcının mevcut URL'siyle etkileşimde bulunmasını sağlamak için kullanabileceği bir Angular hizmetidir. Bu hizmet, verilen URL'yi manipüle etmek için birkaç yönteme sahiptir -go()
,replaceState()
veprepareExternalUrl()
. Ancak, bunları dış bir alan adına yönlendirmek için kullanamayız. Örneğin:
Sonuç: http://localhost:4200/http://google.com/about
Angular
Router
sınıfı esasen aynı alan içinde gezinmek için kullanılır ve uygulamaya ek bir güvenlik açığı getirmez:
Sonuç: http://localhost:4200/https:
Aşağıdaki yöntemler de alanın kapsamı içinde gezinir:
Referanslar
Last updated