@memberjunction/global 6.1.0-edge.2 → 6.1.0-edge.4
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 +180 -4
- package/README.md +2 -2
- package/dist/ClassFactory.d.ts.map +1 -1
- package/dist/ClassFactory.js +35 -6
- package/dist/ClassFactory.js.map +1 -1
- package/dist/SQLExpressionValidator.d.ts +28 -1
- package/dist/SQLExpressionValidator.d.ts.map +1 -1
- package/dist/SQLExpressionValidator.js +42 -4
- package/dist/SQLExpressionValidator.js.map +1 -1
- package/dist/SafeExpressionEvaluator.d.ts +131 -6
- package/dist/SafeExpressionEvaluator.d.ts.map +1 -1
- package/dist/SafeExpressionEvaluator.js +344 -41
- package/dist/SafeExpressionEvaluator.js.map +1 -1
- package/dist/__tests__/ClassFactory.test.js +40 -0
- package/dist/__tests__/ClassFactory.test.js.map +1 -1
- package/dist/__tests__/DeepDiff.test.d.ts +2 -0
- package/dist/__tests__/DeepDiff.test.d.ts.map +1 -0
- package/dist/__tests__/DeepDiff.test.js +229 -0
- package/dist/__tests__/DeepDiff.test.js.map +1 -0
- package/dist/__tests__/JSONValidator.test.d.ts +2 -0
- package/dist/__tests__/JSONValidator.test.d.ts.map +1 -0
- package/dist/__tests__/JSONValidator.test.js +221 -0
- package/dist/__tests__/JSONValidator.test.js.map +1 -0
- package/dist/__tests__/MJGlobal.test.js +8 -6
- package/dist/__tests__/MJGlobal.test.js.map +1 -1
- package/dist/__tests__/ResourcePatternUtils.test.d.ts +2 -0
- package/dist/__tests__/ResourcePatternUtils.test.d.ts.map +1 -0
- package/dist/__tests__/ResourcePatternUtils.test.js +50 -0
- package/dist/__tests__/ResourcePatternUtils.test.js.map +1 -0
- package/dist/__tests__/SQLExpressionValidator.security.test.js +62 -1
- package/dist/__tests__/SQLExpressionValidator.security.test.js.map +1 -1
- package/dist/__tests__/SafeExpressionEvaluator.security.test.d.ts +2 -0
- package/dist/__tests__/SafeExpressionEvaluator.security.test.d.ts.map +1 -0
- package/dist/__tests__/SafeExpressionEvaluator.security.test.js +284 -0
- package/dist/__tests__/SafeExpressionEvaluator.security.test.js.map +1 -0
- package/dist/__tests__/SafeExpressionEvaluator.test.d.ts +2 -0
- package/dist/__tests__/SafeExpressionEvaluator.test.d.ts.map +1 -0
- package/dist/__tests__/SafeExpressionEvaluator.test.js +355 -0
- package/dist/__tests__/SafeExpressionEvaluator.test.js.map +1 -0
- package/dist/__tests__/SafeExpressionEvaluator.validateSyntax.test.d.ts +2 -0
- package/dist/__tests__/SafeExpressionEvaluator.validateSyntax.test.d.ts.map +1 -0
- package/dist/__tests__/SafeExpressionEvaluator.validateSyntax.test.js +62 -0
- package/dist/__tests__/SafeExpressionEvaluator.validateSyntax.test.js.map +1 -0
- package/dist/__tests__/util.test.js +62 -1
- package/dist/__tests__/util.test.js.map +1 -1
- package/dist/__tests__/util.toEpochMs.test.d.ts +2 -0
- package/dist/__tests__/util.toEpochMs.test.d.ts.map +1 -0
- package/dist/__tests__/util.toEpochMs.test.js +57 -0
- package/dist/__tests__/util.toEpochMs.test.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/util/ResourcePatternUtils.d.ts +35 -0
- package/dist/util/ResourcePatternUtils.d.ts.map +1 -0
- package/dist/util/ResourcePatternUtils.js +56 -0
- package/dist/util/ResourcePatternUtils.js.map +1 -0
- package/dist/util.d.ts +40 -5
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +79 -25
- package/dist/util.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { SafeExpressionEvaluator } from '../SafeExpressionEvaluator.js';
|
|
3
|
+
/**
|
|
4
|
+
* Adversarial security tests for SafeExpressionEvaluator.
|
|
5
|
+
*
|
|
6
|
+
* SafeExpressionEvaluator compiles the caller's expression into a real JavaScript
|
|
7
|
+
* function via `new Function(...)` and runs it. Its defense against arbitrary code
|
|
8
|
+
* execution is a STRUCTURAL ALLOWLIST: the expression is parsed to an AST and every
|
|
9
|
+
* node is checked against a whitelist before it is ever compiled. A construct that
|
|
10
|
+
* is not on the list — computed member access with a non-literal key, `.constructor`
|
|
11
|
+
* / `__proto__` access, any call outside the safe-method list, a host-global
|
|
12
|
+
* identifier — is rejected at validation time and never reaches `new Function`.
|
|
13
|
+
*
|
|
14
|
+
* This is what closes the string-concatenation escape a textual denylist could not:
|
|
15
|
+
* `[]["cons"+"tructor"]["cons"+"tructor"]("…")()` parses to computed member access
|
|
16
|
+
* whose key is a `+` expression, not a literal, so it is rejected structurally no
|
|
17
|
+
* matter how the dangerous name is spelled. See the "string-concatenation escape"
|
|
18
|
+
* block below. Because the check is structural, it also stops over-rejecting data
|
|
19
|
+
* that merely mentions a reserved word (`name == 'constructor'` is a legal compare).
|
|
20
|
+
*/
|
|
21
|
+
describe('SafeExpressionEvaluator - Security', () => {
|
|
22
|
+
let evaluator;
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
evaluator = new SafeExpressionEvaluator();
|
|
25
|
+
});
|
|
26
|
+
/** Assert an expression is rejected at the validation stage (never compiled/run). */
|
|
27
|
+
const expectBlocked = (expr, ctx = {}) => {
|
|
28
|
+
const r = evaluator.evaluate(expr, ctx);
|
|
29
|
+
expect(r.success).toBe(false);
|
|
30
|
+
expect(r.error).toContain('forbidden construct');
|
|
31
|
+
};
|
|
32
|
+
// ---------------------------------------------------------------
|
|
33
|
+
// Direct code-execution primitives — denylist HOLDS
|
|
34
|
+
// ---------------------------------------------------------------
|
|
35
|
+
describe('direct eval / Function constructor (textual forms blocked)', () => {
|
|
36
|
+
it('should block eval(...)', () => {
|
|
37
|
+
expectBlocked("eval('1+1')");
|
|
38
|
+
});
|
|
39
|
+
it('should block new Function(...)', () => {
|
|
40
|
+
expectBlocked("new Function('return 1')");
|
|
41
|
+
});
|
|
42
|
+
it('should block a bare Function(...) call', () => {
|
|
43
|
+
expectBlocked("Function('return 1')()");
|
|
44
|
+
});
|
|
45
|
+
it('should block require(...)', () => {
|
|
46
|
+
expectBlocked("require('child_process')");
|
|
47
|
+
});
|
|
48
|
+
it('should block import statements', () => {
|
|
49
|
+
expectBlocked("import 'fs'");
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
// ---------------------------------------------------------------
|
|
53
|
+
// Prototype-chain escapes — denylist HOLDS
|
|
54
|
+
// ---------------------------------------------------------------
|
|
55
|
+
describe('prototype-chain escapes (blocked)', () => {
|
|
56
|
+
it('should block .constructor access (dotted)', () => {
|
|
57
|
+
expectBlocked('x.constructor', { x: 1 });
|
|
58
|
+
});
|
|
59
|
+
it('should block constructor.constructor (the classic Function-constructor climb)', () => {
|
|
60
|
+
expectBlocked("x.constructor.constructor('return process')()", { x: 1 });
|
|
61
|
+
});
|
|
62
|
+
it('should block constructor via bracket string', () => {
|
|
63
|
+
// The word-boundary denylist matches "constructor" even inside ["..."]
|
|
64
|
+
expectBlocked('x["constructor"]', { x: 1 });
|
|
65
|
+
});
|
|
66
|
+
it('should block __proto__ access (dotted)', () => {
|
|
67
|
+
expectBlocked('x.__proto__', { x: {} });
|
|
68
|
+
});
|
|
69
|
+
it('should block __proto__ via bracket string', () => {
|
|
70
|
+
expectBlocked('x["__proto__"]', { x: {} });
|
|
71
|
+
});
|
|
72
|
+
it('should block prototype access', () => {
|
|
73
|
+
expectBlocked('x.prototype', { x: {} });
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
// ---------------------------------------------------------------
|
|
77
|
+
// Dotted access to host globals — denylist HOLDS for the dotted form
|
|
78
|
+
// ---------------------------------------------------------------
|
|
79
|
+
describe('dotted host-global access (blocked)', () => {
|
|
80
|
+
it('should block process.<member>', () => {
|
|
81
|
+
expectBlocked('process.exit');
|
|
82
|
+
});
|
|
83
|
+
it('should block global.<member>', () => {
|
|
84
|
+
expectBlocked('global.process');
|
|
85
|
+
});
|
|
86
|
+
it('should block window.<member>', () => {
|
|
87
|
+
expectBlocked('window.location');
|
|
88
|
+
});
|
|
89
|
+
it('should block document.<member>', () => {
|
|
90
|
+
expectBlocked('document.cookie');
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
// ---------------------------------------------------------------
|
|
94
|
+
// Statement / control-flow injection — denylist HOLDS
|
|
95
|
+
// ---------------------------------------------------------------
|
|
96
|
+
describe('statement and control-flow injection (blocked)', () => {
|
|
97
|
+
it('should block semicolons (statement chaining)', () => {
|
|
98
|
+
expectBlocked('a == 1; b == 2', { a: 1, b: 2 });
|
|
99
|
+
});
|
|
100
|
+
it('should block curly braces (code blocks)', () => {
|
|
101
|
+
expectBlocked('{ a: 1 }', { a: 1 });
|
|
102
|
+
});
|
|
103
|
+
it('should block template literals', () => {
|
|
104
|
+
expectBlocked('a == `x`', { a: 'x' });
|
|
105
|
+
});
|
|
106
|
+
it.each(['throw', 'try', 'catch', 'finally', 'async', 'await', 'class', 'extends', 'this'])('should block the "%s" keyword', (keyword) => {
|
|
107
|
+
expectBlocked(`${keyword} x`, { x: 1 });
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
// ---------------------------------------------------------------
|
|
111
|
+
// Input-size guard (the one DoS-ish protection the code promises)
|
|
112
|
+
// ---------------------------------------------------------------
|
|
113
|
+
describe('input-size guard', () => {
|
|
114
|
+
it('should reject expressions over 1000 characters', () => {
|
|
115
|
+
const huge = 'a == 1 && '.repeat(150) + 'a == 1';
|
|
116
|
+
const r = evaluator.evaluate(huge, { a: 1 });
|
|
117
|
+
expect(r.success).toBe(false);
|
|
118
|
+
expect(r.error).toContain('maximum length');
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
// ---------------------------------------------------------------
|
|
122
|
+
// Context sanitisation
|
|
123
|
+
// ---------------------------------------------------------------
|
|
124
|
+
describe('context sanitisation', () => {
|
|
125
|
+
it('should drop a dangerous "eval" context key so compilation still succeeds', () => {
|
|
126
|
+
// A parameter named "eval" is a SyntaxError inside the strict-mode compiled function,
|
|
127
|
+
// so if createSafeContext did NOT strip it, evaluation would fail. Success here proves
|
|
128
|
+
// the dangerous key was dropped before `new Function(...)` was built.
|
|
129
|
+
const r = evaluator.evaluate('normal == 1', { eval: 99, normal: 1 });
|
|
130
|
+
expect(r.success).toBe(true);
|
|
131
|
+
expect(r.value).toBe(true);
|
|
132
|
+
});
|
|
133
|
+
it('should drop a dangerous "constructor" context key and keep normal keys usable', () => {
|
|
134
|
+
const r = evaluator.evaluate('normal == 1', { constructor: 99, normal: 1 });
|
|
135
|
+
expect(r.success).toBe(true);
|
|
136
|
+
expect(r.value).toBe(true);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
// ===============================================================
|
|
140
|
+
// SANDBOX ESCAPE — bracket-string member access (now CLOSED)
|
|
141
|
+
// ===============================================================
|
|
142
|
+
//
|
|
143
|
+
// The escape reached host globals two ways the old dotted/call rules missed:
|
|
144
|
+
// - the bare identifiers `globalThis` / `global` (host global object), and
|
|
145
|
+
// - BRACKET-STRING member access, e.g. globalThis["Function"] or globalThis["process"],
|
|
146
|
+
// which contains neither `Function(` nor `process.` and so slipped every rule.
|
|
147
|
+
//
|
|
148
|
+
// Because `new Function` runs in global scope, `globalThis`/`global` resolved to the real
|
|
149
|
+
// host global, giving arbitrary code execution and `process` reachability:
|
|
150
|
+
//
|
|
151
|
+
// globalThis["Function"]("<attacker JS>")() // was: arbitrary code execution
|
|
152
|
+
// globalThis["process"]["mainModule"]["require"]("child_process") // was: RCE gateway
|
|
153
|
+
//
|
|
154
|
+
// Fixed by denying the dangerous identifiers as WHOLE WORDS (\bglobalThis\b, \bglobal\b,
|
|
155
|
+
// \bFunction\b, \bprocess\b, \beval\b, \brequire\b, …) — a bare-word match also catches the
|
|
156
|
+
// bracket-string form. These tests pin that the route stays blocked.
|
|
157
|
+
// ===============================================================
|
|
158
|
+
describe('sandbox escape via bracket-string member access (blocked)', () => {
|
|
159
|
+
it('blocks the bare `globalThis` host global', () => {
|
|
160
|
+
expectBlocked('globalThis');
|
|
161
|
+
});
|
|
162
|
+
it('blocks the Function constructor reached via bracket string', () => {
|
|
163
|
+
expectBlocked('globalThis["Function"]("return 40+2")() === 42');
|
|
164
|
+
});
|
|
165
|
+
it('blocks `process` reached via bracket string on globalThis', () => {
|
|
166
|
+
expectBlocked('typeof globalThis["process"] === "object"');
|
|
167
|
+
});
|
|
168
|
+
it('blocks `process` reached via the bare `global` identifier', () => {
|
|
169
|
+
expectBlocked('typeof global["process"] === "object"');
|
|
170
|
+
});
|
|
171
|
+
it('blocks chained bracket-string access to process internals', () => {
|
|
172
|
+
expectBlocked('globalThis["process"]["version"].length > 0');
|
|
173
|
+
});
|
|
174
|
+
it('blocks single-segment dotted host global (globalThis.process)', () => {
|
|
175
|
+
expectBlocked('globalThis.process');
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
// ===============================================================
|
|
179
|
+
// STRING-CONCATENATION ESCAPE — the route a textual denylist missed (blocked)
|
|
180
|
+
// ===============================================================
|
|
181
|
+
//
|
|
182
|
+
// The prior whole-word denylist matched only literal tokens, so splitting a
|
|
183
|
+
// dangerous name across a `+` expression spelled it nowhere in the source:
|
|
184
|
+
//
|
|
185
|
+
// []["cons"+"tructor"]["cons"+"tructor"]("return process.pid")()
|
|
186
|
+
//
|
|
187
|
+
// `[].constructor` is Array; `Array.constructor` is Function; the resulting
|
|
188
|
+
// Function constructor runs in global scope and reaches `process`. The AST walk
|
|
189
|
+
// rejects it because the computed member key is a `+` (BinaryExpression), not a
|
|
190
|
+
// literal — no matter how the name is assembled.
|
|
191
|
+
// ===============================================================
|
|
192
|
+
describe('string-concatenation sandbox escape (blocked)', () => {
|
|
193
|
+
it('blocks the Function-constructor climb built from split string literals', () => {
|
|
194
|
+
expectBlocked('[]["cons"+"tructor"]["cons"+"tructor"]("return 1")()');
|
|
195
|
+
});
|
|
196
|
+
it('blocks a split-name computed member access on a context value', () => {
|
|
197
|
+
expectBlocked('x["con"+"structor"]', { x: 1 });
|
|
198
|
+
});
|
|
199
|
+
it('blocks a split host-global name reached via computed access', () => {
|
|
200
|
+
expectBlocked('({})["__pro"+"to__"]', {});
|
|
201
|
+
});
|
|
202
|
+
it('blocks any dynamic (non-literal) computed member key', () => {
|
|
203
|
+
// Even a harmless-looking dynamic key is refused: dynamic keys are the escape surface.
|
|
204
|
+
expectBlocked('x[y]', { x: { a: 1 }, y: 'a' });
|
|
205
|
+
});
|
|
206
|
+
it('blocks a parenthesized string key that resolves to a dangerous property', () => {
|
|
207
|
+
expectBlocked('x[("constructor")]', { x: 1 });
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
// ===============================================================
|
|
211
|
+
// SAFE GLOBALS DO NOT REOPEN THE ESCAPE
|
|
212
|
+
// ===============================================================
|
|
213
|
+
//
|
|
214
|
+
// `Math.abs(x)` and `parseInt(x)` are admitted so the task-graph door stops refusing
|
|
215
|
+
// specs that run correctly. Both halves of every admitted call are FIXED identifiers
|
|
216
|
+
// in the AST, so the four invariants that close the escape still hold: literal-only
|
|
217
|
+
// computed keys, no `constructor`/`__proto__`/`prototype`, a closed non-computed call
|
|
218
|
+
// surface with no `call`/`apply`/`bind`, and screened free identifiers. These pin that.
|
|
219
|
+
// ===============================================================
|
|
220
|
+
describe('safe-global calls do not widen the escape surface', () => {
|
|
221
|
+
it('blocks the constructor climb off an allowed namespace', () => {
|
|
222
|
+
expectBlocked('Math.constructor("return 1")()');
|
|
223
|
+
expectBlocked('JSON.stringify.constructor("return 1")()');
|
|
224
|
+
});
|
|
225
|
+
it('blocks call/apply/bind on an allowed namespace method', () => {
|
|
226
|
+
expectBlocked('Math.abs.call(null, -1) === 1');
|
|
227
|
+
expectBlocked('parseInt.apply(null, ["1"]) === 1');
|
|
228
|
+
});
|
|
229
|
+
it('blocks a computed method name on an allowed namespace', () => {
|
|
230
|
+
expectBlocked('Math["cons"+"tructor"]("return 1")()');
|
|
231
|
+
expectBlocked('Math[m](-1) === 1', { m: 'abs' });
|
|
232
|
+
});
|
|
233
|
+
it('blocks a namespace method that is not on its list', () => {
|
|
234
|
+
expectBlocked('Object.getPrototypeOf(x) !== null', { x: {} });
|
|
235
|
+
expectBlocked('Object.setPrototypeOf(x, null) !== null', { x: {} });
|
|
236
|
+
expectBlocked('String.fromCharCode(65) === "A"');
|
|
237
|
+
});
|
|
238
|
+
it('blocks a bare call to any global outside the callable list', () => {
|
|
239
|
+
expectBlocked('setTimeout(1) === 1');
|
|
240
|
+
expectBlocked('structuredClone(x) !== null', { x: 1 });
|
|
241
|
+
});
|
|
242
|
+
it('blocks an optional call on a context value', () => {
|
|
243
|
+
// Optional chaining unwraps to the ordinary rules; it does not make `f()` callable.
|
|
244
|
+
expectBlocked('f?.() === 1', { f: 1 });
|
|
245
|
+
expectBlocked('x?.constructor', { x: 1 });
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
// ---------------------------------------------------------------
|
|
249
|
+
// No over-blocking of harmless data — the structural allowlist fix
|
|
250
|
+
// ---------------------------------------------------------------
|
|
251
|
+
// The old denylist rejected any expression whose TEXT mentioned a reserved token,
|
|
252
|
+
// even inside a string literal or as a field name. The AST walk distinguishes a
|
|
253
|
+
// reserved word used as CODE (blocked) from the same characters used as DATA
|
|
254
|
+
// (allowed), so these legitimate comparisons now succeed.
|
|
255
|
+
describe('legitimate data that mentions reserved words (allowed)', () => {
|
|
256
|
+
it('allows comparing a field against the literal string "constructor"', () => {
|
|
257
|
+
const r = evaluator.evaluate('name == "constructor"', { name: 'constructor' });
|
|
258
|
+
expect(r.success).toBe(true);
|
|
259
|
+
expect(r.value).toBe(true);
|
|
260
|
+
});
|
|
261
|
+
it('allows comparing a field against the literal string "this"', () => {
|
|
262
|
+
const r = evaluator.evaluate('label == "this"', { label: 'this' });
|
|
263
|
+
expect(r.success).toBe(true);
|
|
264
|
+
expect(r.value).toBe(true);
|
|
265
|
+
});
|
|
266
|
+
it('allows a `${...}` sequence inside a plain string literal', () => {
|
|
267
|
+
const r = evaluator.evaluate("a == '${x}'", { a: '${x}' });
|
|
268
|
+
expect(r.success).toBe(true);
|
|
269
|
+
expect(r.value).toBe(true);
|
|
270
|
+
});
|
|
271
|
+
it('allows reading a context field whose name is a former reserved token', () => {
|
|
272
|
+
// `payload.window` is a data field read, not host-global access.
|
|
273
|
+
const r = evaluator.evaluate("payload.window == 'morning'", { payload: { window: 'morning' } });
|
|
274
|
+
expect(r.success).toBe(true);
|
|
275
|
+
expect(r.value).toBe(true);
|
|
276
|
+
});
|
|
277
|
+
it('still allows words that merely contain a reserved token as a substring', () => {
|
|
278
|
+
const r = evaluator.evaluate('label == "thistle"', { label: 'thistle' });
|
|
279
|
+
expect(r.success).toBe(true);
|
|
280
|
+
expect(r.value).toBe(true);
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
//# sourceMappingURL=SafeExpressionEvaluator.security.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SafeExpressionEvaluator.security.test.js","sourceRoot":"","sources":["../../src/__tests__/SafeExpressionEvaluator.security.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SafeExpressionEvaluator.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/SafeExpressionEvaluator.test.ts"],"names":[],"mappings":""}
|