@nx-all/nx-html-parser 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +149 -0
- package/dist/libs/nx-html-parser/README.md +149 -0
- package/dist/libs/nx-html-parser/fesm2022/nx-all-nx-html-parser.mjs +53 -0
- package/dist/libs/nx-html-parser/fesm2022/nx-all-nx-html-parser.mjs.map +1 -0
- package/dist/libs/nx-html-parser/index.d.ts +6 -0
- package/dist/libs/nx-html-parser/index.d.ts.map +1 -0
- package/package.json +76 -0
package/README.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# nx-html-parser
|
|
2
|
+
|
|
3
|
+
## HTML Security Parser
|
|
4
|
+
|
|
5
|
+
`nx-html-parser` is a lightweight Angular HTML security parser that validates HTML input against **OWASP guidelines**.
|
|
6
|
+
|
|
7
|
+
It helps prevent rendering unsafe or malicious HTML by filtering prohibited tags before content is rendered in the DOM.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- OWASP-compliant HTML validation
|
|
14
|
+
- Detects prohibited and unsafe HTML tags
|
|
15
|
+
- Prevents malicious HTML rendering
|
|
16
|
+
- Angular dependency injection support
|
|
17
|
+
- Lightweight and easy to integrate
|
|
18
|
+
- Safe handling of dynamic HTML content
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Prohibited Tags
|
|
23
|
+
|
|
24
|
+
The following HTML tags are blocked and will trigger a security validation error:
|
|
25
|
+
|
|
26
|
+
| Tags |
|
|
27
|
+
|------|
|
|
28
|
+
| `script` |
|
|
29
|
+
| `img` |
|
|
30
|
+
| `body` |
|
|
31
|
+
| `a` |
|
|
32
|
+
| `iframe` |
|
|
33
|
+
| `svg` |
|
|
34
|
+
| `object` |
|
|
35
|
+
| `embed` |
|
|
36
|
+
| `details` |
|
|
37
|
+
| `video` |
|
|
38
|
+
| `audio` |
|
|
39
|
+
| `source` |
|
|
40
|
+
| `input` |
|
|
41
|
+
| `button` |
|
|
42
|
+
| `textarea` |
|
|
43
|
+
| `select` |
|
|
44
|
+
| `link` |
|
|
45
|
+
| `style` |
|
|
46
|
+
| `base` |
|
|
47
|
+
| `form` |
|
|
48
|
+
| `animate` |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install --save-dev nx-html-parser
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
### Import the Parser
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
import { HtmlParser } from 'nx-html-parser'
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Angular Example
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { Component, inject, signal } from '@angular/core';
|
|
70
|
+
import { RouterModule } from '@angular/router';
|
|
71
|
+
import { HtmlParser } from 'nx-html-parser';
|
|
72
|
+
import { SafeHtml } from '@angular/platform-browser';
|
|
73
|
+
|
|
74
|
+
@Component({
|
|
75
|
+
selector: 'app-root',
|
|
76
|
+
imports: [RouterModule],
|
|
77
|
+
templateUrl: './app.html',
|
|
78
|
+
styleUrl: './app.scss',
|
|
79
|
+
})
|
|
80
|
+
export class App {
|
|
81
|
+
|
|
82
|
+
public htmlParser = inject(HtmlParser);
|
|
83
|
+
|
|
84
|
+
htmlContent = signal('<p>Hello!</p><strong>Valid HTML</strong>');
|
|
85
|
+
|
|
86
|
+
errorMessage = signal('');
|
|
87
|
+
|
|
88
|
+
parseContent(content: string): string | SafeHtml {
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
|
|
92
|
+
const parsed = this.htmlParser(content);
|
|
93
|
+
|
|
94
|
+
return parsed;
|
|
95
|
+
|
|
96
|
+
} catch (error: any) {
|
|
97
|
+
|
|
98
|
+
console.error(error);
|
|
99
|
+
|
|
100
|
+
return '';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
injectProhibitedTag(tag: string) {
|
|
105
|
+
|
|
106
|
+
const htmlTag = `<${tag}>Blocked content</${tag}>`;
|
|
107
|
+
|
|
108
|
+
this.htmlContent.set(this.htmlParser(htmlTag));
|
|
109
|
+
|
|
110
|
+
this.errorMessage.set(
|
|
111
|
+
`Security Error: The tag <${tag}> is prohibited by OWASP guidelines.`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Development
|
|
120
|
+
|
|
121
|
+
Build the library locally:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
ng build nx-html-parser
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Run tests:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
nx test nx-html-parser
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Run lint:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
nx lint nx-html-parser
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
## Security
|
|
141
|
+
|
|
142
|
+
This package is designed to help reduce risks associated with:
|
|
143
|
+
|
|
144
|
+
- **Cross-site scripting (XSS)**
|
|
145
|
+
- **Unsafe DOM rendering**
|
|
146
|
+
- **Dynamic HTML injection**
|
|
147
|
+
- **Malicious embedded content**
|
|
148
|
+
|
|
149
|
+
Validation rules are based on **OWASP security recommendations**.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# nx-html-parser
|
|
2
|
+
|
|
3
|
+
## HTML Security Parser
|
|
4
|
+
|
|
5
|
+
`nx-html-parser` is a lightweight Angular HTML security parser that validates HTML input against **OWASP guidelines**.
|
|
6
|
+
|
|
7
|
+
It helps prevent rendering unsafe or malicious HTML by filtering prohibited tags before content is rendered in the DOM.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- OWASP-compliant HTML validation
|
|
14
|
+
- Detects prohibited and unsafe HTML tags
|
|
15
|
+
- Prevents malicious HTML rendering
|
|
16
|
+
- Angular dependency injection support
|
|
17
|
+
- Lightweight and easy to integrate
|
|
18
|
+
- Safe handling of dynamic HTML content
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Prohibited Tags
|
|
23
|
+
|
|
24
|
+
The following HTML tags are blocked and will trigger a security validation error:
|
|
25
|
+
|
|
26
|
+
| Tags |
|
|
27
|
+
|------|
|
|
28
|
+
| `script` |
|
|
29
|
+
| `img` |
|
|
30
|
+
| `body` |
|
|
31
|
+
| `a` |
|
|
32
|
+
| `iframe` |
|
|
33
|
+
| `svg` |
|
|
34
|
+
| `object` |
|
|
35
|
+
| `embed` |
|
|
36
|
+
| `details` |
|
|
37
|
+
| `video` |
|
|
38
|
+
| `audio` |
|
|
39
|
+
| `source` |
|
|
40
|
+
| `input` |
|
|
41
|
+
| `button` |
|
|
42
|
+
| `textarea` |
|
|
43
|
+
| `select` |
|
|
44
|
+
| `link` |
|
|
45
|
+
| `style` |
|
|
46
|
+
| `base` |
|
|
47
|
+
| `form` |
|
|
48
|
+
| `animate` |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install --save-dev nx-html-parser
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
### Import the Parser
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
import { HtmlParser } from 'nx-html-parser'
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Angular Example
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { Component, inject, signal } from '@angular/core';
|
|
70
|
+
import { RouterModule } from '@angular/router';
|
|
71
|
+
import { HtmlParser } from 'nx-html-parser';
|
|
72
|
+
import { SafeHtml } from '@angular/platform-browser';
|
|
73
|
+
|
|
74
|
+
@Component({
|
|
75
|
+
selector: 'app-root',
|
|
76
|
+
imports: [RouterModule],
|
|
77
|
+
templateUrl: './app.html',
|
|
78
|
+
styleUrl: './app.scss',
|
|
79
|
+
})
|
|
80
|
+
export class App {
|
|
81
|
+
|
|
82
|
+
public htmlParser = inject(HtmlParser);
|
|
83
|
+
|
|
84
|
+
htmlContent = signal('<p>Hello!</p><strong>Valid HTML</strong>');
|
|
85
|
+
|
|
86
|
+
errorMessage = signal('');
|
|
87
|
+
|
|
88
|
+
parseContent(content: string): string | SafeHtml {
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
|
|
92
|
+
const parsed = this.htmlParser(content);
|
|
93
|
+
|
|
94
|
+
return parsed;
|
|
95
|
+
|
|
96
|
+
} catch (error: any) {
|
|
97
|
+
|
|
98
|
+
console.error(error);
|
|
99
|
+
|
|
100
|
+
return '';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
injectProhibitedTag(tag: string) {
|
|
105
|
+
|
|
106
|
+
const htmlTag = `<${tag}>Blocked content</${tag}>`;
|
|
107
|
+
|
|
108
|
+
this.htmlContent.set(this.htmlParser(htmlTag));
|
|
109
|
+
|
|
110
|
+
this.errorMessage.set(
|
|
111
|
+
`Security Error: The tag <${tag}> is prohibited by OWASP guidelines.`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Development
|
|
120
|
+
|
|
121
|
+
Build the library locally:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
ng build nx-html-parser
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Run tests:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
nx test nx-html-parser
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Run lint:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
nx lint nx-html-parser
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
## Security
|
|
141
|
+
|
|
142
|
+
This package is designed to help reduce risks associated with:
|
|
143
|
+
|
|
144
|
+
- **Cross-site scripting (XSS)**
|
|
145
|
+
- **Unsafe DOM rendering**
|
|
146
|
+
- **Dynamic HTML injection**
|
|
147
|
+
- **Malicious embedded content**
|
|
148
|
+
|
|
149
|
+
Validation rules are based on **OWASP security recommendations**.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { InjectionToken, signal } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
const invalidHtmlTags = [
|
|
4
|
+
'script',
|
|
5
|
+
'img',
|
|
6
|
+
'body',
|
|
7
|
+
'a',
|
|
8
|
+
'iframe',
|
|
9
|
+
'svg',
|
|
10
|
+
'object',
|
|
11
|
+
'embed',
|
|
12
|
+
'details',
|
|
13
|
+
'video',
|
|
14
|
+
'audio',
|
|
15
|
+
'source',
|
|
16
|
+
'input',
|
|
17
|
+
'button',
|
|
18
|
+
'textarea',
|
|
19
|
+
'select',
|
|
20
|
+
'link',
|
|
21
|
+
'style',
|
|
22
|
+
'base',
|
|
23
|
+
'form',
|
|
24
|
+
'animate',
|
|
25
|
+
];
|
|
26
|
+
function checkInvalidHTMLTags(str) {
|
|
27
|
+
const regex = new RegExp(`<\\s*\\/??\\s*(${invalidHtmlTags.join('|')})\\b`, 'i');
|
|
28
|
+
return regex.test(str);
|
|
29
|
+
}
|
|
30
|
+
function securedHTML(input) {
|
|
31
|
+
if (!input()) {
|
|
32
|
+
const error = new Error('Input cannot be empty');
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
if (checkInvalidHTMLTags(input())) {
|
|
36
|
+
const error = new Error('XSS : Insecure HTML tags detected as per OWASP guidelines');
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
return input();
|
|
40
|
+
}
|
|
41
|
+
const HtmlParser = new InjectionToken('secureHTML', {
|
|
42
|
+
providedIn: 'root',
|
|
43
|
+
factory: () => {
|
|
44
|
+
return (rawString) => securedHTML(signal(rawString));
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Generated bundle index. Do not edit.
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
export { HtmlParser };
|
|
53
|
+
//# sourceMappingURL=nx-all-nx-html-parser.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nx-all-nx-html-parser.mjs","sources":["../../../../libs/nx-html-parser/src/lib/service/html-parser/html-parser.ts","../../../../libs/nx-html-parser/src/nx-all-nx-html-parser.ts"],"sourcesContent":["import { InjectionToken, Signal, signal } from '@angular/core';\r\n\r\nconst invalidHtmlTags = [\r\n 'script',\r\n 'img',\r\n 'body',\r\n 'a',\r\n 'iframe',\r\n 'svg',\r\n 'object',\r\n 'embed',\r\n 'details',\r\n 'video',\r\n 'audio',\r\n 'source',\r\n 'input',\r\n 'button',\r\n 'textarea',\r\n 'select',\r\n 'link',\r\n 'style',\r\n 'base',\r\n 'form',\r\n 'animate',\r\n];\r\n\r\n\r\n\r\nfunction checkInvalidHTMLTags(str: string): boolean {\r\n const regex = new RegExp(`<\\\\s*\\\\/??\\\\s*(${invalidHtmlTags.join('|')})\\\\b`, 'i');\r\n return regex.test(str);\r\n}\r\n\r\nfunction securedHTML(input: Signal<string>): string {\r\n if (!input()) {\r\n const error = new Error('Input cannot be empty');\r\n throw error;\r\n }\r\n\r\n if (checkInvalidHTMLTags(input())) {\r\n const error = new Error('XSS : Insecure HTML tags detected as per OWASP guidelines');\r\n throw error;\r\n }\r\n return input();\r\n}\r\n\r\nexport const HtmlParser = new InjectionToken<(input: string) => string>('secureHTML', {\r\n providedIn: 'root',\r\n factory: () => {\r\n return (rawString: string) => securedHTML(signal(rawString));\r\n },\r\n});\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;AAEA,MAAM,eAAe,GAAG;IACtB,QAAQ;IACR,KAAK;IACL,MAAM;IACN,GAAG;IACH,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,OAAO;IACP,SAAS;IACT,OAAO;IACP,OAAO;IACP,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,SAAS;CACV;AAID,SAAS,oBAAoB,CAAC,GAAW,EAAA;AACvC,IAAA,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,kBAAkB,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA,IAAA,CAAM,EAAE,GAAG,CAAC;AAChF,IAAA,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;AACxB;AAEA,SAAS,WAAW,CAAC,KAAqB,EAAA;AACxC,IAAA,IAAI,CAAC,KAAK,EAAE,EAAE;AACZ,QAAA,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,uBAAuB,CAAC;AAChD,QAAA,MAAM,KAAK;IACb;AAEA,IAAA,IAAI,oBAAoB,CAAC,KAAK,EAAE,CAAC,EAAE;AACjC,QAAA,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,2DAA2D,CAAC;AACpF,QAAA,MAAM,KAAK;IACb;IACA,OAAO,KAAK,EAAE;AAChB;MAEa,UAAU,GAAG,IAAI,cAAc,CAA4B,YAAY,EAAE;AACpF,IAAA,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,MAAK;AACZ,QAAA,OAAO,CAAC,SAAiB,KAAK,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9D,CAAC;AACF,CAAA;;ACnDD;;AAEG;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sources":["../../../libs/nx-html-parser/src/lib/service/html-parser/html-parser.ts"],"mappings":";;AA8CA,cAAA,UAAa,EAAA,cAAU;;;;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nx-all/nx-html-parser",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"dist/",
|
|
10
|
+
"README.md",
|
|
11
|
+
"index.js",
|
|
12
|
+
"index.d.ts"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "nx build nx-html-parser",
|
|
16
|
+
"test": "nx test nx-html-parser",
|
|
17
|
+
"start": "nx serve app-html-parser"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/paragkulkarni/nx-html-parser.git"
|
|
22
|
+
},
|
|
23
|
+
"author": {
|
|
24
|
+
"name": "Parag Kulkarni",
|
|
25
|
+
"email": "parag15363@gmail.com"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@angular/common": "~20.3.0",
|
|
29
|
+
"@angular/compiler": "~20.3.0",
|
|
30
|
+
"@angular/core": "~20.3.0",
|
|
31
|
+
"@angular/forms": "~20.3.0",
|
|
32
|
+
"@angular/platform-browser": "~20.3.0",
|
|
33
|
+
"@angular/platform-browser-dynamic": "~20.3.0",
|
|
34
|
+
"@angular/router": "~20.3.0",
|
|
35
|
+
"rxjs": "~7.8.0",
|
|
36
|
+
"zone.js": "~0.15.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@angular-devkit/core": "~20.3.0",
|
|
40
|
+
"@angular-devkit/schematics": "~20.3.0",
|
|
41
|
+
"@angular/build": "~20.3.0",
|
|
42
|
+
"@angular/cli": "~20.3.0",
|
|
43
|
+
"@angular/compiler-cli": "~20.3.0",
|
|
44
|
+
"@angular/language-service": "~20.3.0",
|
|
45
|
+
"@eslint/js": "^9.8.0",
|
|
46
|
+
"@nx/angular": "21.6.11",
|
|
47
|
+
"@nx/eslint": "21.6.11",
|
|
48
|
+
"@nx/eslint-plugin": "21.6.11",
|
|
49
|
+
"@nx/jest": "21.6.11",
|
|
50
|
+
"@nx/js": "21.6.11",
|
|
51
|
+
"@nx/web": "21.6.11",
|
|
52
|
+
"@nx/workspace": "21.6.11",
|
|
53
|
+
"@schematics/angular": "~20.3.0",
|
|
54
|
+
"@swc-node/register": "~1.9.1",
|
|
55
|
+
"@swc/core": "~1.5.7",
|
|
56
|
+
"@swc/helpers": "~0.5.11",
|
|
57
|
+
"@types/jest": "^29.5.12",
|
|
58
|
+
"@types/node": "18.16.9",
|
|
59
|
+
"@typescript-eslint/utils": "^8.40.0",
|
|
60
|
+
"angular-eslint": "^20.3.0",
|
|
61
|
+
"eslint": "^9.8.0",
|
|
62
|
+
"eslint-config-prettier": "^10.0.0",
|
|
63
|
+
"jest": "^29.7.0",
|
|
64
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
65
|
+
"jest-preset-angular": "~14.6.1",
|
|
66
|
+
"jest-util": "^29.7.0",
|
|
67
|
+
"ng-packagr": "~20.3.0",
|
|
68
|
+
"nx": "21.6.11",
|
|
69
|
+
"prettier": "^2.6.2",
|
|
70
|
+
"ts-jest": "^29.1.0",
|
|
71
|
+
"ts-node": "10.9.1",
|
|
72
|
+
"tslib": "^2.3.0",
|
|
73
|
+
"typescript": "~5.9.2",
|
|
74
|
+
"typescript-eslint": "^8.40.0"
|
|
75
|
+
}
|
|
76
|
+
}
|