@runa-ai/runa-cli 0.5.32 → 0.5.34

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/index.js CHANGED
@@ -925,7 +925,7 @@ var CLI_VERSION, HAS_ADMIN_COMMAND;
925
925
  var init_version = __esm({
926
926
  "src/version.ts"() {
927
927
  init_esm_shims();
928
- CLI_VERSION = "0.5.32";
928
+ CLI_VERSION = "0.5.34";
929
929
  HAS_ADMIN_COMMAND = false;
930
930
  }
931
931
  });
@@ -3362,6 +3362,14 @@ var init_json_reporter = __esm({
3362
3362
  });
3363
3363
 
3364
3364
  // src/internal/vuln-checker/reporters/markdown-reporter.ts
3365
+ function escapeMarkdown(text) {
3366
+ let escaped = text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
3367
+ escaped = escaped.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\*/g, "\\*").replace(/_/g, "\\_").replace(/\{/g, "\\{").replace(/\}/g, "\\}").replace(/\[/g, "\\[").replace(/\]/g, "\\]").replace(/\(/g, "\\(").replace(/\)/g, "\\)").replace(/#/g, "\\#").replace(/\+/g, "\\+").replace(/-/g, "\\-").replace(/\./g, "\\.").replace(/!/g, "\\!").replace(/\|/g, "\\|");
3368
+ return escaped;
3369
+ }
3370
+ function sanitizeCodeBlock(text) {
3371
+ return text.replace(/```/g, "\\`\\`\\`");
3372
+ }
3365
3373
  function groupByCategory2(findings) {
3366
3374
  const byCategory = /* @__PURE__ */ new Map();
3367
3375
  for (const finding of findings) {
@@ -3392,29 +3400,31 @@ function formatMetadata(finding) {
3392
3400
  }
3393
3401
  function formatSnippet(finding) {
3394
3402
  if (!finding.snippet) return [];
3395
- return ["```", finding.snippet.text, "```\n"];
3403
+ return ["```", sanitizeCodeBlock(finding.snippet.text), "```\n"];
3396
3404
  }
3397
3405
  function formatFix(finding) {
3398
3406
  if (!finding.fix) return [];
3399
- const lines = [`**Fix**: ${finding.fix.description}
3407
+ const lines = [`**Fix**: ${escapeMarkdown(finding.fix.description)}
3400
3408
  `];
3401
3409
  if (finding.fix.replacement) {
3402
- lines.push("```", finding.fix.replacement, "```\n");
3410
+ lines.push("```", sanitizeCodeBlock(finding.fix.replacement), "```\n");
3403
3411
  }
3404
3412
  return lines;
3405
3413
  }
3406
3414
  function formatFinding2(finding) {
3407
3415
  const emoji = SEVERITY_EMOJI[finding.severity];
3408
3416
  const location = `${formatFilePath(finding.location.file)}:${finding.location.line}`;
3417
+ const safeTitle = escapeMarkdown(finding.title);
3418
+ const safeDescription = escapeMarkdown(finding.description);
3409
3419
  return [
3410
- `#### ${emoji} ${finding.title}
3420
+ `#### ${emoji} ${safeTitle}
3411
3421
  `,
3412
3422
  `- **Severity**: ${finding.severity}`,
3413
3423
  `- **Location**: \`${location}\``,
3414
3424
  `- **Rule**: \`${finding.ruleId}\``,
3415
3425
  ...formatMetadata(finding),
3416
3426
  `
3417
- ${finding.description}
3427
+ ${safeDescription}
3418
3428
  `,
3419
3429
  ...formatSnippet(finding),
3420
3430
  ...formatFix(finding),
@@ -3483,8 +3493,9 @@ var init_markdown_reporter = __esm({
3483
3493
  lines.push("The following findings were ignored based on configuration:\n");
3484
3494
  for (const finding of result.ignoredFindings) {
3485
3495
  const emoji = SEVERITY_EMOJI[finding.severity];
3496
+ const safeTitle = escapeMarkdown(finding.title);
3486
3497
  lines.push(
3487
- `- ${emoji} **${finding.title}** at \`${finding.location.file}:${finding.location.line}\``
3498
+ `- ${emoji} **${safeTitle}** at \`${finding.location.file}:${finding.location.line}\``
3488
3499
  );
3489
3500
  }
3490
3501
  lines.push("");
@@ -1,5 +1,8 @@
1
1
  /**
2
2
  * Markdown reporter for human-readable vulnerability reports
3
+ *
4
+ * SECURITY (Issue #543): This reporter sanitizes all user-controlled content
5
+ * to prevent XSS and injection attacks when reports are rendered in web interfaces.
3
6
  */
4
7
  import type { Reporter, ScanResult } from '../types.js';
5
8
  export declare class MarkdownReporter implements Reporter {
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-reporter.d.ts","sourceRoot":"","sources":["../../../../src/internal/vuln-checker/reporters/markdown-reporter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAW,QAAQ,EAAE,UAAU,EAAY,MAAM,aAAa,CAAC;AAgH3E,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,IAAI,SAAc;IAElB,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;CAqDnC"}
1
+ {"version":3,"file":"markdown-reporter.d.ts","sourceRoot":"","sources":["../../../../src/internal/vuln-checker/reporters/markdown-reporter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAW,QAAQ,EAAE,UAAU,EAAY,MAAM,aAAa,CAAC;AA2K3E,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,IAAI,SAAc;IAElB,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;CAuDnC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runa-ai/runa-cli",
3
- "version": "0.5.32",
3
+ "version": "0.5.34",
4
4
  "private": false,
5
5
  "description": "AI-powered DevOps CLI",
6
6
  "type": "module",
@@ -26,8 +26,6 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@dotenvx/dotenvx": "1.51.4",
29
- "@runa-ai/runa": "^0.5.32",
30
- "@runa-ai/runa-xstate-test-plugin": "^0.5.28",
31
29
  "@types/node": "22.19.3",
32
30
  "boxen": "7.1.1",
33
31
  "chalk": "5.6.2",
@@ -53,7 +51,9 @@
53
51
  "tsup": "8.5.1",
54
52
  "typescript": "5.9.3",
55
53
  "xstate": "5.25.0",
56
- "zod": "4.3.5"
54
+ "zod": "4.3.5",
55
+ "@runa-ai/runa": "0.5.33",
56
+ "@runa-ai/runa-xstate-test-plugin": "0.5.28"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">=20.0.0"