ngx-security-audit 1.0.0
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/LICENSE +21 -0
- package/README.md +385 -0
- package/bin/ngx-security-audit.js +192 -0
- package/package.json +63 -0
- package/src/config.js +65 -0
- package/src/index.js +54 -0
- package/src/reporters/console-reporter.js +111 -0
- package/src/reporters/html-reporter.js +191 -0
- package/src/reporters/index.js +23 -0
- package/src/reporters/json-reporter.js +10 -0
- package/src/reporters/sarif-reporter.js +111 -0
- package/src/rules/angular-config-rules.js +280 -0
- package/src/rules/auth-rules.js +153 -0
- package/src/rules/best-practice-rules.js +283 -0
- package/src/rules/http-rules.js +163 -0
- package/src/rules/index.js +25 -0
- package/src/rules/injection-rules.js +134 -0
- package/src/rules/sensitive-data-rules.js +168 -0
- package/src/rules/xss-rules.js +162 -0
- package/src/scanner.js +154 -0
- package/src/utils/file-utils.js +138 -0
- package/src/utils/severity.js +86 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 noredinebahri
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# 🛡️ ngx-security-audit
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/ngx-security-audit)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
[](https://owasp.org/www-project-top-ten/)
|
|
7
|
+
|
|
8
|
+
**Enterprise-grade Angular security auditing tool.** Static analysis scanner that detects XSS, CSRF, injection, sensitive data exposure, misconfigurations, and **34+ security vulnerabilities** in Angular projects. Generates detailed reports with severity levels for CI/CD pipeline integration.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## ✨ Features
|
|
13
|
+
|
|
14
|
+
- 🔍 **34+ Security Rules** — Comprehensive checks across 7 security categories
|
|
15
|
+
- 🎯 **Angular-Specific** — Deep understanding of Angular's security model, DomSanitizer, route guards, interceptors
|
|
16
|
+
- 📊 **4 Report Formats** — Console (colored), JSON (machine), HTML (stakeholders), SARIF (GitHub/Azure DevOps)
|
|
17
|
+
- 🏗️ **CI/CD Ready** — Exit codes, threshold configuration, pipeline examples for GitHub Actions, Azure DevOps, GitLab CI
|
|
18
|
+
- 📈 **Security Scoring** — 0-100 score with A-F grades for easy tracking over time
|
|
19
|
+
- ⚙️ **Configurable** — .ngsecurityrc.json support, rule overrides, custom include/exclude patterns
|
|
20
|
+
- 🌐 **OWASP Aligned** — Every rule mapped to OWASP Top 10 2021 and CWE identifiers
|
|
21
|
+
- 🚀 **Zero Config** — Works out of the box on any Angular project
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 📦 Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Global installation (recommended for CLI usage)
|
|
29
|
+
npm install -g ngx-security-audit
|
|
30
|
+
|
|
31
|
+
# Local installation (for project integration)
|
|
32
|
+
npm install --save-dev ngx-security-audit
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 🚀 Quick Start
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Scan current Angular project
|
|
41
|
+
ngx-security-audit scan
|
|
42
|
+
|
|
43
|
+
# Scan a specific path
|
|
44
|
+
ngx-security-audit scan /path/to/angular/project
|
|
45
|
+
|
|
46
|
+
# Generate HTML report
|
|
47
|
+
ngx-security-audit scan --format html --output report.html
|
|
48
|
+
|
|
49
|
+
# Use in CI/CD with exit code
|
|
50
|
+
ngx-security-audit scan --threshold high
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 📋 Commands
|
|
56
|
+
|
|
57
|
+
### `scan` — Run security audit
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
ngx-security-audit scan [path] [options]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
| Option | Description | Default |
|
|
64
|
+
|--------|-------------|---------|
|
|
65
|
+
| `-f, --format <format>` | Report format: `console`, `json`, `html`, `sarif` | `console` |
|
|
66
|
+
| `-o, --output <file>` | Write report to file | stdout |
|
|
67
|
+
| `-t, --threshold <level>` | Fail threshold: `critical`, `high`, `medium`, `low`, `info` | `high` |
|
|
68
|
+
| `-v, --verbose` | Enable verbose output | `false` |
|
|
69
|
+
| `--disable-rules <rules>` | Comma-separated rule IDs to disable | none |
|
|
70
|
+
| `--include <patterns>` | Comma-separated glob patterns to include | `src/**/*.ts,src/**/*.html` |
|
|
71
|
+
| `--exclude <patterns>` | Comma-separated glob patterns to exclude | none |
|
|
72
|
+
|
|
73
|
+
### `rules` — List available rules
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# List all rules
|
|
77
|
+
ngx-security-audit rules
|
|
78
|
+
|
|
79
|
+
# Filter by category
|
|
80
|
+
ngx-security-audit rules --category XSS
|
|
81
|
+
|
|
82
|
+
# Output as JSON
|
|
83
|
+
ngx-security-audit rules --json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `init` — Create config file
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
ngx-security-audit init
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 🔒 Security Rules (34 Rules)
|
|
95
|
+
|
|
96
|
+
### XSS — Cross-Site Scripting (4 rules)
|
|
97
|
+
|
|
98
|
+
| Rule ID | Severity | Description |
|
|
99
|
+
|---------|----------|-------------|
|
|
100
|
+
| `xss/bypass-security-trust` | 🔴 CRITICAL | Detects `bypassSecurityTrustHtml/Script/Style/Url/ResourceUrl` usage |
|
|
101
|
+
| `xss/inner-html-binding` | 🟡 MEDIUM | Detects `[innerHTML]` bindings in templates |
|
|
102
|
+
| `xss/dom-manipulation` | 🟠 HIGH | Direct DOM manipulation via `nativeElement`, `document.write` |
|
|
103
|
+
| `xss/unsafe-template-concat` | 🔴 CRITICAL | Dynamic template construction enabling template injection |
|
|
104
|
+
|
|
105
|
+
### Injection (4 rules)
|
|
106
|
+
|
|
107
|
+
| Rule ID | Severity | Description |
|
|
108
|
+
|---------|----------|-------------|
|
|
109
|
+
| `injection/eval-usage` | 🔴 CRITICAL | `eval()` usage detection |
|
|
110
|
+
| `injection/function-constructor` | 🔴 CRITICAL | `new Function()` constructor usage |
|
|
111
|
+
| `injection/settimeout-string` | 🟠 HIGH | `setTimeout/setInterval` with string argument |
|
|
112
|
+
| `injection/script-tag-in-template` | 🟠 HIGH | `<script>` tags in Angular templates |
|
|
113
|
+
|
|
114
|
+
### Authentication & Authorization (4 rules)
|
|
115
|
+
|
|
116
|
+
| Rule ID | Severity | Description |
|
|
117
|
+
|---------|----------|-------------|
|
|
118
|
+
| `auth/missing-route-guards` | 🟠 HIGH | Sensitive routes without `canActivate/canMatch/canLoad` guards |
|
|
119
|
+
| `auth/missing-auth-interceptor` | 🟡 MEDIUM | Missing HTTP authentication interceptor |
|
|
120
|
+
| `auth/jwt-in-localstorage` | 🟠 HIGH | JWT/auth tokens stored in localStorage |
|
|
121
|
+
| `auth/hardcoded-roles` | 🟡 MEDIUM | Hardcoded role checks in templates |
|
|
122
|
+
|
|
123
|
+
### Sensitive Data (4 rules)
|
|
124
|
+
|
|
125
|
+
| Rule ID | Severity | Description |
|
|
126
|
+
|---------|----------|-------------|
|
|
127
|
+
| `sensitive/hardcoded-secrets` | 🔴 CRITICAL | Hardcoded API keys, passwords, tokens in source code |
|
|
128
|
+
| `sensitive/environment-secrets` | 🟠 HIGH | Secrets in `environment.ts` files |
|
|
129
|
+
| `sensitive/console-log` | 🔵 LOW | Console statements that may leak sensitive data |
|
|
130
|
+
| `sensitive/local-storage-sensitive` | 🟡 MEDIUM | Sensitive data in browser storage |
|
|
131
|
+
|
|
132
|
+
### HTTP Security (4 rules)
|
|
133
|
+
|
|
134
|
+
| Rule ID | Severity | Description |
|
|
135
|
+
|---------|----------|-------------|
|
|
136
|
+
| `http/missing-xsrf-protection` | 🟠 HIGH | Missing or disabled XSRF/CSRF protection |
|
|
137
|
+
| `http/insecure-url` | 🟡 MEDIUM | Insecure HTTP URLs (non-localhost) |
|
|
138
|
+
| `http/cors-wildcard` | 🟡 MEDIUM | CORS wildcard `*` configuration |
|
|
139
|
+
| `http/missing-error-handler` | 🔵 LOW | Missing global HTTP error handler |
|
|
140
|
+
|
|
141
|
+
### Angular Configuration (7 rules)
|
|
142
|
+
|
|
143
|
+
| Rule ID | Severity | Description |
|
|
144
|
+
|---------|----------|-------------|
|
|
145
|
+
| `config/aot-disabled` | 🟠 HIGH | AOT compilation disabled (enables template injection) |
|
|
146
|
+
| `config/source-maps-prod` | 🟡 MEDIUM | Source maps enabled in production |
|
|
147
|
+
| `config/strict-mode` | 🔵 LOW | TypeScript strict mode not enabled |
|
|
148
|
+
| `config/outdated-angular` | 🟡 MEDIUM | Outdated Angular version without security patches |
|
|
149
|
+
| `config/budget-check` | ⚪ INFO | Missing bundle budgets in production config |
|
|
150
|
+
| `config/csp-meta-tag` | 🟡 MEDIUM | Missing Content Security Policy |
|
|
151
|
+
| `config/allowed-hosts-ssr` | 🟠 HIGH | SSR app without `allowedHosts` (SSRF risk) |
|
|
152
|
+
|
|
153
|
+
### Best Practices (7 rules)
|
|
154
|
+
|
|
155
|
+
| Rule ID | Severity | Description |
|
|
156
|
+
|---------|----------|-------------|
|
|
157
|
+
| `best-practice/noopener-noreferrer` | 🔵 LOW | Missing `rel="noopener"` on external links |
|
|
158
|
+
| `best-practice/trusted-types` | ⚪ INFO | Trusted Types not configured |
|
|
159
|
+
| `best-practice/production-mode` | 🔵 LOW | Production mode not enabled |
|
|
160
|
+
| `best-practice/dependency-audit` | 🟠 HIGH | Known vulnerable npm packages |
|
|
161
|
+
| `best-practice/form-autocomplete` | 🔵 LOW | Sensitive fields without `autocomplete="off"` |
|
|
162
|
+
| `best-practice/iframe-sandbox` | 🟡 MEDIUM | Unsandboxed iframes |
|
|
163
|
+
| `best-practice/postmessage-origin` | 🟠 HIGH | `postMessage` without origin validation |
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## 📊 Report Formats
|
|
168
|
+
|
|
169
|
+
### Console Output
|
|
170
|
+
|
|
171
|
+
Beautiful colored terminal output with code snippets and recommendations:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
ngx-security-audit scan
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### JSON Report
|
|
178
|
+
|
|
179
|
+
Machine-readable format for CI/CD pipelines:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
ngx-security-audit scan --format json --output report.json
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### HTML Report
|
|
186
|
+
|
|
187
|
+
Stunning dark-themed report for stakeholders with charts and code snippets:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
ngx-security-audit scan --format html --output report.html
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### SARIF Report
|
|
194
|
+
|
|
195
|
+
[SARIF 2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html) format for GitHub Code Scanning and Azure DevOps:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
ngx-security-audit scan --format sarif --output results.sarif
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 🏗️ CI/CD Integration
|
|
204
|
+
|
|
205
|
+
### GitHub Actions
|
|
206
|
+
|
|
207
|
+
```yaml
|
|
208
|
+
name: Angular Security Audit
|
|
209
|
+
on: [push, pull_request]
|
|
210
|
+
|
|
211
|
+
jobs:
|
|
212
|
+
security:
|
|
213
|
+
runs-on: ubuntu-latest
|
|
214
|
+
steps:
|
|
215
|
+
- uses: actions/checkout@v4
|
|
216
|
+
- uses: actions/setup-node@v4
|
|
217
|
+
with:
|
|
218
|
+
node-version: '20'
|
|
219
|
+
- run: npm ci
|
|
220
|
+
- run: npm install -g ngx-security-audit
|
|
221
|
+
- run: ngx-security-audit scan . --threshold high
|
|
222
|
+
- run: ngx-security-audit scan . --format sarif --output results.sarif
|
|
223
|
+
if: always()
|
|
224
|
+
- uses: github/codeql-action/upload-sarif@v3
|
|
225
|
+
if: always()
|
|
226
|
+
with:
|
|
227
|
+
sarif_file: results.sarif
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Azure DevOps
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
steps:
|
|
234
|
+
- script: npm ci
|
|
235
|
+
- script: npm install -g ngx-security-audit
|
|
236
|
+
- script: ngx-security-audit scan . --threshold high
|
|
237
|
+
- script: ngx-security-audit scan . --format html --output $(Build.ArtifactStagingDirectory)/report.html
|
|
238
|
+
condition: always()
|
|
239
|
+
- task: PublishBuildArtifacts@1
|
|
240
|
+
condition: always()
|
|
241
|
+
inputs:
|
|
242
|
+
artifactName: 'SecurityReport'
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### GitLab CI
|
|
246
|
+
|
|
247
|
+
```yaml
|
|
248
|
+
security_scan:
|
|
249
|
+
image: node:20-alpine
|
|
250
|
+
script:
|
|
251
|
+
- npm ci
|
|
252
|
+
- npm install -g ngx-security-audit
|
|
253
|
+
- ngx-security-audit scan . --threshold high
|
|
254
|
+
artifacts:
|
|
255
|
+
paths:
|
|
256
|
+
- security-report.html
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## ⚙️ Configuration
|
|
262
|
+
|
|
263
|
+
Create a `.ngsecurityrc.json` in your project root:
|
|
264
|
+
|
|
265
|
+
```json
|
|
266
|
+
{
|
|
267
|
+
"threshold": "high",
|
|
268
|
+
"format": "console",
|
|
269
|
+
"include": ["src/**/*.ts", "src/**/*.html", "src/**/*.js"],
|
|
270
|
+
"exclude": ["**/*.spec.ts", "**/*.test.ts"],
|
|
271
|
+
"disabledRules": ["sensitive/console-log"],
|
|
272
|
+
"ruleOverrides": {
|
|
273
|
+
"xss/inner-html-binding": "low"
|
|
274
|
+
},
|
|
275
|
+
"verbose": false
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Or add to `package.json`:
|
|
280
|
+
|
|
281
|
+
```json
|
|
282
|
+
{
|
|
283
|
+
"ngxSecurityAudit": {
|
|
284
|
+
"threshold": "high",
|
|
285
|
+
"disabledRules": ["sensitive/console-log"]
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## 📚 Programmatic API
|
|
293
|
+
|
|
294
|
+
```javascript
|
|
295
|
+
const { audit, generateReport, listRules } = require('ngx-security-audit');
|
|
296
|
+
|
|
297
|
+
// Run audit
|
|
298
|
+
const result = await audit('/path/to/angular/project', {
|
|
299
|
+
threshold: 'high',
|
|
300
|
+
format: 'console',
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
console.log(`Score: ${result.score}/100 (Grade: ${result.grade})`);
|
|
304
|
+
console.log(`Total findings: ${result.summary.total}`);
|
|
305
|
+
console.log(`Passed: ${result.passed}`);
|
|
306
|
+
|
|
307
|
+
// Generate different report formats
|
|
308
|
+
const htmlReport = generateReport(result, 'html');
|
|
309
|
+
const sarifReport = generateReport(result, 'sarif');
|
|
310
|
+
|
|
311
|
+
// List available rules
|
|
312
|
+
const rules = listRules();
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## 🎯 Exit Codes
|
|
318
|
+
|
|
319
|
+
| Code | Meaning |
|
|
320
|
+
|------|---------|
|
|
321
|
+
| `0` | Audit passed — no findings at or above threshold |
|
|
322
|
+
| `1` | Audit failed — findings found at or above threshold |
|
|
323
|
+
| `2` | Error — invalid project, configuration error, etc. |
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## 🔥 Severity Levels
|
|
328
|
+
|
|
329
|
+
| Level | Weight | Description |
|
|
330
|
+
|-------|--------|-------------|
|
|
331
|
+
| 🔴 **CRITICAL** | -20 pts | Immediate exploitation risk. Fix before deployment. |
|
|
332
|
+
| 🟠 **HIGH** | -10 pts | Significant security risk. Fix as priority. |
|
|
333
|
+
| 🟡 **MEDIUM** | -5 pts | Moderate risk. Plan to fix soon. |
|
|
334
|
+
| 🔵 **LOW** | -2 pts | Minor risk. Fix when convenient. |
|
|
335
|
+
| ⚪ **INFO** | 0 pts | Informational. Consider for hardening. |
|
|
336
|
+
|
|
337
|
+
**Security Score:** Start at 100, deduct per finding based on severity weight. Minimum score is 0.
|
|
338
|
+
|
|
339
|
+
| Grade | Score Range |
|
|
340
|
+
|-------|-------------|
|
|
341
|
+
| A | 90-100 |
|
|
342
|
+
| B | 80-89 |
|
|
343
|
+
| C | 70-79 |
|
|
344
|
+
| D | 60-69 |
|
|
345
|
+
| F | 0-59 |
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## 🌐 OWASP Top 10 Coverage
|
|
350
|
+
|
|
351
|
+
| OWASP Category | Rules |
|
|
352
|
+
|----------------|-------|
|
|
353
|
+
| A01: Broken Access Control | Route guards, postMessage origin, hardcoded roles |
|
|
354
|
+
| A02: Cryptographic Failures | Hardcoded secrets, environment secrets, insecure HTTP, browser storage |
|
|
355
|
+
| A03: Injection | XSS (bypass trust, innerHTML, DOM), eval, Function constructor, template injection |
|
|
356
|
+
| A04: Insecure Design | Strict mode, noopener, form autocomplete, iframe sandbox |
|
|
357
|
+
| A05: Security Misconfiguration | CSRF, AOT, source maps, CSP |
|
|
358
|
+
| A06: Vulnerable Components | Outdated Angular, known vulnerable packages |
|
|
359
|
+
| A07: Auth Failures | Auth interceptor, JWT in localStorage |
|
|
360
|
+
| A09: Logging Failures | Console statements, error handlers |
|
|
361
|
+
| A10: SSRF | SSR allowed hosts |
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## 🤝 Contributing
|
|
366
|
+
|
|
367
|
+
Contributions are welcome! To add a new security rule:
|
|
368
|
+
|
|
369
|
+
1. Create your rule in the appropriate file under `src/rules/`
|
|
370
|
+
2. Follow the existing rule structure with `id`, `name`, `description`, `category`, `severity`, `owasp`, `cwe`, and `check` function
|
|
371
|
+
3. Add tests in `test/run-tests.js`
|
|
372
|
+
4. Submit a PR
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## 📄 License
|
|
377
|
+
|
|
378
|
+
MIT © [noredinebahri](https://github.com/noredinebahri)
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
<p align="center">
|
|
383
|
+
<strong>Built with ❤️ for the Angular community</strong><br>
|
|
384
|
+
<em>Secure your Angular applications. Protect your users.</em>
|
|
385
|
+
</p>
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { Command } = require('commander');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const { audit, generateReport, listRules } = require('../src/index');
|
|
8
|
+
|
|
9
|
+
const pkg = require('../package.json');
|
|
10
|
+
|
|
11
|
+
const program = new Command();
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.name('ngx-security-audit')
|
|
15
|
+
.description('Enterprise-grade Angular security auditing tool. Detect XSS, CSRF, injection, and 30+ vulnerabilities with OWASP-aligned severity levels.')
|
|
16
|
+
.version(pkg.version);
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command('scan')
|
|
20
|
+
.alias('s')
|
|
21
|
+
.description('Scan an Angular project for security vulnerabilities')
|
|
22
|
+
.argument('[path]', 'Path to Angular project root', '.')
|
|
23
|
+
.option('-f, --format <format>', 'Report format: console, json, html, sarif', 'console')
|
|
24
|
+
.option('-o, --output <file>', 'Write report to file')
|
|
25
|
+
.option('-t, --threshold <level>', 'Fail threshold: critical, high, medium, low, info', 'high')
|
|
26
|
+
.option('--no-color', 'Disable colored output')
|
|
27
|
+
.option('-v, --verbose', 'Enable verbose output')
|
|
28
|
+
.option('--disable-rules <rules>', 'Comma-separated list of rule IDs to disable')
|
|
29
|
+
.option('--include <patterns>', 'Comma-separated glob patterns to include')
|
|
30
|
+
.option('--exclude <patterns>', 'Comma-separated glob patterns to exclude')
|
|
31
|
+
.action(async (projectPath, options) => {
|
|
32
|
+
try {
|
|
33
|
+
const resolvedPath = path.resolve(projectPath);
|
|
34
|
+
|
|
35
|
+
// Build config from CLI options
|
|
36
|
+
const config = {
|
|
37
|
+
threshold: options.threshold,
|
|
38
|
+
format: options.format,
|
|
39
|
+
verbose: options.verbose || false,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
if (options.disableRules) {
|
|
43
|
+
config.disabledRules = options.disableRules.split(',').map((r) => r.trim());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (options.include) {
|
|
47
|
+
config.include = options.include.split(',').map((p) => p.trim());
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (options.exclude) {
|
|
51
|
+
config.exclude = options.exclude.split(',').map((p) => p.trim());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Show spinner for console output
|
|
55
|
+
let spinner;
|
|
56
|
+
if (options.format === 'console') {
|
|
57
|
+
try {
|
|
58
|
+
const ora = require('ora');
|
|
59
|
+
spinner = ora({
|
|
60
|
+
text: 'Scanning Angular project for security vulnerabilities...',
|
|
61
|
+
spinner: 'dots12',
|
|
62
|
+
}).start();
|
|
63
|
+
} catch {
|
|
64
|
+
console.log('Scanning Angular project for security vulnerabilities...');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const result = await audit(resolvedPath, config);
|
|
69
|
+
|
|
70
|
+
if (spinner) spinner.stop();
|
|
71
|
+
|
|
72
|
+
if (!result.success) {
|
|
73
|
+
console.error(`Error: ${result.error}`);
|
|
74
|
+
process.exit(2);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Generate report
|
|
78
|
+
const report = generateReport(result, options.format);
|
|
79
|
+
|
|
80
|
+
// Output
|
|
81
|
+
if (options.output) {
|
|
82
|
+
const outputPath = path.resolve(options.output);
|
|
83
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
84
|
+
fs.writeFileSync(outputPath, report, 'utf-8');
|
|
85
|
+
if (options.format === 'console') {
|
|
86
|
+
console.log(report);
|
|
87
|
+
}
|
|
88
|
+
console.log(`\nReport saved to: ${outputPath}`);
|
|
89
|
+
} else {
|
|
90
|
+
console.log(report);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Exit code based on threshold
|
|
94
|
+
process.exit(result.passed ? 0 : 1);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error(`Fatal error: ${error.message}`);
|
|
97
|
+
if (options.verbose) {
|
|
98
|
+
console.error(error.stack);
|
|
99
|
+
}
|
|
100
|
+
process.exit(2);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
program
|
|
105
|
+
.command('rules')
|
|
106
|
+
.description('List all available security rules')
|
|
107
|
+
.option('--json', 'Output as JSON')
|
|
108
|
+
.option('-c, --category <category>', 'Filter by category')
|
|
109
|
+
.action((options) => {
|
|
110
|
+
let rules = listRules();
|
|
111
|
+
|
|
112
|
+
if (options.category) {
|
|
113
|
+
rules = rules.filter((r) => r.category.toLowerCase().includes(options.category.toLowerCase()));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (options.json) {
|
|
117
|
+
console.log(JSON.stringify(rules, null, 2));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const chalk = require('chalk');
|
|
122
|
+
console.log('');
|
|
123
|
+
console.log(chalk.bold.cyan(' NGX Security Audit - Available Rules'));
|
|
124
|
+
console.log(chalk.bold.cyan(' ════════════════════════════════════════'));
|
|
125
|
+
console.log('');
|
|
126
|
+
|
|
127
|
+
const categories = [...new Set(rules.map((r) => r.category))];
|
|
128
|
+
for (const category of categories) {
|
|
129
|
+
console.log(chalk.bold.white(` 📋 ${category}`));
|
|
130
|
+
const catRules = rules.filter((r) => r.category === category);
|
|
131
|
+
for (const rule of catRules) {
|
|
132
|
+
const severityColor = {
|
|
133
|
+
critical: 'red',
|
|
134
|
+
high: 'redBright',
|
|
135
|
+
medium: 'yellow',
|
|
136
|
+
low: 'cyan',
|
|
137
|
+
info: 'gray',
|
|
138
|
+
}[rule.severity] || 'white';
|
|
139
|
+
|
|
140
|
+
console.log(
|
|
141
|
+
` ${chalk[severityColor](`[${rule.severity.toUpperCase()}]`.padEnd(12))}` +
|
|
142
|
+
`${chalk.white(rule.id.padEnd(35))}` +
|
|
143
|
+
`${chalk.gray(rule.name)}`
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
console.log('');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
console.log(chalk.gray(` Total: ${rules.length} rules`));
|
|
150
|
+
console.log('');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
program
|
|
154
|
+
.command('init')
|
|
155
|
+
.description('Create a .ngsecurityrc.json configuration file')
|
|
156
|
+
.action(() => {
|
|
157
|
+
const configPath = path.resolve('.ngsecurityrc.json');
|
|
158
|
+
if (fs.existsSync(configPath)) {
|
|
159
|
+
console.log('Configuration file already exists: .ngsecurityrc.json');
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const defaultConfig = {
|
|
164
|
+
threshold: 'high',
|
|
165
|
+
format: 'console',
|
|
166
|
+
include: ['src/**/*.ts', 'src/**/*.html', 'src/**/*.js'],
|
|
167
|
+
exclude: [],
|
|
168
|
+
disabledRules: [],
|
|
169
|
+
ruleOverrides: {},
|
|
170
|
+
verbose: false,
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');
|
|
174
|
+
console.log('Created .ngsecurityrc.json with default configuration.');
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// Default command - scan current directory
|
|
178
|
+
program
|
|
179
|
+
.argument('[path]', 'Path to Angular project (shorthand for "scan" command)')
|
|
180
|
+
.option('-f, --format <format>', 'Report format', 'console')
|
|
181
|
+
.option('-o, --output <file>', 'Write report to file')
|
|
182
|
+
.option('-t, --threshold <level>', 'Fail threshold', 'high')
|
|
183
|
+
.option('-v, --verbose', 'Verbose output')
|
|
184
|
+
.action(async (projectPath, options) => {
|
|
185
|
+
// If no subcommand, run scan
|
|
186
|
+
if (projectPath && !['scan', 'rules', 'init'].includes(projectPath)) {
|
|
187
|
+
await program.commands.find((c) => c.name() === 'scan')
|
|
188
|
+
.parseAsync([process.argv[0], process.argv[1], 'scan', projectPath, ...process.argv.slice(3)]);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
program.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ngx-security-audit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Enterprise-grade Angular security auditing tool. Static analysis scanner that detects XSS, CSRF, injection, sensitive data exposure, misconfigurations and 40+ security vulnerabilities in Angular projects. Generates detailed reports with severity levels for CI/CD pipeline integration.",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"ngx-security-audit": "bin/ngx-security-audit.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "node test/run-tests.js",
|
|
11
|
+
"lint": "node bin/ngx-security-audit.js .",
|
|
12
|
+
"prepublishOnly": "node test/run-tests.js"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"angular",
|
|
16
|
+
"security",
|
|
17
|
+
"audit",
|
|
18
|
+
"scanner",
|
|
19
|
+
"xss",
|
|
20
|
+
"csrf",
|
|
21
|
+
"owasp",
|
|
22
|
+
"vulnerability",
|
|
23
|
+
"static-analysis",
|
|
24
|
+
"devops",
|
|
25
|
+
"ci-cd",
|
|
26
|
+
"pipeline",
|
|
27
|
+
"security-report",
|
|
28
|
+
"angular-security",
|
|
29
|
+
"ngx",
|
|
30
|
+
"sast",
|
|
31
|
+
"code-analysis",
|
|
32
|
+
"devsecops",
|
|
33
|
+
"appsec",
|
|
34
|
+
"penetration-testing"
|
|
35
|
+
],
|
|
36
|
+
"author": "noredinebahri",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/noredinebahri/ngx-security-audit.git"
|
|
41
|
+
},
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/noredinebahri/ngx-security-audit/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://noredinebahri.github.io/ngx-security-audit",
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=14.0.0"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"chalk": "^4.1.2",
|
|
51
|
+
"commander": "^11.1.0",
|
|
52
|
+
"glob": "^10.3.10",
|
|
53
|
+
"ora": "^5.4.1"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {},
|
|
56
|
+
"files": [
|
|
57
|
+
"bin/",
|
|
58
|
+
"src/",
|
|
59
|
+
"templates/",
|
|
60
|
+
"README.md",
|
|
61
|
+
"LICENSE"
|
|
62
|
+
]
|
|
63
|
+
}
|