+ "details": "### Impact\nThe APIVersion rule uses `new Function()` to evaluate expression strings. A malicious crafted flow metadata file can cause arbitrary JavaScript execution during scanning. An attacker could execute arbitrary JavaScript during a scan by supplying a malicious expression within rule configuration or crafted flow metadata. This could compromise developer machines, CI runners, or editor environments.\n\n### Patches\nThe patch removes all uses of `new Function()` and replaces them with a safer parser. It now validates operators (`>`, >=`, `<`, `<=`, `==`) and performs numeric comparisons without evaluating untrusted JavaScript.\n**version:** core-v6.10.6,\n**version vsx:**: v2.4.4\n\n### Work around\n\n```\n// --- Handle APIVersion rule separately to avoid unsafe-eval in the core library ---\n const apiVersionConfig = ruleConfig.rules.APIVersion;\n if (apiVersionConfig) {\n delete ruleConfig.rules.APIVersion;\n }\n\n// Manually evaluate the APIVersion rule, if it was configured.\n if (apiVersionConfig) {\n const flowApiVer = this.currentFlow.apiVersion || this.currentFlow.xmlData?.apiVersion;\n const apiVersionRuleDef = allRules.find(r => r.name === \"APIVersion\");\n\n // Determine the required expression (e.g. \">=58\").\n let requiredExpr;\n if (apiVersionConfig.expression) {\n requiredExpr = apiVersionConfig.expression;\n } else if (apiVersionConfig.threshold != null) {\n requiredExpr = `>=${apiVersionConfig.threshold}`;\n }\n\n if (requiredExpr) {\n const minVer = parseInt(requiredExpr.replace(/[^0-9]/g, \"\"), 10);\n const operator = requiredExpr.replace(/[0-9]/g, \"\").trim();\n const operators = {\n \">=\": (a, b) => a < b,\n \"<\": (a, b) => a >= b,\n \">\": (a, b) => a <= b,\n \"<=\": (a, b) => a > b,\n \"==\": (a, b) => a !== b,\n \"=\": (a, b) => a !== b\n };\n const violation = operators[operator] ? operators[operator](flowApiVer, minVer) : flowApiVer < minVer;\n\n if (violation) {\n // Craft a result object that mimics the core scanner output so downstream logic remains unchanged.\n const manualScanResult = [{\n flow: parsedFlow,\n ruleResults: [{\n ruleName: \"APIVersion\",\n ruleDefinition: {\n description: apiVersionRuleDef?.description || \"API Version check\",\n label: apiVersionRuleDef?.label || \"APIVersion\"\n },\n occurs: true,\n severity: apiVersionConfig.severity,\n details: [{\n name: String(flowApiVer),\n type: \"apiVersion\",\n expression: requiredExpr\n }]\n }]\n }];\n results.push(...this.processScanResults(manualScanResult));\n }\n }\n }\n\n```",
0 commit comments