@scenarist/core 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"in-memory-state-manager.d.ts","sourceRoot":"","sources":["../../src/adapters/in-memory-state-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAErE;;;;;;GAMG;AACH,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8C;IAEtE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAUzC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAyBtD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI/C,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI3B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,cAAc;CAavB;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAAO,YAE7C,CAAC"}
1
+ {"version":3,"file":"in-memory-state-manager.d.ts","sourceRoot":"","sources":["../../src/adapters/in-memory-state-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAErE;;;;;;GAMG;AACH,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8C;IAEtE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAUzC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAyBtD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI/C,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI3B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,cAAc;IAoBtB,OAAO,CAAC,cAAc;CAmBvB;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAAO,YAE7C,CAAC"}
@@ -50,21 +50,29 @@ export class InMemoryStateManager {
50
50
  return testState;
51
51
  }
52
52
  setNestedValue(obj, path, value) {
53
+ const key = path[0];
54
+ // Guard: Prevent prototype pollution attacks
55
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
56
+ return;
57
+ }
53
58
  if (path.length === 1) {
54
- obj[path[0]] = value;
59
+ obj[key] = value;
55
60
  return;
56
61
  }
57
- const key = path[0];
58
62
  if (typeof obj[key] !== 'object' || obj[key] === null || Array.isArray(obj[key])) {
59
63
  obj[key] = {};
60
64
  }
61
65
  this.setNestedValue(obj[key], path.slice(1), value);
62
66
  }
63
67
  getNestedValue(obj, path) {
68
+ const key = path[0];
69
+ // Guard: Prevent prototype pollution attacks
70
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
71
+ return undefined;
72
+ }
64
73
  if (path.length === 1) {
65
- return obj[path[0]];
74
+ return obj[key];
66
75
  }
67
- const key = path[0];
68
76
  const nested = obj[key];
69
77
  if (typeof nested !== 'object' || nested === null || Array.isArray(nested)) {
70
78
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"template-replacement.d.ts","sourceRoot":"","sources":["../../src/domain/template-replacement.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,EAAE,cAAc,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,OAsDtF,CAAC"}
1
+ {"version":3,"file":"template-replacement.d.ts","sourceRoot":"","sources":["../../src/domain/template-replacement.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,EAAE,cAAc,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,OAwDtF,CAAC"}
@@ -17,7 +17,8 @@ export const applyTemplates = (value, templateData) => {
17
17
  if (typeof value === 'string') {
18
18
  // Check if entire string is a single pure template (no surrounding text)
19
19
  // Supports both {{state.key}} and {{params.key}}
20
- const pureTemplateMatch = /^\{\{(state|params)\.([^}]+)\}\}$/.exec(value);
20
+ // Using {1,256} limit to prevent ReDoS attacks with malicious input
21
+ const pureTemplateMatch = /^\{\{(state|params)\.([^}]{1,256})\}\}$/.exec(value);
21
22
  if (pureTemplateMatch) {
22
23
  // Pure template: return raw value (preserves type - arrays, numbers, objects)
23
24
  const prefix = pureTemplateMatch[1]; // 'state' or 'params'
@@ -29,7 +30,8 @@ export const applyTemplates = (value, templateData) => {
29
30
  }
30
31
  // Mixed template (has surrounding text): use string replacement
31
32
  // Supports both {{state.key}} and {{params.key}}
32
- return value.replace(/\{\{(state|params)\.([^}]+)\}\}/g, (match, prefix, path) => {
33
+ // Using {1,256} limit to prevent ReDoS attacks with malicious input
34
+ return value.replace(/\{\{(state|params)\.([^}]{1,256})\}\}/g, (match, prefix, path) => {
33
35
  const resolvedValue = resolveTemplatePath(normalizedData, prefix, path);
34
36
  // Guard: Missing keys remain as template
35
37
  if (resolvedValue === undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scenarist/core",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Internal: Hexagonal architecture core for scenario-based testing with MSW",
5
5
  "author": "Paul Hammond (citypaul) <paul@packsoftware.co.uk>",
6
6
  "license": "MIT",