xypriss 9.12.45 → 9.12.46
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/dist/cjs/src/middleware/built-in/security/MaliciousUrlScanner.js +68 -21
- package/dist/cjs/src/middleware/built-in/security/MaliciousUrlScanner.js.map +1 -1
- package/dist/esm/src/middleware/built-in/security/MaliciousUrlScanner.js +68 -21
- package/dist/esm/src/middleware/built-in/security/MaliciousUrlScanner.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/package.json +1 -1
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
var strulink = require('strulink');
|
|
4
4
|
|
|
5
|
+
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
6
|
+
const HASH_REGEX = /^[0-9a-f]{16,64}$/i;
|
|
7
|
+
const SAFE_PARAM_REGEX = /^[a-zA-Z0-9_\-.~%]+$/;
|
|
5
8
|
class MaliciousUrlScanner {
|
|
6
9
|
/**
|
|
7
10
|
* Middleware for scanning incoming URLs for malicious payloads (XSS, Path Traversal, etc.)
|
|
@@ -25,37 +28,83 @@ class MaliciousUrlScanner {
|
|
|
25
28
|
return (req, res, next) => next?.();
|
|
26
29
|
}
|
|
27
30
|
const mode = scannerConfig.mode || "block";
|
|
28
|
-
const options =
|
|
29
|
-
minScore:
|
|
31
|
+
const options = {
|
|
32
|
+
minScore: 70,
|
|
30
33
|
sensitivity: 1.0,
|
|
34
|
+
enableEntropyAnalysis: false, // Disabled by default to prevent false positives on UUIDs and hash IDs
|
|
35
|
+
...scannerConfig.options,
|
|
31
36
|
advanced: {
|
|
32
37
|
maxEncodingLayers: 3,
|
|
33
|
-
entropyThreshold:
|
|
34
|
-
|
|
38
|
+
entropyThreshold: 5.5,
|
|
39
|
+
...scannerConfig.options?.advanced,
|
|
40
|
+
},
|
|
35
41
|
};
|
|
36
42
|
return async (req, res, next) => {
|
|
37
43
|
try {
|
|
44
|
+
const reqPath = req.path || (req.url ? req.url.split("?")[0] : "");
|
|
45
|
+
// Check excluded paths
|
|
46
|
+
if (scannerConfig.excludePaths && scannerConfig.excludePaths.length > 0) {
|
|
47
|
+
for (const pattern of scannerConfig.excludePaths) {
|
|
48
|
+
if (typeof pattern === "string") {
|
|
49
|
+
if (pattern.endsWith("/**")) {
|
|
50
|
+
const prefix = pattern.slice(0, -3);
|
|
51
|
+
if (reqPath === prefix || reqPath.startsWith(prefix + "/")) {
|
|
52
|
+
return next?.();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (pattern.endsWith("/*")) {
|
|
56
|
+
const prefix = pattern.slice(0, -2);
|
|
57
|
+
if (reqPath === prefix || reqPath.startsWith(prefix + "/")) {
|
|
58
|
+
return next?.();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (reqPath === pattern || reqPath.startsWith(pattern)) {
|
|
62
|
+
return next?.();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (pattern instanceof RegExp && pattern.test(reqPath)) {
|
|
66
|
+
return next?.();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
38
70
|
// Reconstruct full URL to scan everything including path and query
|
|
39
71
|
const protocol = req.headers["x-forwarded-proto"] || "http";
|
|
40
72
|
const host = req.headers.host || "localhost";
|
|
41
73
|
const fullUrl = `${protocol}://${host}${req.originalUrl || req.url}`;
|
|
42
74
|
const result = await strulink.__strl__.scanUrl(fullUrl, options);
|
|
43
75
|
if (result.isMalicious) {
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
76
|
+
// Filter heuristic false positives on standard UUIDs, hashes, and benign params
|
|
77
|
+
const genuinePatterns = (result.detectedPatterns || []).filter((p) => {
|
|
78
|
+
if (scannerConfig.ignorePatterns?.includes(p.type)) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
if (p.type === "encoded_payload" || p.pattern === "high_entropy") {
|
|
82
|
+
const val = p.matchedValue || "";
|
|
83
|
+
if (UUID_REGEX.test(val) || HASH_REGEX.test(val) || SAFE_PARAM_REGEX.test(val)) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
});
|
|
89
|
+
if (genuinePatterns.length > 0) {
|
|
90
|
+
const reasons = genuinePatterns.map((p) => p.type).join(", ");
|
|
91
|
+
const logMessage = `[MaliciousUrlScanner] Detected malicious URL (Score: ${result.score}). Reasons: ${reasons}. URL: ${req.url}`;
|
|
92
|
+
if (logger) {
|
|
93
|
+
logger.warn("security", logMessage);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
console.warn(logMessage);
|
|
97
|
+
}
|
|
98
|
+
if (mode === "block") {
|
|
99
|
+
if (!res.headersSent && !res.writableEnded) {
|
|
100
|
+
res.status(403).json({
|
|
101
|
+
error: "Forbidden",
|
|
102
|
+
code: "EMALICIOUSURL",
|
|
103
|
+
message: "The request was blocked due to suspected malicious payload."
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
59
108
|
}
|
|
60
109
|
}
|
|
61
110
|
next?.();
|
|
@@ -64,8 +113,6 @@ class MaliciousUrlScanner {
|
|
|
64
113
|
if (logger) {
|
|
65
114
|
logger.error("security", "Failed to scan URL for malicious payloads", err);
|
|
66
115
|
}
|
|
67
|
-
// Fail open or fail closed? Usually fail closed for security, but fail open to avoid breaking app if strulink crashes.
|
|
68
|
-
// We'll call next() to fail open.
|
|
69
116
|
next?.();
|
|
70
117
|
}
|
|
71
118
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MaliciousUrlScanner.js","sources":["../../../../../../src/middleware/built-in/security/MaliciousUrlScanner.ts"],"sourcesContent":[null],"names":["__strl__"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"MaliciousUrlScanner.js","sources":["../../../../../../src/middleware/built-in/security/MaliciousUrlScanner.ts"],"sourcesContent":[null],"names":["__strl__"],"mappings":"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"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { __strl__ } from 'strulink';
|
|
2
2
|
|
|
3
|
+
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
4
|
+
const HASH_REGEX = /^[0-9a-f]{16,64}$/i;
|
|
5
|
+
const SAFE_PARAM_REGEX = /^[a-zA-Z0-9_\-.~%]+$/;
|
|
3
6
|
class MaliciousUrlScanner {
|
|
4
7
|
/**
|
|
5
8
|
* Middleware for scanning incoming URLs for malicious payloads (XSS, Path Traversal, etc.)
|
|
@@ -23,37 +26,83 @@ class MaliciousUrlScanner {
|
|
|
23
26
|
return (req, res, next) => next?.();
|
|
24
27
|
}
|
|
25
28
|
const mode = scannerConfig.mode || "block";
|
|
26
|
-
const options =
|
|
27
|
-
minScore:
|
|
29
|
+
const options = {
|
|
30
|
+
minScore: 70,
|
|
28
31
|
sensitivity: 1.0,
|
|
32
|
+
enableEntropyAnalysis: false, // Disabled by default to prevent false positives on UUIDs and hash IDs
|
|
33
|
+
...scannerConfig.options,
|
|
29
34
|
advanced: {
|
|
30
35
|
maxEncodingLayers: 3,
|
|
31
|
-
entropyThreshold:
|
|
32
|
-
|
|
36
|
+
entropyThreshold: 5.5,
|
|
37
|
+
...scannerConfig.options?.advanced,
|
|
38
|
+
},
|
|
33
39
|
};
|
|
34
40
|
return async (req, res, next) => {
|
|
35
41
|
try {
|
|
42
|
+
const reqPath = req.path || (req.url ? req.url.split("?")[0] : "");
|
|
43
|
+
// Check excluded paths
|
|
44
|
+
if (scannerConfig.excludePaths && scannerConfig.excludePaths.length > 0) {
|
|
45
|
+
for (const pattern of scannerConfig.excludePaths) {
|
|
46
|
+
if (typeof pattern === "string") {
|
|
47
|
+
if (pattern.endsWith("/**")) {
|
|
48
|
+
const prefix = pattern.slice(0, -3);
|
|
49
|
+
if (reqPath === prefix || reqPath.startsWith(prefix + "/")) {
|
|
50
|
+
return next?.();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (pattern.endsWith("/*")) {
|
|
54
|
+
const prefix = pattern.slice(0, -2);
|
|
55
|
+
if (reqPath === prefix || reqPath.startsWith(prefix + "/")) {
|
|
56
|
+
return next?.();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (reqPath === pattern || reqPath.startsWith(pattern)) {
|
|
60
|
+
return next?.();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if (pattern instanceof RegExp && pattern.test(reqPath)) {
|
|
64
|
+
return next?.();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
36
68
|
// Reconstruct full URL to scan everything including path and query
|
|
37
69
|
const protocol = req.headers["x-forwarded-proto"] || "http";
|
|
38
70
|
const host = req.headers.host || "localhost";
|
|
39
71
|
const fullUrl = `${protocol}://${host}${req.originalUrl || req.url}`;
|
|
40
72
|
const result = await __strl__.scanUrl(fullUrl, options);
|
|
41
73
|
if (result.isMalicious) {
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
74
|
+
// Filter heuristic false positives on standard UUIDs, hashes, and benign params
|
|
75
|
+
const genuinePatterns = (result.detectedPatterns || []).filter((p) => {
|
|
76
|
+
if (scannerConfig.ignorePatterns?.includes(p.type)) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
if (p.type === "encoded_payload" || p.pattern === "high_entropy") {
|
|
80
|
+
const val = p.matchedValue || "";
|
|
81
|
+
if (UUID_REGEX.test(val) || HASH_REGEX.test(val) || SAFE_PARAM_REGEX.test(val)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return true;
|
|
86
|
+
});
|
|
87
|
+
if (genuinePatterns.length > 0) {
|
|
88
|
+
const reasons = genuinePatterns.map((p) => p.type).join(", ");
|
|
89
|
+
const logMessage = `[MaliciousUrlScanner] Detected malicious URL (Score: ${result.score}). Reasons: ${reasons}. URL: ${req.url}`;
|
|
90
|
+
if (logger) {
|
|
91
|
+
logger.warn("security", logMessage);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.warn(logMessage);
|
|
95
|
+
}
|
|
96
|
+
if (mode === "block") {
|
|
97
|
+
if (!res.headersSent && !res.writableEnded) {
|
|
98
|
+
res.status(403).json({
|
|
99
|
+
error: "Forbidden",
|
|
100
|
+
code: "EMALICIOUSURL",
|
|
101
|
+
message: "The request was blocked due to suspected malicious payload."
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
57
106
|
}
|
|
58
107
|
}
|
|
59
108
|
next?.();
|
|
@@ -62,8 +111,6 @@ class MaliciousUrlScanner {
|
|
|
62
111
|
if (logger) {
|
|
63
112
|
logger.error("security", "Failed to scan URL for malicious payloads", err);
|
|
64
113
|
}
|
|
65
|
-
// Fail open or fail closed? Usually fail closed for security, but fail open to avoid breaking app if strulink crashes.
|
|
66
|
-
// We'll call next() to fail open.
|
|
67
114
|
next?.();
|
|
68
115
|
}
|
|
69
116
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MaliciousUrlScanner.js","sources":["../../../../../../src/middleware/built-in/security/MaliciousUrlScanner.ts"],"sourcesContent":[null],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"MaliciousUrlScanner.js","sources":["../../../../../../src/middleware/built-in/security/MaliciousUrlScanner.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1604,6 +1604,15 @@ interface MaliciousUrlScannerConfig {
|
|
|
1604
1604
|
* - "log": Allow the request but log a security warning
|
|
1605
1605
|
*/
|
|
1606
1606
|
mode?: "block" | "log";
|
|
1607
|
+
/**
|
|
1608
|
+
* Paths or regex patterns to exclude from malicious URL scanning
|
|
1609
|
+
* e.g. ["/static/**", "/tmp-storage/**", /^\/api\/presence\//]
|
|
1610
|
+
*/
|
|
1611
|
+
excludePaths?: (string | RegExp)[];
|
|
1612
|
+
/**
|
|
1613
|
+
* Pattern types to ignore (e.g. ["encoded_payload", "suspicious_param_name"])
|
|
1614
|
+
*/
|
|
1615
|
+
ignorePatterns?: string[];
|
|
1607
1616
|
/** Custom options passed directly to [StruLink](https://github.com/Nehonix-Team/strulink)'s `scanUrl` method */
|
|
1608
1617
|
options?: MaliciousPatternOptions;
|
|
1609
1618
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xypriss",
|
|
3
|
-
"version": "9.12.
|
|
3
|
+
"version": "9.12.46",
|
|
4
4
|
"description": "XyPriss is a high-performance, TypeScript-first hyper-system web framework powered by a native Go core (XHSC), featuring robust multi-tenant sandboxing, secure native file streaming, and zero Express dependencies.",
|
|
5
5
|
"author": {
|
|
6
6
|
"DEV.to": "https://dev.to/nehonix",
|