Angular, **Google** tarafından sürdürülen **güçlü** ve **açık kaynaklı** bir ön uç çerçevesidir. Kod okunabilirliğini ve hata ayıklamayı artırmak için **TypeScript** kullanır. Güçlü güvenlik mekanizmalarıyla, Angular **XSS** ve **açık yönlendirmeler** gibi yaygın istemci tarafı güvenlik açıklarını önler. Güvenlik düşünceleri, Angular'ın **hem sunucu tarafında** hem de **istemci tarafında** kullanılabilmesi nedeniyle önemlidir.
Belgelere göre, her Angular uygulamasında en az bir bileşen bulunur. Kök bileşen (`AppComponent`), bileşen hiyerarşisini DOM ile bağlayan bir bileşendir. Her bileşen, bir uygulama veri ve mantığını içeren bir sınıf tanımlar ve hedef ortamda görüntülenecek bir görünümü tanımlayan bir HTML şablonuyla ilişkilendirilir. `@Component()` dekoratörü, hemen altındaki sınıfı bir bileşen olarak tanımlar ve şablona ve ilgili bileşen özel meta verilere sağlar. `AppComponent`, `app.component.ts` dosyasında tanımlanmıştır.
Angular NgModules, bir uygulama alanı, bir iş akışı veya yakından ilişkili bir yetenek kümesine yönelik bir bileşen seti için derleme bağlamı bildirir. Her Angular uygulamasının bir kök modülü vardır ve genellikle `AppModule` olarak adlandırılır. Bu modül, uygulamayı başlatan önyükleme mekanizmasını sağlar. Bir uygulama genellikle birçok işlevsel modül içerir. `AppModule`, `app.module.ts` dosyasında tanımlanmıştır.
Angular `Router` NgModule, uygulamanızdaki farklı uygulama durumları ve görünüm hiyerarşileri arasında bir gezinme yolunu tanımlamanıza olanak sağlayan bir hizmet sağlar. `RouterModule`, `app-routing.module.ts` dosyasında tanımlanmıştır.
Bir görünümle ilişkili olmayan veri veya mantık için ve bileşenler arasında paylaşmak istediğiniz durumlar için bir hizmet sınıfı oluşturursunuz. Bir hizmet sınıfı tanımı, hemen öncesinde `@Injectable()` dekoratörü ile gelir. Dekoratör, diğer sağlayıcıların sınıfınıza bağımlılık olarak enjekte edilmesine izin veren meta verileri sağlar. Bağımlılık enjeksiyonu (DI), bileşen sınıflarınızı sade ve verimli tutmanızı sağlar. Bileşenler, sunucudan veri almayı, kullanıcı girişini doğrulamayı veya doğrudan konsola kaydetmeyi yapmaz; bu tür görevleri hizmetlere devreder.
Angular çerçevesi, `tsconfig.json` seçeneklerini takip ederek TypeScript dosyalarını JavaScript koduna çevirir ve ardından `angular.json` yapılandırmasıyla bir proje oluşturur. `angular.json` dosyasına bakarak, bir sourcemap'i etkinleştirme veya devre dışı bırakma seçeneği olduğunu gözlemledik. Angular belgelerine göre, varsayılan yapılandırma, betikler için bir sourcemap dosyasının etkin olduğunu ve varsayılan olarak gizlenmediğini belirtir.
Genellikle, sourcemap dosyaları hata ayıklama amaçlarıyla kullanılır çünkü oluşturulan dosyaları orijinal dosyalara eşler. Bu nedenle, bunları üretim ortamında kullanmanız önerilmez. Sourcemap'ler etkinleştirildiğinde, Angular projesinin orijinal durumunu yeniden oluşturarak okunabilirliği artırır ve dosya analizine yardımcı olur. Ancak, devre dışı bırakıldığında, bir inceleyici, derlenmiş bir JavaScript dosyasını anti-güvenlik desenlerini arayarak manuel olarak analiz edebilir.
Ayrıca, bir Angular projesinin derlenmiş bir JavaScript dosyası, tarayıcı geliştirici araçları → Kaynaklar (veya Hata Ayıklayıcı ve Kaynaklar) → \[id].main.js içinde bulunabilir. Etkinleştirilen seçeneklere bağlı olarak, bu dosya aşağıdaki satırı içerebilir `//# sourceMappingURL=[id].main.js.map` veya içermeyebilir, eğer **hidden** seçeneği **true** olarak ayarlanmışsa. Bununla birlikte, sourcemap **scripts** için devre dışı bırakıldığında, test etmek daha karmaşık hale gelir ve dosyayı elde edemeyiz. Ayrıca, sourcemap, `ng build --source-map` gibi proje derleme sırasında etkinleştirilebilir.
Bağlama, bir bileşenin ve ilgili görünümünün arasındaki iletişim sürecini ifade eder. Veri, Angular çerçevesine veri aktarımı için kullanılır. Veri, olaylar, interpolasyon, özellikler veya iki yönlü bağlama mekanizması gibi çeşitli yollarla iletilir. Ayrıca, veri, ilişkili bileşenler (ebeveyn-çocuk ilişkisi) ve Servis özelliğini kullanarak iki ilişkisiz bileşen arasında paylaşılabilir.
* Veri kaynağından görünüm hedefine (interpolasyon, özellikler, öznitelikler, sınıflar ve stiller içerir); şablon içinde `[]` veya `{{}}` kullanılarak uygulanabilir;
* Görünüm hedefinden veri kaynağına (olaylar içerir); şablon içinde `()` kullanılarak uygulanabilir;
* İki yönlü; şablon içinde `[()]` kullanılarak uygulanabilir.
Angular'ın tasarımı, varsayılan olarak tüm verilerin kodlanması veya temizlenmesini içerir, bu da Angular projelerinde XSS zafiyetlerini keşfetmeyi ve sömürmeyi giderek zorlaştırır. Veri işleme için iki farklı senaryo vardır:
2. Özelliklere, özniteliklere, sınıflara ve stillere bağlama veya `[attribute]="kullanıcı_girişi"` - sağlanan güvenlik bağlamına dayanarak temizleme yapar.
Angular, varsayılan temizleme işlemini atlamak ve bir değerin belirli bir bağlamda güvenli bir şekilde kullanılabileceğini belirtmek için bir dizi yöntem sunar. İşte beş örnek:
3.`bypassSecurityTrustHtml`, verilen değerin güvenli HTML olduğunu belirtmek için kullanılır. Bu şekilde DOM ağacına `script` öğeleri eklemek, bu öğelerin içerdikleri JavaScript kodunu yürütmez, çünkü bu öğelerin DOM ağacına nasıl eklendiğine bağlıdır.
4.`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ütemediğimiz için davranışının öngörülemez olduğunu bulduk.
Bu zafiyet, kullanıcı girdisinin `innerHTML`, `outerHTML` veya `iframe``srcdoc` özelliklerinden herhangi birine bağlandığında ortaya çıkar. Bu özelliklere bağlanırken HTML doğrudan yorumlanır, ancak girdi `SecurityContext.HTML` kullanılarak temizlenir. Bu nedenle, HTML enjeksiyonu mümkün olsa da, cross-site scripting (XSS) mümkün değildir.
Angular, sayfaları dinamik olarak oluşturmak için şablonları kullanır. Bu yaklaşım, Angular'ın değerlendirmesi için çift süslü parantez içinde (`{{}}`) şablon ifadelerini kapsar. Bu şekilde, çerçeve ek işlevsellik sunar. Örneğin, `{{1+1}}` gibi bir şablon 2 olarak görüntülenir.
Genellikle, Angular, şablon ifadeleriyle karıştırılabilecek kullanıcı girişini kaçırır (örneğin, \`< > ' " \`\` gibi karakterler). Bu, yasaklanmış karakterleri kullanmaktan kaçınmak için JavaScript dize nesneleri üreten işlevleri kullanma gibi ek adımlar gerektirir. Bununla birlikte, bunu başarmak için Angular bağlamını, özelliklerini ve değişkenlerini dikkate almamız gerekmektedir. Bu nedenle, bir şablon enjeksiyon saldırısı aşağıdaki gibi görünebilir:
Yukarıda gösterildiği gibi: `constructor`, String yapıcısını çağırarak ve keyfi bir kodu yürüterek, Object `constructor` özelliğinin kapsamını ifade eder.
CSR'de tarayıcının DOM'unda gerçekleştiği gibi, Angular Universal, şablon dosyalarının SSR'ını üstlenir. Bu dosyalar daha sonra kullanıcıya teslim edilir. Bu ayrımın yanı sıra, Angular Universal, SSR güvenliğini artırmak için CSR'de kullanılan aynı temizleme mekanizmalarını uygular. SSR'deki bir şablon enjeksiyonu açığı, kullanılan şablon dilinin aynı olduğu şekilde tespit edilebilir.
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.
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ı bir açıklaması**Açık yönlendirmeler** bölümünde verilmiştir. İlk iki sınıf arasındaki temel fark, `Renderer2` API'nin DOM öğesi ile bileşen kodu arasında bir soyutlama katmanı sağlamasıdır, oysa `ElementRef` sadece öğeye bir referans tutar. Bu nedenle, Angular belgelerine göre, `ElementRef` API'si, doğrudan DOM erişimi gerektiğinde sadece son çare olarak kullanılmalıdır.
*`ElementRef`, DOM öğelerini manipüle etmek için kullanılabilecek `nativeElement` özelliğini içerir. Bununla birlikte, `nativeElement`'in yanlış kullanımı XSS enjeksiyonu güvenlik açığına neden olabilir, aşağıdaki örnekte gösterildiği gibi:
```tsx
//app.component.ts
import { Component, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
*`Renderer2`, doğrudan erişim sağlanamadığında bile güvenli bir şekilde kullanılabilecek API'leri sağlasa da, hala bazı güvenlik açıkları vardır. `Renderer2` ile `setAttribute()` yöntemi kullanılarak bir HTML öğesine öznitelikler atanabilir ve bu yöntemde XSS önleme mekanizmaları bulunmaz.
```tsx
//app.component.ts
import {Component, Renderer2, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
Araştırmamız sırasında, XSS ve CSS enjeksiyonlarıyla ilgili olarak `setStyle()`, `createComment()` ve `setValue()` gibi diğer `Renderer2` yöntemlerinin davranışını da inceledik. Ancak, bu yöntemler için geçerli saldırı vektörleri bulamadık çünkü işlevsel sınırlamaları vardı.
jQuery, HTML DOM nesnelerini manipüle etmede yardımcı olmak için Angular projesinde kullanılabilecek hızlı, küçük ve özellik açısından zengin bir JavaScript kütüphanesidir. Ancak, bu kütüphanenin yöntemleri XSS zafiyeti elde etmek için kötüye kullanılabilir. Angular projelerinde bazı güvenlik açıklarına sahip jQuery yöntemlerinin nasıl kötüye kullanılabileceğini tartışmak için bu alt bölümü ekledik.
*`html()` yöntemi, eşleşen öğelerin kümesindeki ilk öğenin HTML içeriğini alır veya her eşleşen öğenin HTML içeriğini ayarlar. Ancak, tasarım gereği, HTML dizesini kabul eden herhangi bir jQuery yapıcısı veya yöntemi potansiyel olarak kodu yürütebilir. Bu, `<script>` etiketlerinin enjeksiyonu veya kodu yürüten HTML özniteliklerinin kullanımıyla gerçekleşebilir, aşağıdaki örnekte gösterildiği gibi.
```tsx
//app.component.ts
import { Component, OnInit } from '@angular/core';
import * as $ from 'jquery';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit
{
ngOnInit()
{
$("button").on("click", function()
{
$("p").html("<script>alert(1)</script>");
});
}
}
//app.component.html
<button>Bana tıkla</button>
<p>burada bazı metinler</p>
```
*`jQuery.parseHTML()` yöntemi, dizeyi DOM düğümlerinin bir kümesine dönüştürmek için yerel yöntemleri kullanır ve ardından bunları belgeye yerleştirir.
Daha önce belirtildiği gibi, HTML dizelerini kabul eden çoğu jQuery API'si, HTML içinde bulunan betikleri çalıştırır. `jQuery.parseHTML()` yöntemi, `keepScripts` açıkça `true` olarak belirtilmedikçe ayrıştırılan HTML'deki betikleri çalıştırmaz. Bununla birlikte, çoğu ortamda hala dolaylı olarak betiklerin yürütülmesi mümkündür; örneğin, `<img onerror>` özniteliği aracılığıyla.
```tsx
//app.component.ts
import { Component, OnInit } from '@angular/core';
import * as $ from 'jquery';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit
{
ngOnInit()
{
$("button").on("click", function()
{
var $palias = $("#palias"),
str = "<imgsrc=1onerror=alert(1)>",
html = $.parseHTML(str),
nodeNames = [];
$palias.append(html);
});
}
}
//app.component.html
<button>Bana tıkla</button>
<pid="palias">bazı metinler</p>
```
### Açık yönlendirmeler
#### DOM arayüzleri
W3C belgelerine göre, `window.location` ve `document.location` nesneleri modern tarayıcılarda birbirine eşit olarak kabul edilir. Bu nedenle, bazı yöntemlerin ve özelliklerin benzer uygulamalarına sahiptirler, bu da açık yönlendirme ve `javascript://` şema saldırılarıyla DOM XSS'e neden olabilir.
Geçerli 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. Bu nedenle, bu nesneye sahip olmak, açık yönlendirme zafiyetini sömürmemize olanak tanır.
Bu yöntem, pencerenin belirtilen URL'deki belgeyi yüklemesine ve görüntülemesine neden olur. Bu yönteme sahipsek, açık yönlendirme saldırısı için bir hedef olabilir.
Bu yöntem, mevcut kaynağı sağlanan URL ile değiştirir.
Bu, `assign()` yönteminden farklı olarak, `window.location.replace()` kullanıldıktan sonra mevcut sayfa oturum Geçmişinde kaydedilmeyecektir. Bununla birlikte, bu yönteme sahip olduğumuzda açık yönlendirme zafiyetini sömürmek mümkündür.
`window.open()` yöntemi bir URL alır ve onu yeni veya mevcut bir
#### Angular Sınıfları
* Angular belgelerine göre, Angular `Document` DOM belgesiyle aynıdır, bu da Angular'da istemci tarafı güvenlik açıklarını sömürmek için genel vektörlerin DOM belgesi için 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:
```tsx
//app.component.ts
import { Component, Inject } from '@angular/core';
* Araştırma aşamasında, açık yönlendirme güvenlik açıkları için Angular `Location` sınıfını da inceledik, ancak geçerli vektörler bulunamadı. `Location`, uygulamaların tarayıcının geçerli URL'siyle etkileşimde bulunmak için kullanabileceği bir Angular servisidir. Bu servisin, verilen URL'yi manipüle etmek için birkaç yöntemi vardır - `go()`, `replaceState()` ve `prepareExternalUrl()`. Bununla birlikte, bunları harici bir etki alanına yönlendirme için kullanamayız. Örneğin:
```tsx
//app.component.ts
import { Component, Inject } from '@angular/core';
import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common';
* [Angular Bağlamı: İç İçe Bileşen Ağaçları ve Router Outlet için Kolay Veri Bağlama](https://medium.com/angular-in-depth/angular-context-easy-data-binding-for-nested-component-trees-and-the-router-outlet-a977efacd48)
* [Temizleme ve güvenlik bağlamları](https://angular.io/guide/security#sanitization-and-security-contexts)
* [Renderer2 Örneği: Angular'da DOM Manipülasyonu - TekTutorialsHub](https://www.tektutorialshub.com/angular/renderer2-angular/)
* [jQuery API Belgeleri](http://api.jquery.com/)
* [Angular ile jQuery Nasıl Kullanılır (Mutlaka Kullanmanız Gerektiğinde)](https://blog.bitsrc.io/how-to-use-jquery-with-angular-when-you-absolutely-have-to-42c8b6a37ff9)