Angular

चेकलिस्ट

चेकलिस्ट यहाँ से.

अंगुलर क्या है

अंगुलर एक शक्तिशाली और ओपन-सोर्स फ्रंट-एंड फ्रेमवर्क है जिसे Google द्वारा बनाए और बनाए रखा जाता है। यह TypeScript का उपयोग करता है ताकि कोड पठनीयता और डीबगिंग में सुधार किया जा सके। मजबूत सुरक्षा तंत्र के साथ, अंगुलर XSS और ओपन रीडाइरेक्ट्स जैसी सामान्य क्लाइंट-साइड सुरक्षा दोषों को रोकता है। यह सर्वर-साइड पर भी उपयोग किया जा सकता है, जिससे सुरक्षा संबंधित विचारणाएं दोनों कोणों से महत्वपूर्ण होती हैं।

फ्रेमवर्क वास्तुकला

अंगुलर की मूल अवधारणाओं को बेहतर समझने के लिए, चलिए इसके महत्वपूर्ण अवधारणाओं पर चर्चा करते हैं।

सामान्य अंगुलर परियोजना आम तौर पर इस तरह दिखती है:

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 एप्लिकेशन में कम से कम एक कॉम्पोनेंट होता है, जो डोम के साथ एक कॉम्पोनेंट वर्ग (AppComponent) को जोड़ता है। प्रत्येक कॉम्पोनेंट एक क्लास को परिभाषित करता है जिसमें एप्लिकेशन डेटा और तर्क होता है, और एक HTML टेम्पलेट के साथ जुड़ा होता है जो एक लक्षित वातावरण में प्रदर्शित करने के लिए एक दृश्य को परिभाषित करता है। @Component() डेकोरेटर क्लास को तुरंत नीचे कॉम्पोनेंट के रूप में पहचानता है, और टेम्पलेट और संबंधित कॉम्पोनेंट-विशिष्ट मेटाडेटा प्रदान करता है। AppComponent को app.component.ts फ़ाइल में परिभाषित किया गया है।

Angular NgModules एक संदर्भ संकलन को घोषित करते हैं जो एक एप्लिकेशन डोम, एक कार्यप्रवाह, या एक संबंधित सेट क्षमताओं के लिए समर्पित है। प्रत्येक Angular एप्लिकेशन में एक रूट मॉड्यूल होता है, सामान्य रूप से AppModule नामित, जो एप्लिकेशन को लॉन्च करने वाली बूटस्ट्रैप तंत्र प्रदान करता है। एक एप्लिकेशन आम तौर पर कई कार्यात्मक मॉड्यूल शामिल करता है। AppModule को app.module.ts फ़ाइल में परिभाषित किया गया है।

Angular Router NgModule एक सेवा प्रदान करता है जो आपको अपने एप्लिकेशन में विभिन्न एप्लिकेशन स्थितियों और दृश्य वर्गीकृतियों के बीच एक नेविगेशन पथ परिभाषित करने देता है। RouterModule को app-routing.module.ts फ़ाइल में परिभाषित किया गया है।

एक विशेष दृश्य से संबंधित नहीं होने वाले डेटा या तर्क के लिए, और जो आप कॉम्पोनेंटों के बीच साझा करना चाहते हैं, उसके लिए आप एक सेवा क्लास बनाते हैं। एक सेवा क्लास परिभाषा के तुरंत पहले @Injectable() डेकोरेटर से पहले होती है। डेकोरेटर उन मेटाडेटा प्रदान करता है जो अन्य प्रदाताओं को आपकी क्लास में डिपेंडेंसी के रूप में इंजेक्ट करने की अनुमति देता है। डिपेंडेंसी इंजेक्शन (DI) आपको अपने कॉम्पोनेंट क्लास को पतला और कुशल रखने देता है। वे सर्वर से डेटा नहीं लेते, उपयोगकर्ता इनपुट को मान्यता प्रदान नहीं करते, या सीधे कंसोल में लॉग नहीं करते; वे ऐसी कार्यों को सेवाओं को सौंपते हैं।

सोर्समैप कॉन्फ़िगरेशन

Angular फ़्रेमवर्क tsconfig.json विकल्पों का पालन करके TypeScript फ़ाइलों को जावास्क्रिप्ट कोड में अनुवादित करता है और फिर angular.json कॉन्फ़िगरेशन के साथ एक परियोजना बनाता है। angular.json फ़ाइल को देखते हुए, हमने एक सोर्समैप को सक्षम या अक्षम करने का विकल्प देखा। Angular दस्तावेज़ीकरण के अनुसार, डिफ़ॉल्ट कॉन्फ़िगरेशन में स्क्रिप्ट के लिए एक सोर्समैप फ़ाइल सक्षम है और डिफ़ॉल्ट रूप से छुपा नहीं है:

"sourceMap": {
"scripts": true,
"styles": true,
"vendor": false,
"hidden": false
}

आम तौर पर, sourcemap फ़ाइल debugging के उद्देश्यों के लिए उपयोग की जाती है क्योंकि यह उत्पन्न फ़ाइलों को उनकी मूल फ़ाइलों से मैप करती है। इसलिए, इन्हें उत्पादन वातावरण में उपयोग करना सिफारिश नहीं है। यदि sourcemaps सक्षम हैं, तो यह Angular परियोजना की मूल स्थिति को प्रतिबिंबित करके पढ़ने में सुधार करता है और फ़ाइल विश्लेषण में मदद करता है। हालांकि, यदि वे अक्षम हैं, तो समीक्षक एक कंपाइल्ड JavaScript फ़ाइल का मैन्युअल विश्लेषण कर सकता है अंटी-सुरक्षा पैटर्न खोजकर।

इसके अतिरिक्त, एक Angular परियोजना के साथ एक कंपाइल्ड JavaScript फ़ाइल को ब्राउज़र डेवलपर टूल्स → स्रोत (या डीबगर और स्रोत) → [id].main.js में पाया जा सकता है। सक्षम विकल्पों के आधार पर, इस फ़ाइल में अंत में निम्नलिखित पंक्ति शामिल हो सकती है //# sourceMappingURL=[id].main.js.map या यह नहीं हो सकता है, अगर छिपा हुआ विकल्प सत्य पर सेट किया गया है। फिर भी, यदि स्क्रिप्ट के लिए sourcemap अक्षम है, तो परीक्षण अधिक जटिल हो जाता है, और हम फ़ाइल प्राप्त नहीं कर सकते। इसके अतिरिक्त, sourcemap परियोजना निर्माण के दौरान सक्षम किया जा सकता है जैसे ng build --source-map

//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>परीक्षण</h1></div>

टेम्पलेट इंजेक्शन

क्लाइंट-साइड रेंडरिंग (CSR)

एंगुलर डायनामिक रूप से पृष्ठ निर्मित करने के लिए टेम्पलेट का उपयोग करता है। इस दृष्टिकोण में, एंगुलर को मूल्यांकन के लिए टेम्पलेट अभिव्यक्तियों को डबल कर्ली ब्रैकेट्स ({{}}) में बंधने की आवश्यकता होती है। इस तरह, फ्रेमवर्क अतिरिक्त कार्यक्षमता प्रदान करता है। उदाहरण के लिए, एक टेम्पलेट जैसे {{1+1}} को 2 के रूप में प्रदर्शित किया जाएगा।

सामान्यत: एंगुलर उपयोगकर्ता इनपुट को टेम्पलेट अभिव्यक्तियों के साथ गलतफहमी कर सकता है (जैसे कि `< > ' " ``) को भगोड़ा बनाने के लिए उपयोग करता है। इसका अर्थ है कि इस प्रतिबंध को दूर करने के लिए अतिरिक्त कदम आवश्यक होते हैं, जैसे कि ब्लैकलिस्टेड वर्णों का उपयोग न करने के लिए जावास्क्रिप्ट स्ट्रिंग ऑब्जेक्ट जेनरेट करने के लिए फ़ंक्शन का उपयोग करना। हालांकि, इसे प्राप्त करने के लिए, हमें एंगुलर संदर्भ, इसकी गुणधर्मों और चरों को विचार में लेना चाहिए। इसलिए, एक टेम्पलेट इंजेक्शन हमला निम्नलिखित रूप में प्रकट हो सकता है:

//app.component.ts
const _userInput = '{{constructor.constructor(\'alert(1)\'()}}'
@Component({
selector: 'app-root',
template: '<h1>title</h1>' + _userInput
})

सर्वर-साइड रेंडरिंग (SSR)

CSR के विपरीत, जो ब्राउज़र के DOM में होता है, ऐंगुलर यूनिवर्सल SSR के लिए टेम्पलेट फ़ाइलों का जिम्मेदार है। ये फ़ाइलें फिर उपयोगकर्ता को पहुँचाई जाती हैं। इस भिन्नता के बावजूद, ऐंगुलर यूनिवर्सल एक समान सैनिटाइज़ेशन तंत्र का उपयोग करता है जो CSR में उपयोग किया जाता है ताकि SSR सुरक्षा में सुधार किया जा सके। SSR में टेम्पलेट इंजेक्शन संरचना को CSR में की तरह ही पहचाना जा सकता है, क्योंकि उपयोग की जाने वाली टेम्पलेट भाषा एक ही है।

बिल्कुल, तीसरी पक्षीय टेम्पलेट इंजेक्शन संरचनाओं को लागू करते समय नए टेम्पलेट इंजेक्शन संरचनाओं का भी संभावना है जैसे Pug और Handlebars।

XSS

DOM इंटरफेस

पहले ही कहा गया है, हम Document इंटरफेस का सीधा उपयोग करके DOM तक पहुँच सकते हैं। यदि उपयोगकर्ता इनपुट पहले सत्यापित नहीं किया गया है, तो यह क्रॉस-साइट स्क्रिप्टिंग (XSS) संरचनाओं की संभावना है।

हमने नीचे दिए गए उदाहरणों में document.write() और document.createElement() विधियों का उपयोग किया:

//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 elements के साथ काम करने के लिए कुछ classes हैं: ElementRef, Renderer2, Location और Document। पिछले दो classes का विस्तृत विवरण Open redirects खंड में दिया गया है। पहले दो के बीच मुख्य अंतर यह है कि Renderer2 API DOM element और component code के बीच एक एक्सट्रेक्शन परत प्रदान करती है, जबकि ElementRef केवल तत्व का संदर्भ रखती है। इसलिए, Angular दस्तावेज़ के अनुसार, ElementRef API को केवल तब उपयोग किया जाना चाहिए जब सीधा DOM तक पहुंच की आवश्यकता हो।

  • ElementRef में nativeElement property होती है, जिसका उपयोग DOM elements को मैनिपुलेट करने के लिए किया जा सकता है। हालांकि, nativeElement का गलत उपयोग एक XSS इन्जेक्शन संरक्षण की कमी में परिणाम दे सकता है, जैसा कि नीचे दिखाया गया है:

//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 के साथ, HTML element पर एट्रिब्यूट सेट करने के लिए setAttribute() method का उपयोग किया जा सकता है, जिसमें XSS रोकथाम तंत्र नहीं है।

//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 element की property सेट करने के लिए, Renderer2.setProperty() method का उपयोग किया जा सकता है और XSS हमला ट्रिगर किया जा सकता है:

//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>

हमारे अनुसंधान के दौरान, हमने अन्य Renderer2 methods का व्यवहार भी जांचा, जैसे setStyle(), createComment(), और setValue(), XSS और CSS इन्जेक्शन के संबंध में। हालांकि, हमने इन methods के लिए कोई वैध हमला वेक्टर नहीं मिला क्योंकि उनकी कार्यात्मक सीमाओं के कारण।

jQuery

jQuery एक तेज, छोटा, और सुविधासम्पन्न JavaScript लाइब्रेरी है जो Angular परियोजना में HTML DOM objects को मानिपुलेट करने में मदद के लिए उपयोग किया जा सकता है। हालांकि, जैसा कि जाना जाता है, इस लाइब्रेरी के methods XSS संरक्षण को प्राप्त करने के लिए उपयोग किया जा सकता है। कुछ विकल्पनीय jQuery methods को कैसे एक्सप्लॉइट किया जा सकता है Angular परियोजनाओं में, इसे चर्चा करने के लिए हमने यह उपखंड जोड़ा।

  • html() method में पहले मिले हुए elements के HTML contents को प्राप्त करता है या हर मिले हुए element के HTML contents को सेट करता है। हालांकि, डिज़ाइन के अनुसार, किसी भी jQuery constructor या method जो एक HTML string को स्वीकार करता है, संभावित रूप से कोड को निष्पादित कर सकता है। यह <script> tags का इन्जेक्शन या कोड निष्पादन करने वाले HTML attributes का उपयोग करके हो सकता है जैसा कि निम्नलिखित उदाहरण में दिखाया गया है।

//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() method नेटिव methods का उपयोग करता है ताकि स्ट्रिंग को DOM nodes के सेट में बदल सके, जो फिर दस्तावेज़ में डाला जा सकता है।

jQuery.parseHTML(data [, context ] [, keepScripts ])

पहले ही कहा गया है, ज्यादातर jQuery APIs जो HTML strings को स्वीकार करते हैं, वे HTML में शामिल स्क्रिप्ट्स को चला सकते हैं। jQuery.parseHTML() method पार्स किए गए HTML में स्क्रिप्ट्स को नहीं चलाता है जब तक keepScripts विशेष रूप से true नहीं है। हालांकि, इसके बावजूद, अधिकांश परिवेशों में स्क्रिप्ट्स को अप्रत्यक्ष रूप से निष्पादित करना भी संभव है; उदाहरण के रूप में <img onerror> एट्रिब्यूट के माध्यम से।

//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>

Last updated