mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
610 lines
42 KiB
Markdown
610 lines
42 KiB
Markdown
# Angular
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## The Checklist
|
||
|
||
Checklist [from here](https://lsgeurope.com/post/angular-security-checklist).
|
||
|
||
* [ ] Angular को एक क्लाइंट-साइड फ्रेमवर्क माना जाता है और इसे सर्वर-साइड सुरक्षा प्रदान करने की अपेक्षा नहीं की जाती है
|
||
* [ ] प्रोजेक्ट कॉन्फ़िगरेशन में स्क्रिप्ट के लिए सोर्समैप अक्षम है
|
||
* [ ] अविश्वसनीय उपयोगकर्ता इनपुट को हमेशा टेम्पलेट्स में उपयोग करने से पहले इंटरपोलेट या सैनीटाइज किया जाता है
|
||
* [ ] उपयोगकर्ता के पास सर्वर-साइड या क्लाइंट-साइड टेम्पलेट्स पर कोई नियंत्रण नहीं है
|
||
* [ ] अविश्वसनीय उपयोगकर्ता इनपुट को एप्लिकेशन द्वारा विश्वसनीय बनने से पहले उचित सुरक्षा संदर्भ का उपयोग करके सैनीटाइज किया जाता है
|
||
* [ ] `BypassSecurity*` विधियों का अविश्वसनीय इनपुट के साथ उपयोग नहीं किया जाता है
|
||
* [ ] अविश्वसनीय उपयोगकर्ता इनपुट को Angular क्लासेस जैसे `ElementRef`, `Renderer2` और `Document`, या अन्य JQuery/DOM सिंक्स में नहीं भेजा जाता है
|
||
|
||
## What is Angular
|
||
|
||
Angular एक **शक्तिशाली** और **ओपन-सोर्स** फ्रंट-एंड फ्रेमवर्क है जिसे **Google** द्वारा बनाए रखा जाता है। यह कोड की पठनीयता और डिबगिंग को बढ़ाने के लिए **TypeScript** का उपयोग करता है। मजबूत सुरक्षा तंत्र के साथ, Angular सामान्य क्लाइंट-साइड कमजोरियों जैसे **XSS** और **open redirects** को रोकता है। इसे **सर्वर-साइड** पर भी उपयोग किया जा सकता है, जिससे **दोनों कोणों** से सुरक्षा पर विचार करना महत्वपूर्ण हो जाता है।
|
||
|
||
## Framework architecture
|
||
|
||
Angular के मूलभूत सिद्धांतों को बेहतर ढंग से समझने के लिए, आइए इसके आवश्यक अवधारणाओं के माध्यम से चलते हैं।
|
||
|
||
सामान्य Angular प्रोजेक्ट आमतौर पर इस तरह दिखता है:
|
||
```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
|
||
```
|
||
Angular एप्लिकेशन के अनुसार, हर Angular एप्लिकेशन में कम से कम एक घटक होता है, रूट घटक (`AppComponent`) जो घटक पदानुक्रम को DOM से जोड़ता है। प्रत्येक घटक एक वर्ग को परिभाषित करता है जिसमें एप्लिकेशन डेटा और लॉजिक होता है, और यह एक HTML टेम्पलेट से संबंधित होता है जो एक लक्ष्य वातावरण में प्रदर्शित होने वाले दृश्य को परिभाषित करता है। `@Component()` डेकोरेटर उस वर्ग को घटक के रूप में पहचानता है जो इसके ठीक नीचे है, और टेम्पलेट और संबंधित घटक-विशिष्ट मेटाडेटा प्रदान करता है। `AppComponent` को `app.component.ts` फ़ाइल में परिभाषित किया गया है।
|
||
|
||
Angular NgModules एक एप्लिकेशन डोमेन, एक कार्यप्रवाह, या निकटता से संबंधित क्षमताओं के सेट के लिए एक संकलन संदर्भ घोषित करते हैं। हर Angular एप्लिकेशन में एक रूट मॉड्यूल होता है, जिसे पारंपरिक रूप से `AppModule` कहा जाता है, जो एप्लिकेशन को लॉन्च करने के लिए बूटस्ट्रैप तंत्र प्रदान करता है। एक एप्लिकेशन में आमतौर पर कई कार्यात्मक मॉड्यूल होते हैं। `AppModule` को `app.module.ts` फ़ाइल में परिभाषित किया गया है।
|
||
|
||
Angular `Router` NgModule एक सेवा प्रदान करता है जो आपको अपने एप्लिकेशन में विभिन्न एप्लिकेशन राज्यों और दृश्य पदानुक्रमों के बीच एक नेविगेशन पथ परिभाषित करने की अनुमति देता है। `RouterModule` को `app-routing.module.ts` फ़ाइल में परिभाषित किया गया है।
|
||
|
||
डेटा या लॉजिक के लिए जो किसी विशिष्ट दृश्य से संबंधित नहीं है, और जिसे आप घटकों के बीच साझा करना चाहते हैं, आप एक सेवा वर्ग बनाते हैं। एक सेवा वर्ग परिभाषा के तुरंत पहले `@Injectable()` डेकोरेटर होता है। डेकोरेटर मेटाडेटा प्रदान करता है जो अन्य प्रदाताओं को आपकी कक्षा में निर्भरता के रूप में इंजेक्ट करने की अनुमति देता है। निर्भरता इंजेक्शन (DI) आपको अपने घटक वर्गों को पतला और कुशल बनाए रखने की अनुमति देता है। वे सर्वर से डेटा नहीं लाते, उपयोगकर्ता इनपुट को मान्य नहीं करते, या सीधे कंसोल में लॉग नहीं करते; वे ऐसी कार्यों को सेवाओं को सौंपते हैं।
|
||
|
||
## Sourcemap configuration
|
||
|
||
Angular ढांचा TypeScript फ़ाइलों को JavaScript कोड में अनुवाद करता है `tsconfig.json` विकल्पों का पालन करते हुए और फिर `angular.json` कॉन्फ़िगरेशन के साथ एक प्रोजेक्ट बनाता है। `angular.json` फ़ाइल को देखते हुए, हमने एक विकल्प देखा जो एक sourcemap को सक्षम या अक्षम करने के लिए है। Angular दस्तावेज़ के अनुसार, डिफ़ॉल्ट कॉन्फ़िगरेशन में स्क्रिप्ट के लिए एक sourcemap फ़ाइल सक्षम होती है और यह डिफ़ॉल्ट रूप से छिपी नहीं होती है:
|
||
```json
|
||
"sourceMap": {
|
||
"scripts": true,
|
||
"styles": true,
|
||
"vendor": false,
|
||
"hidden": false
|
||
}
|
||
```
|
||
Generally, sourcemap files are utilized for debugging purposes as they map generated files to their original files. Therefore, it is not recommended to use them in a production environment. If sourcemaps are enabled, it improves the readability and aids in file analysis by replicating the original state of the Angular project. However, if they are disabled, a reviewer can still analyze a compiled JavaScript file manually by searching for anti-security patterns.
|
||
|
||
Furthemore, a compiled JavaScript file with an Angular project can be found in the browser developer tools → Sources (or Debugger and Sources) → \[id].main.js. Depending on the enabled options, this file may contain the following row in the end `//# sourceMappingURL=[id].main.js.map` or it may not, if the **hidden** option is set to **true**. Nonetheless, if the sourcemap is disabled for **scripts**, testing becomes more complex, and we cannot obtain the file. In addition, sourcemap can be enabled during project build like `ng build --source-map`.
|
||
|
||
## Data binding
|
||
|
||
Binding refers to the process of communication between a component and its corresponding view. It is utilized for transferring data to and from the Angular framework. Data can be passed through various means, such as through events, interpolation, properties, or through the two-way binding mechanism. Moreover, data can also be shared between related components (parent-child relation) and between two unrelated components using the Service feature.
|
||
|
||
We can classify binding by data flow:
|
||
|
||
* Data source to view target (includes _interpolation_, _properties_, _attributes_, _classes_ and _styles_); can be applied by using `[]` or `{{}}` in template;
|
||
* View target to data source (includes _events_); can be applied by using `()` in template;
|
||
* Two-Way; can be applied by using `[()]` in template.
|
||
|
||
Binding can be called on properties, events, and attributes, as well as on any public member of a source directive:
|
||
|
||
| TYPE | TARGET | EXAMPLES |
|
||
| --------- | -------------------------------------------------------- | -------------------------------------------------------------------- |
|
||
| Property | Element property, Component property, Directive property | \<img \[alt]="hero.name" \[src]="heroImageUrl"> |
|
||
| Event | Element event, Component event, Directive event | \<button type="button" (click)="onSave()">Save |
|
||
| Two-way | Event and property | \<input \[(ngModel)]="name"> |
|
||
| Attribute | Attribute (the exception) | \<button type="button" \[attr.aria-label]="help">help |
|
||
| Class | class property | \<div \[class.special]="isSpecial">Special |
|
||
| Style | style property | \<button type="button" \[style.color]="isSpecial ? 'red' : 'green'"> |
|
||
|
||
## Angular security model
|
||
|
||
Angular's design includes encoding or sanitization of all data by default, making it increasingly difficult to discover and exploit XSS vulnerabilities in Angular projects. There are two distinct scenarios for data handling:
|
||
|
||
1. Interpolation or `{{user_input}}`- performs context-sensitive encoding and interprets user input as text;
|
||
|
||
```jsx
|
||
//app.component.ts
|
||
test = "<script>alert(1)</script><h1>test</h1>";
|
||
|
||
//app.component.html
|
||
{{test}}
|
||
```
|
||
|
||
Result: `<script>alert(1)</script><h1>test</h1>`
|
||
2. Binding to properties, attributes, classes and styles or `[attribute]="user_input"` - performs sanitization based on the provided security context.
|
||
|
||
```jsx
|
||
//app.component.ts
|
||
test = "<script>alert(1)</script><h1>test</h1>";
|
||
|
||
//app.component.html
|
||
<div [innerHtml]="test"></div>
|
||
```
|
||
|
||
Result: `<div><h1>test</h1></div>`
|
||
|
||
There are 6 types of `SecurityContext` :
|
||
|
||
* `None`;
|
||
* `HTML` is used, when interpreting value as HTML;
|
||
* `STYLE` is used, when binding CSS into the `style` property;
|
||
* `URL` is used for URL properties, such as `<a href>`;
|
||
* `SCRIPT` is used for JavaScript code;
|
||
* `RESOURCE_URL` as a URL that is loaded and executed as code, for example, in `<script src>`.
|
||
|
||
## Vulnerabilities
|
||
|
||
### Bypass Security Trust methods
|
||
|
||
The Angular introduces a list of methods to bypass its default sanitization process and to indicate that a value can be used safely in a specific context, as in the following five examples:
|
||
|
||
1. `bypassSecurityTrustUrl` is used to indicate the given value is a safe style URL:
|
||
|
||
```jsx
|
||
//app.component.ts
|
||
this.trustedUrl = this.sanitizer.bypassSecurityTrustUrl('javascript:alert()');
|
||
|
||
//app.component.html
|
||
<a class="e2e-trusted-url" [href]="trustedUrl">Click me</a>
|
||
|
||
//result
|
||
<a _ngcontent-pqg-c12="" class="e2e-trusted-url" href="javascript:alert()">Click me</a>
|
||
```
|
||
2. `bypassSecurityTrustResourceUrl` is used to indicate the given value is a safe resource URL:
|
||
|
||
```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>
|
||
|
||
//result
|
||
<img _ngcontent-nre-c12="" src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png">
|
||
```
|
||
3. `bypassSecurityTrustHtml` is used to indicate the given value is safe HTML. Note that inserting `script` elements into the DOM tree in this way will not cause them to execute the enclosed JavaScript code, because of how these elements are added to the DOM tree.
|
||
|
||
```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>
|
||
|
||
//result
|
||
<h1>html tag</h1>
|
||
<svg onclick="alert('bypassSecurityTrustHtml')" style="display:block">blah</svg>
|
||
```
|
||
4. `bypassSecurityTrustScript` is used to indicate the given value is safe JavaScript. However, we found its behavior to be unpredictable, because we couldn’t to execute JS code in templates using this method.
|
||
|
||
```jsx
|
||
//app.component.ts
|
||
this.trustedScript = this.sanitizer.bypassSecurityTrustScript("alert('bypass Security TrustScript')");
|
||
|
||
//app.component.html
|
||
<script [innerHtml]="trustedScript"></script>
|
||
|
||
//result
|
||
-
|
||
```
|
||
5. `bypassSecurityTrustStyle` is used to indicate the given value is safe CSS. The following example illustrates CSS injection:
|
||
|
||
```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">
|
||
|
||
//result
|
||
Request URL: GET example.com/exfil/a
|
||
```
|
||
|
||
Angular provides a `sanitize` method to sanitize data before displaying it in views. This method employs the security context provided and cleanses the input accordingly. It is, however, crucial to use the correct security context for the specific data and context. For instance, applying a sanitizer with `SecurityContext.URL` on HTML content does not provide protection against dangerous HTML values. In such scenarios, misuse of security context could lead to XSS vulnerabilities.
|
||
|
||
### HTML injection
|
||
|
||
This vulnerability occurs when user input is bound to any of the three properties: `innerHTML`, `outerHTML`, or `iframe` `srcdoc`. While binding to these attributes interprets HTML as it is, the input is sanitized using `SecurityContext.HTML`. Thus, HTML injection is possible, but cross-site scripting (XSS) is not.
|
||
|
||
Example of using `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 टेम्पलेट्स का उपयोग करके पृष्ठों को गतिशील रूप से बनाने के लिए टेम्पलेट्स का लाभ उठाता है। यह दृष्टिकोण Angular को मूल्यांकन करने के लिए टेम्पलेट अभिव्यक्तियों को डबल कर्ली ब्रैकेट्स (`{{}}`) के भीतर संलग्न करने की आवश्यकता होती है। इस तरह, ढांचा अतिरिक्त कार्यक्षमता प्रदान करता है। उदाहरण के लिए, एक टेम्पलेट जैसे `{{1+1}}` 2 के रूप में प्रदर्शित होगा।
|
||
|
||
आमतौर पर, Angular उपयोगकर्ता इनपुट को बचाता है जिसे टेम्पलेट अभिव्यक्तियों के साथ भ्रमित किया जा सकता है (जैसे, \`< > ' " \`\` जैसे वर्ण)। इसका मतलब है कि इस प्रतिबंध को पार करने के लिए अतिरिक्त कदमों की आवश्यकता होती है, जैसे कि ऐसे फ़ंक्शंस का उपयोग करना जो JavaScript स्ट्रिंग ऑब्जेक्ट उत्पन्न करते हैं ताकि ब्लैकलिस्टेड वर्णों का उपयोग करने से बचा जा सके। हालाँकि, इसे प्राप्त करने के लिए, हमें Angular संदर्भ, इसकी विशेषताओं और चर पर विचार करना होगा। इसलिए, एक टेम्पलेट इंजेक्शन हमला इस प्रकार दिखाई दे सकता है:
|
||
```jsx
|
||
//app.component.ts
|
||
const _userInput = '{{constructor.constructor(\'alert(1)\'()}}'
|
||
@Component({
|
||
selector: 'app-root',
|
||
template: '<h1>title</h1>' + _userInput
|
||
})
|
||
```
|
||
जैसा कि ऊपर दिखाया गया है: `constructor` ऑब्जेक्ट `constructor` प्रॉपर्टी के दायरे को संदर्भित करता है, जिससे हमें स्ट्रिंग कंस्ट्रक्टर को कॉल करने और मनमाने कोड को निष्पादित करने की अनुमति मिलती है।
|
||
|
||
#### सर्वर-साइड रेंडरिंग (SSR)
|
||
|
||
CSR के विपरीत, जो ब्राउज़र के DOM में होता है, Angular Universal टेम्पलेट फ़ाइलों के SSR के लिए जिम्मेदार है। ये फ़ाइलें फिर उपयोगकर्ता को भेजी जाती हैं। इस भिन्नता के बावजूद, Angular Universal SSR सुरक्षा को बढ़ाने के लिए CSR में उपयोग किए जाने वाले समान सैनिटाइजेशन तंत्रों को लागू करता है। SSR में एक टेम्पलेट इंजेक्शन भेद्यता को CSR की तरह ही पहचाना जा सकता है, क्योंकि उपयोग की जाने वाली टेम्पलेट भाषा समान है।
|
||
|
||
बेशक, तीसरे पक्ष के टेम्पलेट इंजनों जैसे Pug और Handlebars का उपयोग करते समय नई टेम्पलेट इंजेक्शन भेद्यताओं को पेश करने की संभावना भी है।
|
||
|
||
### XSS
|
||
|
||
#### DOM इंटरफेस
|
||
|
||
जैसा कि पहले कहा गया था, हम _Document_ इंटरफेस का उपयोग करके सीधे DOM तक पहुँच सकते हैं। यदि उपयोगकर्ता इनपुट को पहले से मान्य नहीं किया गया है, तो यह क्रॉस-साइट स्क्रिप्टिंग (XSS) भेद्यताओं की ओर ले जा सकता है।
|
||
|
||
हमने नीचे दिए गए उदाहरणों में `document.write()` और `document.createElement()` विधियों का उपयोग किया:
|
||
```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);
|
||
}
|
||
}
|
||
```
|
||
#### Angular classes
|
||
|
||
Angular में DOM तत्वों के साथ काम करने के लिए कुछ क्लासेस हैं: `ElementRef`, `Renderer2`, `Location` और `Document`। अंतिम दो क्लासेस का विस्तृत विवरण **Open redirects** अनुभाग में दिया गया है। पहले दो के बीच मुख्य अंतर यह है कि `Renderer2` API DOM तत्व और कंपोनेंट कोड के बीच एक एब्स्ट्रैक्शन की परत प्रदान करता है, जबकि `ElementRef` केवल तत्व का संदर्भ रखता है। इसलिए, Angular दस्तावेज़ के अनुसार, `ElementRef` API का उपयोग केवल अंतिम उपाय के रूप में किया जाना चाहिए जब DOM तक सीधी पहुँच की आवश्यकता हो।
|
||
|
||
* `ElementRef` में `nativeElement` प्रॉपर्टी होती है, जिसका उपयोग DOM तत्वों को संशोधित करने के लिए किया जा सकता है। हालाँकि, `nativeElement` का अनुचित उपयोग XSS इंजेक्शन भेद्यता का परिणाम बन सकता है, जैसा कि नीचे दिखाया गया है:
|
||
|
||
```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);
|
||
}
|
||
}
|
||
```
|
||
* हालाँकि `Renderer2` API प्रदान करता है जिसे सुरक्षित रूप से उपयोग किया जा सकता है, भले ही मूल तत्वों तक सीधी पहुँच समर्थित न हो, फिर भी इसमें कुछ सुरक्षा दोष हैं। `Renderer2` के साथ, HTML तत्व पर `setAttribute()` विधि का उपयोग करके विशेषताएँ सेट करना संभव है, जिसमें कोई 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>
|
||
```
|
||
* DOM तत्व की प्रॉपर्टी सेट करने के लिए, आप `Renderer2.setProperty()` विधि का उपयोग कर सकते हैं और 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>
|
||
```
|
||
|
||
हमारे शोध के दौरान, हमने XSS और CSS इंजेक्शन के संबंध में अन्य `Renderer2` विधियों जैसे `setStyle()`, `createComment()`, और `setValue()` के व्यवहार की भी जांच की। हालाँकि, हम इन विधियों के लिए कोई मान्य हमलावर वेक्टर नहीं ढूंढ सके।
|
||
|
||
#### jQuery
|
||
|
||
jQuery एक तेज, छोटा और विशेषताओं से भरपूर JavaScript लाइब्रेरी है जिसे Angular प्रोजेक्ट में HTML DOM ऑब्जेक्ट्स के साथ संशोधन में मदद के लिए उपयोग किया जा सकता है। हालाँकि, जैसा कि ज्ञात है, इस लाइब्रेरी की विधियों का उपयोग XSS भेद्यता प्राप्त करने के लिए किया जा सकता है। Angular प्रोजेक्ट में कुछ कमजोर jQuery विधियों के शोषण के तरीके पर चर्चा करने के लिए, हमने इस उपखंड को जोड़ा है।
|
||
|
||
* `html()` विधि सेट के पहले तत्व की HTML सामग्री प्राप्त करती है या हर मिलान किए गए तत्व की HTML सामग्री सेट करती है। हालाँकि, डिज़ाइन के अनुसार, कोई भी jQuery कंस्ट्रक्टर या विधि जो HTML स्ट्रिंग स्वीकार करती है, संभावित रूप से कोड निष्पादित कर सकती है। यह `<script>` टैग के इंजेक्शन या कोड निष्पादित करने वाले HTML विशेषताओं के उपयोग के माध्यम से हो सकता है जैसा कि उदाहरण में दिखाया गया है।
|
||
|
||
```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>
|
||
```
|
||
* `jQuery.parseHTML()` विधि स्ट्रिंग को DOM नोड्स के सेट में परिवर्तित करने के लिए मूल विधियों का उपयोग करती है, जिसे फिर दस्तावेज़ में डाला जा सकता है।
|
||
|
||
```tsx
|
||
jQuery.parseHTML(data [, context ] [, keepScripts ])
|
||
```
|
||
|
||
जैसा कि पहले उल्लेख किया गया, अधिकांश jQuery APIs जो HTML स्ट्रिंग स्वीकार करते हैं, HTML में शामिल स्क्रिप्ट चलाएंगे। `jQuery.parseHTML()` विधि पार्स की गई HTML में स्क्रिप्ट नहीं चलाती जब तक कि `keepScripts` स्पष्ट रूप से `true` न हो। हालाँकि, अधिकांश वातावरण में अप्रत्यक्ष रूप से स्क्रिप्ट निष्पादित करना संभव है; उदाहरण के लिए, `<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
|
||
|
||
#### DOM interfaces
|
||
|
||
W3C दस्तावेज़ के अनुसार, `window.location` और `document.location` ऑब्जेक्ट्स को आधुनिक ब्राउज़रों में उपनाम के रूप में माना जाता है। यही कारण है कि उनके कुछ विधियों और प्रॉपर्टीज़ का समान कार्यान्वयन होता है, जो `javascript://` स्कीमा हमलों के साथ एक ओपन रीडायरेक्ट और DOM XSS का कारण बन सकता है जैसा कि नीचे उल्लेख किया गया है।
|
||
|
||
* `window.location.href`(और `document.location.href`)
|
||
|
||
वर्तमान DOM स्थान ऑब्जेक्ट प्राप्त करने का मानक तरीका `window.location` का उपयोग करना है। इसका उपयोग ब्राउज़र को एक नए पृष्ठ पर रीडायरेक्ट करने के लिए भी किया जा सकता है। परिणामस्वरूप, इस ऑब्जेक्ट पर नियंत्रण होने से हमें एक ओपन रीडायरेक्ट भेद्यता का शोषण करने की अनुमति मिलती है।
|
||
|
||
```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>
|
||
```
|
||
|
||
शोषण प्रक्रिया निम्नलिखित परिदृश्यों के लिए समान है।
|
||
* `window.location.assign()`(और `document.location.assign()`)
|
||
|
||
यह विधि विंडो को निर्दिष्ट URL पर दस्तावेज़ लोड और प्रदर्शित करने का कारण बनती है। यदि हमारे पास इस विधि पर नियंत्रण है, तो यह ओपन रीडायरेक्ट हमले के लिए एक सिंक हो सकता है।
|
||
|
||
```tsx
|
||
//app.component.ts
|
||
...
|
||
export class AppComponent {
|
||
goToUrl(): void {
|
||
window.location.assign("https://google.com/about")
|
||
}
|
||
}
|
||
```
|
||
* `window.location.replace()`(और `document.location.replace()`)
|
||
|
||
यह विधि वर्तमान संसाधन को प्रदान किए गए URL पर वाले के साथ बदल देती है।
|
||
|
||
यह `assign()` विधि से भिन्न है कि `window.location.replace()` का उपयोग करने के बाद, वर्तमान पृष्ठ सत्र इतिहास में नहीं बचाया जाएगा। हालाँकि, जब हमारे पास इस विधि पर नियंत्रण होता है, तो ओपन रीडायरेक्ट भेद्यता का शोषण करना भी संभव है।
|
||
|
||
```tsx
|
||
//app.component.ts
|
||
...
|
||
export class AppComponent {
|
||
goToUrl(): void {
|
||
window.location.replace("http://google.com/about")
|
||
}
|
||
}
|
||
```
|
||
* `window.open()`
|
||
|
||
`window.open()` विधि एक URL लेती है और इसे एक नए या मौजूदा टैब या विंडो में लोड करती है। इस विधि पर नियंत्रण होने से XSS या ओपन रीडायरेक्ट भेद्यता को ट्रिगर करने का अवसर भी मिल सकता है।
|
||
|
||
```tsx
|
||
//app.component.ts
|
||
...
|
||
export class AppComponent {
|
||
goToUrl(): void {
|
||
window.open("https://google.com/about", "_blank")
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Angular classes
|
||
|
||
* Angular दस्तावेज़ के अनुसार, Angular `Document` DOM दस्तावेज़ के समान है, जिसका अर्थ है कि Angular में क्लाइंट-साइड भेद्यताओं का शोषण करने के लिए DOM दस्तावेज़ के लिए सामान्य वेक्टर का उपयोग करना संभव है। `Document.location` प्रॉपर्टीज़ और विधियाँ सफल ओपन रीडायरेक्ट हमलों के लिए सिंक हो सकती हैं जैसा कि उदाहरण में दिखाया गया है:
|
||
|
||
```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>
|
||
```
|
||
* शोध चरण के दौरान, हमने ओपन रीडायरेक्ट भेद्यताओं के लिए Angular `Location` क्लास की भी समीक्षा की, लेकिन कोई मान्य वेक्टर नहीं मिला। `Location` एक Angular सेवा है जिसका उपयोग एप्लिकेशन वर्तमान URL के साथ बातचीत करने के लिए कर सकते हैं। इस सेवा में दिए गए URL को संशोधित करने के लिए कई विधियाँ हैं - `go()` , `replaceState()`, और `prepareExternalUrl()`। हालाँकि, हम उन्हें बाहरी डोमेन पर रीडायरेक्ट करने के लिए उपयोग नहीं कर सकते। उदाहरण के लिए:
|
||
|
||
```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"));
|
||
}
|
||
}
|
||
```
|
||
|
||
परिणाम: `http://localhost:4200/http://google.com/about`
|
||
* Angular `Router` क्लास मुख्य रूप से उसी डोमेन के भीतर नेविगेट करने के लिए उपयोग की जाती है और एप्लिकेशन में कोई अतिरिक्त भेद्यताएँ नहीं लाती है:
|
||
|
||
```jsx
|
||
//app-routing.module.ts
|
||
const routes: Routes = [
|
||
{ path: '', redirectTo: 'https://google.com', pathMatch: 'full' }]
|
||
```
|
||
|
||
परिणाम: `http://localhost:4200/https:`
|
||
|
||
निम्नलिखित विधियाँ भी डोमेन के दायरे के भीतर नेविगेट करती हैं:
|
||
|
||
```jsx
|
||
const routes: Routes = [ { path: '', redirectTo: 'ROUTE', pathMatch: 'prefix' } ]
|
||
this.router.navigate(['PATH'])
|
||
this.router.navigateByUrl('URL')
|
||
```
|
||
|
||
## References
|
||
|
||
* [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)
|
||
|
||
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|