praisonai 1.7.1 → 1.7.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.
@@ -42,12 +42,19 @@ exports.createWorkflowFromYAML = createWorkflowFromYAML;
42
42
  exports.loadWorkflowFromFile = loadWorkflowFromFile;
43
43
  exports.validateWorkflowDefinition = validateWorkflowDefinition;
44
44
  const index_1 = require("./index");
45
+ const path = __importStar(require("path"));
46
+ // Whitelist of allowed step keys to prevent injection
47
+ const ALLOWED_STEP_KEYS = new Set([
48
+ 'type', 'agent', 'tool', 'input', 'output', 'condition',
49
+ 'onError', 'maxRetries', 'timeout', 'loopCondition', 'maxIterations',
50
+ ]);
45
51
  /**
46
52
  * Parse YAML string into workflow definition
47
53
  */
48
54
  function parseYAMLWorkflow(yamlContent) {
49
- // Simple YAML parser for workflow definitions
50
- // For production, use js-yaml package
55
+ // SECURITY: If migrating to js-yaml, you MUST use:
56
+ // yaml.load(content, { schema: yaml.JSON_SCHEMA })
57
+ // Never use yaml.load() with DEFAULT_SCHEMA — it enables arbitrary JS execution.
51
58
  const lines = yamlContent.split('\n');
52
59
  const result = {
53
60
  name: '',
@@ -90,7 +97,11 @@ function parseYAMLWorkflow(yamlContent) {
90
97
  };
91
98
  }
92
99
  else if (currentStep) {
93
- // Step properties
100
+ // Step properties — whitelist allowed keys to prevent injection
101
+ if (!ALLOWED_STEP_KEYS.has(key)) {
102
+ // Ignore unknown keys — do not allow arbitrary property injection
103
+ continue;
104
+ }
94
105
  if (key === 'type')
95
106
  currentStep.type = value;
96
107
  else if (key === 'agent')
@@ -262,9 +273,35 @@ function parseValue(value) {
262
273
  /**
263
274
  * Load workflow from YAML file
264
275
  */
265
- async function loadWorkflowFromFile(filePath, agents = {}, tools = {}) {
276
+ async function loadWorkflowFromFile(filePath, agents = {}, tools = {}, options = {}) {
266
277
  const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
267
- const content = await fs.readFile(filePath, 'utf-8');
278
+ // SECURITY: Prevent path traversal
279
+ const normalizedPath = path.normalize(filePath);
280
+ // Check for '..' as path segments (not just substring)
281
+ const pathSegments = normalizedPath.split(path.sep);
282
+ if (pathSegments.includes('..')) {
283
+ throw new Error('Path traversal detected: ".." path segments are not allowed');
284
+ }
285
+ let effectivePath;
286
+ // If basePath is specified, ensure resolvedPath stays within it
287
+ if (options.basePath) {
288
+ const resolvedBase = path.resolve(options.basePath);
289
+ const resolvedFile = path.resolve(options.basePath, normalizedPath);
290
+ if (!resolvedFile.startsWith(resolvedBase + path.sep) && resolvedFile !== resolvedBase) {
291
+ throw new Error(`File path must be within base directory: ${options.basePath}`);
292
+ }
293
+ effectivePath = resolvedFile;
294
+ }
295
+ else {
296
+ effectivePath = path.resolve(normalizedPath);
297
+ }
298
+ // SECURITY: Enforce file size limit (default 1 MB)
299
+ const maxSize = options.maxFileSizeBytes ?? 1048576;
300
+ const stat = await fs.stat(effectivePath);
301
+ if (stat.size > maxSize) {
302
+ throw new Error(`File too large: ${stat.size} bytes exceeds limit of ${maxSize} bytes`);
303
+ }
304
+ const content = await fs.readFile(effectivePath, 'utf-8');
268
305
  const definition = parseYAMLWorkflow(content);
269
306
  return createWorkflowFromYAML(definition, agents, tools);
270
307
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "praisonai",
3
- "version": "1.7.1",
3
+ "version": "1.7.2",
4
4
  "description": "PraisonAI TypeScript AI Agents Framework - Node.js, npm, and Javascript AI Agents Framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -65,7 +65,7 @@
65
65
  },
66
66
  "dependencies": {
67
67
  "@modelcontextprotocol/sdk": "^1.12.1",
68
- "axios": "^1.7.9",
68
+ "axios": "1.8.4",
69
69
  "dotenv": "^16.4.7",
70
70
  "fast-xml-parser": "^4.5.1",
71
71
  "node-fetch": "^2.6.9",