@angular-helpers/security 22.0.0 → 22.2.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.
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, inject, PLATFORM_ID,
|
|
3
|
-
import { injectWorkerPool } from '@angular-helpers/core';
|
|
2
|
+
import { Injectable, InjectionToken, inject, PLATFORM_ID, DestroyRef, signal, computed, NgZone, Injector, makeEnvironmentProviders } from '@angular/core';
|
|
3
|
+
import { injectPlatform, injectWorkerPool } from '@angular-helpers/core';
|
|
4
4
|
import { isPlatformBrowser, DOCUMENT } from '@angular/common';
|
|
5
5
|
import { Observable, Subject, fromEvent, merge } from 'rxjs';
|
|
6
6
|
import { throttleTime } from 'rxjs/operators';
|
|
7
|
+
import { Meta } from '@angular/platform-browser';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Builder pattern to construct safe regular expressions
|
|
@@ -223,22 +224,37 @@ class RegexAnalyzerService {
|
|
|
223
224
|
const levels = { low: 1, medium: 2, high: 3, critical: 4 };
|
|
224
225
|
return levels[risk] || 0;
|
|
225
226
|
}
|
|
226
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
227
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
227
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RegexAnalyzerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
228
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RegexAnalyzerService });
|
|
228
229
|
}
|
|
229
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
230
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RegexAnalyzerService, decorators: [{
|
|
230
231
|
type: Injectable
|
|
231
232
|
}] });
|
|
232
233
|
|
|
234
|
+
const REGEX_WORKER_INLINE = '"use strict";\n(() => {\n // packages/security/src/workers/regex.worker.ts\n self.addEventListener("message", function(event) {\n const task = event.data;\n if (task.type === "regex-test") {\n const { pattern, text } = task.data;\n const startTime = performance.now();\n try {\n const regex = new RegExp(pattern, "g");\n const matches = [];\n let match;\n while ((match = regex.exec(text)) !== null) {\n matches.push([...match]);\n if (matches.length > 1e3) {\n throw new Error("Too many matches - possible infinite loop");\n }\n }\n const groups = {};\n if (matches.length > 0) {\n const firstMatch = matches[0];\n for (let i = 1; i < firstMatch.length; i++) {\n groups[`group${i}`] = firstMatch[i];\n }\n }\n self.postMessage({\n id: task.id,\n type: "regex-result",\n data: {\n match: matches.length > 0,\n matches,\n groups,\n executionTime: performance.now() - startTime,\n timeout: false\n }\n });\n } catch (error) {\n self.postMessage({\n id: task.id,\n type: "regex-result",\n data: {\n match: false,\n executionTime: performance.now() - startTime,\n timeout: false,\n error: error instanceof Error ? error.message : "Execution error"\n }\n });\n }\n }\n });\n})();\n';
|
|
235
|
+
|
|
236
|
+
const REGEX_WORKER_CONFIG = new InjectionToken('REGEX_WORKER_CONFIG');
|
|
233
237
|
/**
|
|
234
238
|
* Service responsible for managing Web Workers for safe regex execution.
|
|
235
239
|
* Avoids creating a new worker for every single execution.
|
|
236
240
|
*/
|
|
237
241
|
class RegexWorkerPoolService {
|
|
242
|
+
config = inject(REGEX_WORKER_CONFIG, { optional: true });
|
|
238
243
|
pool;
|
|
239
244
|
constructor() {
|
|
240
|
-
|
|
245
|
+
const { document } = injectPlatform();
|
|
246
|
+
let workerUrl;
|
|
247
|
+
if (this.config?.workerUrl) {
|
|
248
|
+
workerUrl = this.config.workerUrl;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
workerUrl = document
|
|
252
|
+
? new URL('assets/workers/regex.worker.js', document.baseURI)
|
|
253
|
+
: new URL('assets/workers/regex.worker.js', 'https://example.com'); // SSR: never instantiated
|
|
254
|
+
}
|
|
255
|
+
this.pool = injectWorkerPool(workerUrl, {
|
|
241
256
|
defaultTimeout: 5000,
|
|
257
|
+
fallbackWorkerCode: REGEX_WORKER_INLINE,
|
|
242
258
|
fallbackExecutor: async (type, data) => {
|
|
243
259
|
if (type !== 'regex-test')
|
|
244
260
|
throw new Error(`Unknown task type: ${type}`);
|
|
@@ -287,10 +303,10 @@ class RegexWorkerPoolService {
|
|
|
287
303
|
ngOnDestroy() {
|
|
288
304
|
this.pool.terminate();
|
|
289
305
|
}
|
|
290
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
291
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
306
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RegexWorkerPoolService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
307
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RegexWorkerPoolService });
|
|
292
308
|
}
|
|
293
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
309
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RegexWorkerPoolService, decorators: [{
|
|
294
310
|
type: Injectable
|
|
295
311
|
}], ctorParameters: () => [] });
|
|
296
312
|
|
|
@@ -357,10 +373,10 @@ class RegexSecurityService {
|
|
|
357
373
|
safeMode: config.safeMode || false,
|
|
358
374
|
};
|
|
359
375
|
}
|
|
360
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
361
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
376
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RegexSecurityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
377
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RegexSecurityService });
|
|
362
378
|
}
|
|
363
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
379
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RegexSecurityService, decorators: [{
|
|
364
380
|
type: Injectable
|
|
365
381
|
}] });
|
|
366
382
|
|
|
@@ -479,10 +495,10 @@ class WebCryptoService {
|
|
|
479
495
|
hmacHashName(algorithm) {
|
|
480
496
|
return algorithm.replace('HMAC-', '');
|
|
481
497
|
}
|
|
482
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
483
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
498
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WebCryptoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
499
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WebCryptoService });
|
|
484
500
|
}
|
|
485
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
501
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WebCryptoService, decorators: [{
|
|
486
502
|
type: Injectable
|
|
487
503
|
}] });
|
|
488
504
|
|
|
@@ -670,10 +686,10 @@ class SecureStorageService {
|
|
|
670
686
|
base64ToBytes(base64) {
|
|
671
687
|
return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
|
|
672
688
|
}
|
|
673
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
674
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
689
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SecureStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
690
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SecureStorageService });
|
|
675
691
|
}
|
|
676
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
692
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SecureStorageService, decorators: [{
|
|
677
693
|
type: Injectable
|
|
678
694
|
}], ctorParameters: () => [] });
|
|
679
695
|
|
|
@@ -970,7 +986,9 @@ class InputSanitizerService {
|
|
|
970
986
|
}
|
|
971
987
|
/**
|
|
972
988
|
* Parses and sanitizes an HTML string, keeping only allowed tags and attributes.
|
|
973
|
-
*
|
|
989
|
+
* Leverages the native browser Sanitizer API (e.g. Element.prototype.setHTML) if available
|
|
990
|
+
* for high-performance execution, falling back to a custom DOMParser implementation on
|
|
991
|
+
* unsupported environments (such as older browsers or SSR).
|
|
974
992
|
*
|
|
975
993
|
* @throws {Error} When called in a non-browser environment.
|
|
976
994
|
*/
|
|
@@ -978,6 +996,43 @@ class InputSanitizerService {
|
|
|
978
996
|
if (!this.isSupported()) {
|
|
979
997
|
throw new Error('sanitizeHtml requires a browser environment (DOMParser unavailable)');
|
|
980
998
|
}
|
|
999
|
+
// 1. Try native Element.prototype.setHTML (modern standard in Firefox 148+, etc.)
|
|
1000
|
+
if (typeof Element !== 'undefined' && 'setHTML' in Element.prototype) {
|
|
1001
|
+
try {
|
|
1002
|
+
const tempDiv = document.createElement('div');
|
|
1003
|
+
const config = {
|
|
1004
|
+
allowElements: this.allowedTags,
|
|
1005
|
+
allowAttributes: this.allowedAttributes,
|
|
1006
|
+
};
|
|
1007
|
+
try {
|
|
1008
|
+
tempDiv.setHTML(input, { sanitizer: config });
|
|
1009
|
+
}
|
|
1010
|
+
catch {
|
|
1011
|
+
tempDiv.setHTML(input);
|
|
1012
|
+
}
|
|
1013
|
+
return tempDiv.innerHTML;
|
|
1014
|
+
}
|
|
1015
|
+
catch {
|
|
1016
|
+
// Fallback on error
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
// 2. Try older Sanitizer API spec draft (implemented in some Chrome versions)
|
|
1020
|
+
if (typeof window.Sanitizer !== 'undefined') {
|
|
1021
|
+
try {
|
|
1022
|
+
const tempDiv = document.createElement('div');
|
|
1023
|
+
const config = {
|
|
1024
|
+
allowElements: this.allowedTags,
|
|
1025
|
+
allowAttributes: this.allowedAttributes,
|
|
1026
|
+
};
|
|
1027
|
+
const sanitizer = new window.Sanitizer(config);
|
|
1028
|
+
tempDiv.innerHTML = sanitizer.sanitizeToString(input);
|
|
1029
|
+
return tempDiv.innerHTML;
|
|
1030
|
+
}
|
|
1031
|
+
catch {
|
|
1032
|
+
// Fallback on error
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
// 3. Fallback to DOMParser-based allowlist sanitizer
|
|
981
1036
|
return sanitizeHtmlString(input, {
|
|
982
1037
|
allowedTags: this.allowedTags,
|
|
983
1038
|
allowedAttributes: this.allowedAttributes,
|
|
@@ -1019,10 +1074,10 @@ class InputSanitizerService {
|
|
|
1019
1074
|
return null;
|
|
1020
1075
|
}
|
|
1021
1076
|
}
|
|
1022
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
1023
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
1077
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: InputSanitizerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1078
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: InputSanitizerService });
|
|
1024
1079
|
}
|
|
1025
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
1080
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: InputSanitizerService, decorators: [{
|
|
1026
1081
|
type: Injectable
|
|
1027
1082
|
}], ctorParameters: () => [] });
|
|
1028
1083
|
|
|
@@ -1054,10 +1109,10 @@ class PasswordStrengthService {
|
|
|
1054
1109
|
assess(password) {
|
|
1055
1110
|
return assessPasswordStrength(password);
|
|
1056
1111
|
}
|
|
1057
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
1058
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
1112
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PasswordStrengthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1113
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PasswordStrengthService });
|
|
1059
1114
|
}
|
|
1060
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
1115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PasswordStrengthService, decorators: [{
|
|
1061
1116
|
type: Injectable
|
|
1062
1117
|
}] });
|
|
1063
1118
|
|
|
@@ -1169,10 +1224,10 @@ class JwtService {
|
|
|
1169
1224
|
}
|
|
1170
1225
|
return payload[name] ?? null;
|
|
1171
1226
|
}
|
|
1172
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
1173
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
1227
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: JwtService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1228
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: JwtService });
|
|
1174
1229
|
}
|
|
1175
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
1230
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: JwtService, decorators: [{
|
|
1176
1231
|
type: Injectable
|
|
1177
1232
|
}] });
|
|
1178
1233
|
function base64UrlDecode(input) {
|
|
@@ -1315,10 +1370,10 @@ class SensitiveClipboardService {
|
|
|
1315
1370
|
// ignore
|
|
1316
1371
|
}
|
|
1317
1372
|
}
|
|
1318
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
1319
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
1373
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SensitiveClipboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1374
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SensitiveClipboardService });
|
|
1320
1375
|
}
|
|
1321
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
1376
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SensitiveClipboardService, decorators: [{
|
|
1322
1377
|
type: Injectable
|
|
1323
1378
|
}], ctorParameters: () => [] });
|
|
1324
1379
|
|
|
@@ -1391,10 +1446,10 @@ class HibpService {
|
|
|
1391
1446
|
const match = findSuffixMatch(body, suffix);
|
|
1392
1447
|
return match > 0 ? { leaked: true, count: match } : { leaked: false, count: 0 };
|
|
1393
1448
|
}
|
|
1394
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
1395
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
1449
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: HibpService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1450
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: HibpService, providedIn: 'root' });
|
|
1396
1451
|
}
|
|
1397
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
1452
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: HibpService, decorators: [{
|
|
1398
1453
|
type: Injectable,
|
|
1399
1454
|
args: [{
|
|
1400
1455
|
providedIn: 'root',
|
|
@@ -1617,10 +1672,10 @@ class RateLimiterService {
|
|
|
1617
1672
|
}, timeToExpiryMs);
|
|
1618
1673
|
}
|
|
1619
1674
|
}
|
|
1620
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
1621
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
1675
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RateLimiterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1676
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RateLimiterService });
|
|
1622
1677
|
}
|
|
1623
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
1678
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RateLimiterService, decorators: [{
|
|
1624
1679
|
type: Injectable
|
|
1625
1680
|
}], ctorParameters: () => [] });
|
|
1626
1681
|
function validatePolicy(policy) {
|
|
@@ -1699,10 +1754,10 @@ class CsrfService {
|
|
|
1699
1754
|
get nativeStorage() {
|
|
1700
1755
|
return this.storageTarget === 'session' ? sessionStorage : localStorage;
|
|
1701
1756
|
}
|
|
1702
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
1703
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
1757
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CsrfService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1758
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CsrfService });
|
|
1704
1759
|
}
|
|
1705
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
1760
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CsrfService, decorators: [{
|
|
1706
1761
|
type: Injectable
|
|
1707
1762
|
}], ctorParameters: () => [] });
|
|
1708
1763
|
const DEFAULT_HEADER_NAME = 'X-CSRF-Token';
|
|
@@ -1841,10 +1896,10 @@ class SessionIdleService {
|
|
|
1841
1896
|
this.config = null;
|
|
1842
1897
|
});
|
|
1843
1898
|
}
|
|
1844
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
1845
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
1899
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SessionIdleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1900
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SessionIdleService, providedIn: 'root' });
|
|
1846
1901
|
}
|
|
1847
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
1902
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SessionIdleService, decorators: [{
|
|
1848
1903
|
type: Injectable,
|
|
1849
1904
|
args: [{
|
|
1850
1905
|
providedIn: 'root',
|
|
@@ -1945,10 +2000,10 @@ class SecureMessageService {
|
|
|
1945
2000
|
this._messages$.next(message);
|
|
1946
2001
|
});
|
|
1947
2002
|
}
|
|
1948
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.
|
|
1949
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.
|
|
2003
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SecureMessageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2004
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SecureMessageService, providedIn: 'root' });
|
|
1950
2005
|
}
|
|
1951
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.
|
|
2006
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SecureMessageService, decorators: [{
|
|
1952
2007
|
type: Injectable,
|
|
1953
2008
|
args: [{
|
|
1954
2009
|
providedIn: 'root',
|
|
@@ -2060,8 +2115,277 @@ function provideSecureMessage() {
|
|
|
2060
2115
|
return makeEnvironmentProviders([WebCryptoService, SecureMessageService]);
|
|
2061
2116
|
}
|
|
2062
2117
|
|
|
2118
|
+
/**
|
|
2119
|
+
* Serializes a CspDirectives object into a standard CSP policy string.
|
|
2120
|
+
*/
|
|
2121
|
+
function serializeCsp(directives) {
|
|
2122
|
+
const parts = [];
|
|
2123
|
+
for (const [key, val] of Object.entries(directives)) {
|
|
2124
|
+
if (val === undefined || val === null) {
|
|
2125
|
+
continue;
|
|
2126
|
+
}
|
|
2127
|
+
if (typeof val === 'boolean') {
|
|
2128
|
+
if (val) {
|
|
2129
|
+
parts.push(key);
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
else if (Array.isArray(val)) {
|
|
2133
|
+
if (val.length > 0) {
|
|
2134
|
+
parts.push(`${key} ${val.join(' ')}`);
|
|
2135
|
+
}
|
|
2136
|
+
else {
|
|
2137
|
+
parts.push(key);
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
else if (typeof val === 'string') {
|
|
2141
|
+
parts.push(`${key} ${val}`);
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
return parts.join('; ');
|
|
2145
|
+
}
|
|
2146
|
+
/**
|
|
2147
|
+
* Parses a CSP policy string into a CspDirectives object.
|
|
2148
|
+
*/
|
|
2149
|
+
function parseCsp(policy) {
|
|
2150
|
+
const directives = {};
|
|
2151
|
+
const tokens = policy
|
|
2152
|
+
.split(';')
|
|
2153
|
+
.map((t) => t.trim())
|
|
2154
|
+
.filter(Boolean);
|
|
2155
|
+
for (const token of tokens) {
|
|
2156
|
+
const spaceIndex = token.indexOf(' ');
|
|
2157
|
+
if (spaceIndex === -1) {
|
|
2158
|
+
const key = token;
|
|
2159
|
+
if (key === 'upgrade-insecure-requests' || key === 'block-all-mixed-content') {
|
|
2160
|
+
directives[key] = true;
|
|
2161
|
+
}
|
|
2162
|
+
else {
|
|
2163
|
+
directives[key] = [];
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
else {
|
|
2167
|
+
const key = token.substring(0, spaceIndex);
|
|
2168
|
+
const val = token
|
|
2169
|
+
.substring(spaceIndex + 1)
|
|
2170
|
+
.split(/\s+/)
|
|
2171
|
+
.filter(Boolean);
|
|
2172
|
+
directives[key] = val;
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
return directives;
|
|
2176
|
+
}
|
|
2177
|
+
/**
|
|
2178
|
+
* Fluent builder for creating Content Security Policy (CSP) directives.
|
|
2179
|
+
*/
|
|
2180
|
+
class CspPolicyBuilder {
|
|
2181
|
+
directives = {};
|
|
2182
|
+
defaultSrc(values) {
|
|
2183
|
+
this.directives['default-src'] = Array.isArray(values) ? values : [values];
|
|
2184
|
+
return this;
|
|
2185
|
+
}
|
|
2186
|
+
scriptSrc(values) {
|
|
2187
|
+
this.directives['script-src'] = Array.isArray(values) ? values : [values];
|
|
2188
|
+
return this;
|
|
2189
|
+
}
|
|
2190
|
+
styleSrc(values) {
|
|
2191
|
+
this.directives['style-src'] = Array.isArray(values) ? values : [values];
|
|
2192
|
+
return this;
|
|
2193
|
+
}
|
|
2194
|
+
imgSrc(values) {
|
|
2195
|
+
this.directives['img-src'] = Array.isArray(values) ? values : [values];
|
|
2196
|
+
return this;
|
|
2197
|
+
}
|
|
2198
|
+
connectSrc(values) {
|
|
2199
|
+
this.directives['connect-src'] = Array.isArray(values) ? values : [values];
|
|
2200
|
+
return this;
|
|
2201
|
+
}
|
|
2202
|
+
fontSrc(values) {
|
|
2203
|
+
this.directives['font-src'] = Array.isArray(values) ? values : [values];
|
|
2204
|
+
return this;
|
|
2205
|
+
}
|
|
2206
|
+
frameSrc(values) {
|
|
2207
|
+
this.directives['frame-src'] = Array.isArray(values) ? values : [values];
|
|
2208
|
+
return this;
|
|
2209
|
+
}
|
|
2210
|
+
objectSrc(values) {
|
|
2211
|
+
this.directives['object-src'] = Array.isArray(values) ? values : [values];
|
|
2212
|
+
return this;
|
|
2213
|
+
}
|
|
2214
|
+
mediaSrc(values) {
|
|
2215
|
+
this.directives['media-src'] = Array.isArray(values) ? values : [values];
|
|
2216
|
+
return this;
|
|
2217
|
+
}
|
|
2218
|
+
childSrc(values) {
|
|
2219
|
+
this.directives['child-src'] = Array.isArray(values) ? values : [values];
|
|
2220
|
+
return this;
|
|
2221
|
+
}
|
|
2222
|
+
workerSrc(values) {
|
|
2223
|
+
this.directives['worker-src'] = Array.isArray(values) ? values : [values];
|
|
2224
|
+
return this;
|
|
2225
|
+
}
|
|
2226
|
+
manifestSrc(values) {
|
|
2227
|
+
this.directives['manifest-src'] = Array.isArray(values) ? values : [values];
|
|
2228
|
+
return this;
|
|
2229
|
+
}
|
|
2230
|
+
baseUri(values) {
|
|
2231
|
+
this.directives['base-uri'] = Array.isArray(values) ? values : [values];
|
|
2232
|
+
return this;
|
|
2233
|
+
}
|
|
2234
|
+
formAction(values) {
|
|
2235
|
+
this.directives['form-action'] = Array.isArray(values) ? values : [values];
|
|
2236
|
+
return this;
|
|
2237
|
+
}
|
|
2238
|
+
frameAncestors(values) {
|
|
2239
|
+
this.directives['frame-ancestors'] = Array.isArray(values) ? values : [values];
|
|
2240
|
+
return this;
|
|
2241
|
+
}
|
|
2242
|
+
reportUri(values) {
|
|
2243
|
+
this.directives['report-uri'] = Array.isArray(values) ? values : [values];
|
|
2244
|
+
return this;
|
|
2245
|
+
}
|
|
2246
|
+
reportTo(values) {
|
|
2247
|
+
this.directives['report-to'] = Array.isArray(values) ? values : [values];
|
|
2248
|
+
return this;
|
|
2249
|
+
}
|
|
2250
|
+
sandbox(values) {
|
|
2251
|
+
this.directives['sandbox'] = Array.isArray(values) ? values : [values];
|
|
2252
|
+
return this;
|
|
2253
|
+
}
|
|
2254
|
+
upgradeInsecureRequests(value = true) {
|
|
2255
|
+
this.directives['upgrade-insecure-requests'] = value;
|
|
2256
|
+
return this;
|
|
2257
|
+
}
|
|
2258
|
+
blockAllMixedContent(value = true) {
|
|
2259
|
+
this.directives['block-all-mixed-content'] = value;
|
|
2260
|
+
return this;
|
|
2261
|
+
}
|
|
2262
|
+
set(directive, values) {
|
|
2263
|
+
if (typeof values === 'boolean') {
|
|
2264
|
+
this.directives[directive] = values;
|
|
2265
|
+
}
|
|
2266
|
+
else {
|
|
2267
|
+
this.directives[directive] = Array.isArray(values) ? values : [values];
|
|
2268
|
+
}
|
|
2269
|
+
return this;
|
|
2270
|
+
}
|
|
2271
|
+
build() {
|
|
2272
|
+
return { ...this.directives };
|
|
2273
|
+
}
|
|
2274
|
+
toString() {
|
|
2275
|
+
return serializeCsp(this.directives);
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
/**
|
|
2279
|
+
* Service for dynamically applying and auditing Content Security Policies (CSP).
|
|
2280
|
+
*/
|
|
2281
|
+
class CspService {
|
|
2282
|
+
meta = inject(Meta);
|
|
2283
|
+
/**
|
|
2284
|
+
* Applies the CSP policy dynamically by adding or updating a <meta http-equiv="Content-Security-Policy"> tag.
|
|
2285
|
+
*/
|
|
2286
|
+
applyPolicy(policy) {
|
|
2287
|
+
const content = typeof policy === 'string' ? policy : serializeCsp(policy);
|
|
2288
|
+
this.meta.updateTag({
|
|
2289
|
+
'http-equiv': 'Content-Security-Policy',
|
|
2290
|
+
content,
|
|
2291
|
+
});
|
|
2292
|
+
}
|
|
2293
|
+
/**
|
|
2294
|
+
* Performs static analysis on a CSP policy and reports potential vulnerabilities or errors.
|
|
2295
|
+
*/
|
|
2296
|
+
auditPolicy(policy) {
|
|
2297
|
+
const directives = typeof policy === 'string' ? parseCsp(policy) : policy;
|
|
2298
|
+
const issues = [];
|
|
2299
|
+
// 1. Missing default-src
|
|
2300
|
+
const defaultSrc = directives['default-src'];
|
|
2301
|
+
if (!defaultSrc || defaultSrc.length === 0) {
|
|
2302
|
+
issues.push({
|
|
2303
|
+
severity: 'error',
|
|
2304
|
+
directive: 'default-src',
|
|
2305
|
+
message: "CSP policy is missing 'default-src' directive. It is recommended to set 'default-src \\'none\\'' and selectively override.",
|
|
2306
|
+
});
|
|
2307
|
+
}
|
|
2308
|
+
// 2. Wildcards in sensitive directives
|
|
2309
|
+
const sensitiveDirectives = [
|
|
2310
|
+
'default-src',
|
|
2311
|
+
'script-src',
|
|
2312
|
+
'style-src',
|
|
2313
|
+
'connect-src',
|
|
2314
|
+
'img-src',
|
|
2315
|
+
'font-src',
|
|
2316
|
+
'object-src',
|
|
2317
|
+
'frame-src',
|
|
2318
|
+
];
|
|
2319
|
+
for (const dir of sensitiveDirectives) {
|
|
2320
|
+
const val = directives[dir];
|
|
2321
|
+
if (Array.isArray(val) && val.includes('*')) {
|
|
2322
|
+
if (['default-src', 'script-src', 'connect-src'].includes(dir)) {
|
|
2323
|
+
issues.push({
|
|
2324
|
+
severity: 'error',
|
|
2325
|
+
directive: dir,
|
|
2326
|
+
message: `Directive '${dir}' contains the wildcard '*'. This allows loading or executing resources from any external origin.`,
|
|
2327
|
+
});
|
|
2328
|
+
}
|
|
2329
|
+
else {
|
|
2330
|
+
issues.push({
|
|
2331
|
+
severity: 'warning',
|
|
2332
|
+
directive: dir,
|
|
2333
|
+
message: `Directive '${dir}' contains the wildcard '*'. Consider restricting this to trusted origins.`,
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
// 3. 'unsafe-inline' without safety fallback (nonces or hashes or strict-dynamic)
|
|
2339
|
+
const inlineSensitiveDirectives = ['default-src', 'script-src', 'style-src'];
|
|
2340
|
+
for (const dir of inlineSensitiveDirectives) {
|
|
2341
|
+
const val = directives[dir];
|
|
2342
|
+
if (Array.isArray(val) && val.includes("'unsafe-inline'")) {
|
|
2343
|
+
const hasNonce = val.some((v) => v.startsWith("'nonce-"));
|
|
2344
|
+
const hasHash = val.some((v) => v.startsWith("'sha256-") || v.startsWith("'sha384-") || v.startsWith("'sha512-"));
|
|
2345
|
+
const hasStrictDynamic = dir === 'script-src' && val.includes("'strict-dynamic'");
|
|
2346
|
+
if (!hasNonce && !hasHash && !hasStrictDynamic) {
|
|
2347
|
+
issues.push({
|
|
2348
|
+
severity: 'error',
|
|
2349
|
+
directive: dir,
|
|
2350
|
+
message: `Directive '${dir}' allows 'unsafe-inline' without nonces, hashes, or 'strict-dynamic'. This renders your application vulnerable to Cross-Site Scripting (XSS).`,
|
|
2351
|
+
});
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
// 4. Directives not supported in meta tags
|
|
2356
|
+
const unsupportedMetaDirectives = ['frame-ancestors', 'sandbox', 'report-uri', 'report-to'];
|
|
2357
|
+
for (const dir of unsupportedMetaDirectives) {
|
|
2358
|
+
if (directives[dir] !== undefined) {
|
|
2359
|
+
issues.push({
|
|
2360
|
+
severity: 'warning',
|
|
2361
|
+
directive: dir,
|
|
2362
|
+
message: `Directive '${dir}' is defined in the policy, but it is not supported or ignored when delivered via HTML <meta> tags.`,
|
|
2363
|
+
});
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
// 5. Always add the general dynamic meta warning/info
|
|
2367
|
+
issues.push({
|
|
2368
|
+
severity: 'info',
|
|
2369
|
+
message: 'Policies applied dynamically via <meta http-equiv="Content-Security-Policy"> only affect resources loaded after the tag is inserted.',
|
|
2370
|
+
});
|
|
2371
|
+
const isValid = !issues.some((issue) => issue.severity === 'error');
|
|
2372
|
+
return {
|
|
2373
|
+
isValid,
|
|
2374
|
+
issues,
|
|
2375
|
+
};
|
|
2376
|
+
}
|
|
2377
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CspService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2378
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CspService, providedIn: 'root' });
|
|
2379
|
+
}
|
|
2380
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CspService, decorators: [{
|
|
2381
|
+
type: Injectable,
|
|
2382
|
+
args: [{
|
|
2383
|
+
providedIn: 'root',
|
|
2384
|
+
}]
|
|
2385
|
+
}] });
|
|
2386
|
+
|
|
2063
2387
|
/**
|
|
2064
2388
|
* Generated bundle index. Do not edit.
|
|
2065
2389
|
*/
|
|
2066
2390
|
|
|
2067
|
-
export { CSRF_CONFIG, ClipboardUnsupportedError, CsrfService, DEFAULT_ALLOWED_ATTRIBUTES, DEFAULT_ALLOWED_TAGS, HIBP_CONFIG, HibpService, InputSanitizerService, InvalidJwtError, JwtService, PasswordStrengthService, RATE_LIMITER_CONFIG, RateLimitExceededError, RateLimiterService, RegexAnalyzerService, RegexSecurityBuilder, RegexSecurityService, RegexWorkerPoolService, SANITIZER_CONFIG, SECURE_STORAGE_CONFIG, SecureMessageService, SecureStorageService, SensitiveClipboardService, SessionIdleService, WebCryptoService, assessPasswordStrength, containsScriptInjection, containsSqlInjectionHints, defaultSecurityConfig, isHtmlSafe, isUrlSafe, provideCsrf, provideHibp, provideInputSanitizer, provideJwt, providePasswordStrength, provideRateLimiter, provideRegexSecurity, provideSecureMessage, provideSecureStorage, provideSecurity, provideSensitiveClipboard, provideSessionIdle, provideWebCrypto, sanitizeHtmlString, sanitizeUrlString, withCsrfHeader };
|
|
2391
|
+
export { CSRF_CONFIG, ClipboardUnsupportedError, CspPolicyBuilder, CspService, CsrfService, DEFAULT_ALLOWED_ATTRIBUTES, DEFAULT_ALLOWED_TAGS, HIBP_CONFIG, HibpService, InputSanitizerService, InvalidJwtError, JwtService, PasswordStrengthService, RATE_LIMITER_CONFIG, REGEX_WORKER_CONFIG, RateLimitExceededError, RateLimiterService, RegexAnalyzerService, RegexSecurityBuilder, RegexSecurityService, RegexWorkerPoolService, SANITIZER_CONFIG, SECURE_STORAGE_CONFIG, SecureMessageService, SecureStorageService, SensitiveClipboardService, SessionIdleService, WebCryptoService, assessPasswordStrength, containsScriptInjection, containsSqlInjectionHints, defaultSecurityConfig, isHtmlSafe, isUrlSafe, parseCsp, provideCsrf, provideHibp, provideInputSanitizer, provideJwt, providePasswordStrength, provideRateLimiter, provideRegexSecurity, provideSecureMessage, provideSecureStorage, provideSecurity, provideSensitiveClipboard, provideSessionIdle, provideWebCrypto, sanitizeHtmlString, sanitizeUrlString, serializeCsp, withCsrfHeader };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-helpers/security",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.2.0",
|
|
4
4
|
"description": "Angular security helpers for preventing ReDoS and other security vulnerabilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@angular-helpers/core": "
|
|
51
|
+
"@angular-helpers/core": "workspace:*",
|
|
52
52
|
"tslib": "^2.0.0"
|
|
53
53
|
},
|
|
54
54
|
"module": "fesm2022/angular-helpers-security.mjs",
|
|
@@ -72,4 +72,4 @@
|
|
|
72
72
|
},
|
|
73
73
|
"sideEffects": false,
|
|
74
74
|
"type": "module"
|
|
75
|
-
}
|
|
75
|
+
}
|
|
@@ -276,7 +276,9 @@ declare class InputSanitizerService {
|
|
|
276
276
|
isSupported(): boolean;
|
|
277
277
|
/**
|
|
278
278
|
* Parses and sanitizes an HTML string, keeping only allowed tags and attributes.
|
|
279
|
-
*
|
|
279
|
+
* Leverages the native browser Sanitizer API (e.g. Element.prototype.setHTML) if available
|
|
280
|
+
* for high-performance execution, falling back to a custom DOMParser implementation on
|
|
281
|
+
* unsupported environments (such as older browsers or SSR).
|
|
280
282
|
*
|
|
281
283
|
* @throws {Error} When called in a non-browser environment.
|
|
282
284
|
*/
|
|
@@ -860,11 +862,16 @@ declare class RegexAnalyzerService {
|
|
|
860
862
|
static ɵprov: i0.ɵɵInjectableDeclaration<RegexAnalyzerService>;
|
|
861
863
|
}
|
|
862
864
|
|
|
865
|
+
interface RegexWorkerConfig {
|
|
866
|
+
workerUrl?: string | URL;
|
|
867
|
+
}
|
|
868
|
+
declare const REGEX_WORKER_CONFIG: InjectionToken<RegexWorkerConfig>;
|
|
863
869
|
/**
|
|
864
870
|
* Service responsible for managing Web Workers for safe regex execution.
|
|
865
871
|
* Avoids creating a new worker for every single execution.
|
|
866
872
|
*/
|
|
867
873
|
declare class RegexWorkerPoolService implements OnDestroy {
|
|
874
|
+
private config;
|
|
868
875
|
private pool;
|
|
869
876
|
constructor();
|
|
870
877
|
/**
|
|
@@ -876,5 +883,91 @@ declare class RegexWorkerPoolService implements OnDestroy {
|
|
|
876
883
|
static ɵprov: i0.ɵɵInjectableDeclaration<RegexWorkerPoolService>;
|
|
877
884
|
}
|
|
878
885
|
|
|
879
|
-
|
|
880
|
-
|
|
886
|
+
interface CspDirectives {
|
|
887
|
+
'default-src'?: string[];
|
|
888
|
+
'script-src'?: string[];
|
|
889
|
+
'style-src'?: string[];
|
|
890
|
+
'img-src'?: string[];
|
|
891
|
+
'connect-src'?: string[];
|
|
892
|
+
'font-src'?: string[];
|
|
893
|
+
'frame-src'?: string[];
|
|
894
|
+
'object-src'?: string[];
|
|
895
|
+
'media-src'?: string[];
|
|
896
|
+
'child-src'?: string[];
|
|
897
|
+
'worker-src'?: string[];
|
|
898
|
+
'manifest-src'?: string[];
|
|
899
|
+
'base-uri'?: string[];
|
|
900
|
+
'form-action'?: string[];
|
|
901
|
+
'frame-ancestors'?: string[];
|
|
902
|
+
'report-uri'?: string[];
|
|
903
|
+
'report-to'?: string[];
|
|
904
|
+
sandbox?: string[];
|
|
905
|
+
'upgrade-insecure-requests'?: boolean | string[];
|
|
906
|
+
'block-all-mixed-content'?: boolean | string[];
|
|
907
|
+
[key: string]: string[] | boolean | undefined;
|
|
908
|
+
}
|
|
909
|
+
interface CspAuditIssue {
|
|
910
|
+
severity: 'error' | 'warning' | 'info';
|
|
911
|
+
directive?: string;
|
|
912
|
+
message: string;
|
|
913
|
+
}
|
|
914
|
+
interface CspAuditReport {
|
|
915
|
+
isValid: boolean;
|
|
916
|
+
issues: CspAuditIssue[];
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Serializes a CspDirectives object into a standard CSP policy string.
|
|
920
|
+
*/
|
|
921
|
+
declare function serializeCsp(directives: CspDirectives): string;
|
|
922
|
+
/**
|
|
923
|
+
* Parses a CSP policy string into a CspDirectives object.
|
|
924
|
+
*/
|
|
925
|
+
declare function parseCsp(policy: string): CspDirectives;
|
|
926
|
+
/**
|
|
927
|
+
* Fluent builder for creating Content Security Policy (CSP) directives.
|
|
928
|
+
*/
|
|
929
|
+
declare class CspPolicyBuilder {
|
|
930
|
+
private directives;
|
|
931
|
+
defaultSrc(values: string[] | string): this;
|
|
932
|
+
scriptSrc(values: string[] | string): this;
|
|
933
|
+
styleSrc(values: string[] | string): this;
|
|
934
|
+
imgSrc(values: string[] | string): this;
|
|
935
|
+
connectSrc(values: string[] | string): this;
|
|
936
|
+
fontSrc(values: string[] | string): this;
|
|
937
|
+
frameSrc(values: string[] | string): this;
|
|
938
|
+
objectSrc(values: string[] | string): this;
|
|
939
|
+
mediaSrc(values: string[] | string): this;
|
|
940
|
+
childSrc(values: string[] | string): this;
|
|
941
|
+
workerSrc(values: string[] | string): this;
|
|
942
|
+
manifestSrc(values: string[] | string): this;
|
|
943
|
+
baseUri(values: string[] | string): this;
|
|
944
|
+
formAction(values: string[] | string): this;
|
|
945
|
+
frameAncestors(values: string[] | string): this;
|
|
946
|
+
reportUri(values: string[] | string): this;
|
|
947
|
+
reportTo(values: string[] | string): this;
|
|
948
|
+
sandbox(values: string[] | string): this;
|
|
949
|
+
upgradeInsecureRequests(value?: boolean): this;
|
|
950
|
+
blockAllMixedContent(value?: boolean): this;
|
|
951
|
+
set(directive: string, values: string[] | string | boolean): this;
|
|
952
|
+
build(): CspDirectives;
|
|
953
|
+
toString(): string;
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Service for dynamically applying and auditing Content Security Policies (CSP).
|
|
957
|
+
*/
|
|
958
|
+
declare class CspService {
|
|
959
|
+
private readonly meta;
|
|
960
|
+
/**
|
|
961
|
+
* Applies the CSP policy dynamically by adding or updating a <meta http-equiv="Content-Security-Policy"> tag.
|
|
962
|
+
*/
|
|
963
|
+
applyPolicy(policy: string | CspDirectives): void;
|
|
964
|
+
/**
|
|
965
|
+
* Performs static analysis on a CSP policy and reports potential vulnerabilities or errors.
|
|
966
|
+
*/
|
|
967
|
+
auditPolicy(policy: string | CspDirectives): CspAuditReport;
|
|
968
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<CspService, never>;
|
|
969
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<CspService>;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
export { CSRF_CONFIG, ClipboardUnsupportedError, CspPolicyBuilder, CspService, CsrfService, DEFAULT_ALLOWED_ATTRIBUTES, DEFAULT_ALLOWED_TAGS, HIBP_CONFIG, HibpService, InputSanitizerService, InvalidJwtError, JwtService, PasswordStrengthService, RATE_LIMITER_CONFIG, REGEX_WORKER_CONFIG, RateLimitExceededError, RateLimiterService, RegexAnalyzerService, RegexSecurityBuilder, RegexSecurityService, RegexWorkerPoolService, SANITIZER_CONFIG, SECURE_STORAGE_CONFIG, SecureMessageService, SecureStorageService, SensitiveClipboardService, SessionIdleService, WebCryptoService, assessPasswordStrength, containsScriptInjection, containsSqlInjectionHints, defaultSecurityConfig, isHtmlSafe, isUrlSafe, parseCsp, provideCsrf, provideHibp, provideInputSanitizer, provideJwt, providePasswordStrength, provideRateLimiter, provideRegexSecurity, provideSecureMessage, provideSecureStorage, provideSecurity, provideSensitiveClipboard, provideSessionIdle, provideWebCrypto, sanitizeHtmlString, sanitizeUrlString, serializeCsp, withCsrfHeader };
|
|
973
|
+
export type { AesEncryptResult, AesKeyLength, CopyStatus, CspAuditIssue, CspAuditReport, CspDirectives, CsrfConfig, CsrfHeaderOptions, CsrfStorageTarget, HashAlgorithm, HibpConfig, HibpResult, HmacAlgorithm, HtmlSanitizerOptions, HttpMethod, JwtStandardClaims, PasswordAssessment, PasswordLabel, PasswordScore, PasswordStrengthResult, RateLimitPolicy, RateLimiterConfig, RegexBuilderOptions, RegexSecurityConfig, RegexSecurityResult, RegexTestResult, RegexWorkerConfig, SanitizerConfig, SecureMessage, SecureMessageConfig, SecureStorageConfig, SecurityConfig, SensitiveCopyOptions, SessionIdleConfig, StorageTarget };
|