hackmyagent-core 0.3.9 → 0.4.0

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.
@@ -135,5 +135,9 @@ export declare class HardeningScanner {
135
135
  * OpenClaw supply chain security checks (SUPPLY-001 to SUPPLY-004)
136
136
  */
137
137
  private checkOpenclawSupplyChain;
138
+ /**
139
+ * OpenClaw CVE-specific checks (CVE-001, CVE-002)
140
+ */
141
+ private checkOpenclawCVE;
138
142
  }
139
143
  //# sourceMappingURL=scanner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/hardening/scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,UAAU,EAA0C,MAAM,kBAAkB,CAAC;AAwD3F,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAgHD,qBAAa,gBAAgB;IAE3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAelC;IAEF;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAMvB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;YA0NvC,cAAc;IAsE5B;;OAEG;YACW,iBAAiB;IA+F/B;;OAEG;IACH,OAAO,CAAC,gBAAgB;YAeV,uBAAuB;YAmGvB,aAAa;YAgDb,cAAc;YA+Fd,oBAAoB;YAwDpB,gBAAgB;YA0IhB,oBAAoB;YAgFpB,gBAAgB;YA2IhB,mBAAmB;YA4EnB,iBAAiB;YAyCjB,iBAAiB;YA+DjB,wBAAwB;YA0FxB,wBAAwB;YAmExB,wBAAwB;YAqHxB,oBAAoB;YA+GpB,uBAAuB;YA8HvB,iBAAiB;YA8GjB,oBAAoB;YAuGpB,mBAAmB;YAiGnB,gBAAgB;YAmIhB,oBAAoB;YAoIpB,gBAAgB;YAyHhB,qBAAqB;YA+GrB,eAAe;IAiI7B;;OAEG;YACW,mBAAmB;IA8GjC;;OAEG;YACW,oBAAoB;IAiKlC;;OAEG;YACW,iBAAiB;IA4I/B;;OAEG;YACW,oBAAoB;IAwIlC;;OAEG;YACW,eAAe;IAqJ7B;;OAEG;YACW,eAAe;IAuI7B;;OAEG;YACW,eAAe;IAyG7B;;OAEG;YACW,mBAAmB;IAmHjC,OAAO,CAAC,cAAc;IAsBtB;;OAEG;YACW,YAAY;IAkD1B;;OAEG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6DhD;;;OAGG;YACW,cAAc;IAgD5B;;OAEG;YACW,mBAAmB;IAoUjC;;;OAGG;YACW,kBAAkB;IAgDhC;;OAEG;YACW,sBAAsB;IA2LpC;;OAEG;YACW,sBAAsB;IA+BpC;;OAEG;YACW,oBAAoB;IA0RlC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA4B3B;;OAEG;YACW,iBAAiB;IA8D/B;;OAEG;YACW,mBAAmB;IAmRjC;;OAEG;YACW,wBAAwB;CAsJvC"}
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/hardening/scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,UAAU,EAA0C,MAAM,kBAAkB,CAAC;AAyD3F,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AA8HD,qBAAa,gBAAgB;IAE3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAelC;IAEF;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAMvB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;YA8NvC,cAAc;IAsE5B;;OAEG;YACW,iBAAiB;IA+F/B;;OAEG;IACH,OAAO,CAAC,gBAAgB;YAeV,uBAAuB;YAmGvB,aAAa;YAgDb,cAAc;YA+Fd,oBAAoB;YAwDpB,gBAAgB;YA0IhB,oBAAoB;YAgFpB,gBAAgB;YA2IhB,mBAAmB;YA4EnB,iBAAiB;YAyCjB,iBAAiB;YA+DjB,wBAAwB;YA0FxB,wBAAwB;YAmExB,wBAAwB;YAqHxB,oBAAoB;YA+GpB,uBAAuB;YA8HvB,iBAAiB;YA8GjB,oBAAoB;YAuGpB,mBAAmB;YAiGnB,gBAAgB;YAmIhB,oBAAoB;YAoIpB,gBAAgB;YAyHhB,qBAAqB;YA+GrB,eAAe;IAiI7B;;OAEG;YACW,mBAAmB;IA8GjC;;OAEG;YACW,oBAAoB;IAiKlC;;OAEG;YACW,iBAAiB;IA4I/B;;OAEG;YACW,oBAAoB;IAwIlC;;OAEG;YACW,eAAe;IAqJ7B;;OAEG;YACW,eAAe;IAuI7B;;OAEG;YACW,eAAe;IAyG7B;;OAEG;YACW,mBAAmB;IAmHjC,OAAO,CAAC,cAAc;IAsBtB;;OAEG;YACW,YAAY;IAkD1B;;OAEG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6DhD;;;OAGG;YACW,cAAc;IAgD5B;;OAEG;YACW,mBAAmB;IAoUjC;;;OAGG;YACW,kBAAkB;IAgDhC;;OAEG;YACW,sBAAsB;IA2LpC;;OAEG;YACW,sBAAsB;IA+BpC;;OAEG;YACW,oBAAoB;IAqVlC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA4B3B;;OAEG;YACW,iBAAiB;IA8D/B;;OAEG;YACW,mBAAmB;IA6VjC;;OAEG;YACW,wBAAwB;IA4OtC;;OAEG;YACW,gBAAgB;CAmG/B"}
@@ -71,6 +71,7 @@ const CHECK_PROJECT_TYPES = {
71
71
  'GATEWAY-': ['openclaw'], // Gateway configuration security
72
72
  'CONFIG-': ['openclaw', 'mcp'], // Configuration file security
73
73
  'SUPPLY-': ['openclaw', 'mcp'], // Supply chain security
74
+ 'CVE-': ['openclaw'], // CVE-specific detection
74
75
  'API-': ['api'], // API security headers
75
76
  'RATE-': ['webapp', 'api'], // Rate limiting
76
77
  'PROC-': ['webapp', 'api'], // Process security (headers, etc.)
@@ -165,6 +166,19 @@ const HEARTBEAT_DANGEROUS_CAPS = [
165
166
  'filesystem:/',
166
167
  'network:*',
167
168
  ];
169
+ // ClawHavoc campaign IOCs (Koi Security research, Jan 2026)
170
+ const CLAWHAVOC_C2_IPS = ['91.92.242.30'];
171
+ const CLAWHAVOC_MALICIOUS_FILES = [
172
+ 'openclaw-agent.exe', 'openclaw-agent.zip', 'openclawcli.zip',
173
+ 'agent-setup.exe', 'openclaw-installer.dmg',
174
+ ];
175
+ const CLAWHAVOC_CLICKFIX_PATTERNS = [
176
+ /download.*paste.*terminal/i,
177
+ /copy.*(?:command|script).*terminal/i,
178
+ /right[- ]click.*open/i,
179
+ /run.*\.exe/i,
180
+ ];
181
+ const CLAWHAVOC_ARCHIVE_PASSWORD = /password\s*[:=]\s*["']?(openclaw|claw|agent|setup)["']?/i;
168
182
  const PROMPT_INJECTION_PATTERNS = [
169
183
  /ignore\s+(all\s+)?(previous|prior|above)/gi,
170
184
  /disregard\s+(all\s+)?(previous|prior)/gi,
@@ -320,6 +334,9 @@ class HardeningScanner {
320
334
  // OpenClaw supply chain checks
321
335
  const supplyFindings = await this.checkOpenclawSupplyChain(targetDir, shouldFix);
322
336
  findings.push(...supplyFindings);
337
+ // OpenClaw CVE-specific checks
338
+ const cveFindings = await this.checkOpenclawCVE(targetDir, shouldFix);
339
+ findings.push(...cveFindings);
323
340
  // Filter findings to only show real, actionable issues:
324
341
  // 1. Only failed checks (passed: false)
325
342
  // 2. Only checks with a file path (concrete findings, not generic advice)
@@ -4495,6 +4512,58 @@ dist/
4495
4512
  fix: 'Manually disable privileged mode and remove sensitive host mounts - requires careful review',
4496
4513
  });
4497
4514
  }
4515
+ // GATEWAY-007: Open DM Policy with Wildcard
4516
+ const channels = config.channels;
4517
+ const dm = config.dm;
4518
+ let hasOpenDmWildcard = false;
4519
+ if (channels) {
4520
+ for (const [, channelConfig] of Object.entries(channels)) {
4521
+ if (channelConfig.dmPolicy === 'open' &&
4522
+ Array.isArray(channelConfig.allowFrom) &&
4523
+ channelConfig.allowFrom.includes('*')) {
4524
+ hasOpenDmWildcard = true;
4525
+ break;
4526
+ }
4527
+ }
4528
+ }
4529
+ if (!hasOpenDmWildcard && dm?.policy === 'open') {
4530
+ const allowList = dm.allowFrom;
4531
+ if (Array.isArray(allowList) && allowList.includes('*')) {
4532
+ hasOpenDmWildcard = true;
4533
+ }
4534
+ }
4535
+ if (hasOpenDmWildcard) {
4536
+ findings.push({
4537
+ checkId: 'GATEWAY-007',
4538
+ name: 'Open DM Policy with Wildcard',
4539
+ description: 'Direct message policy allows messages from any source',
4540
+ category: 'gateway',
4541
+ severity: 'critical',
4542
+ passed: false,
4543
+ message: 'DM policy is open with wildcard allowFrom - anyone can message the agent',
4544
+ file: relativePath,
4545
+ fixable: false,
4546
+ fix: 'Replace wildcard "*" in allowFrom with specific allowed sender IDs or domains',
4547
+ });
4548
+ }
4549
+ // GATEWAY-008: Tailscale Funnel Exposure
4550
+ const tailscale = gateway?.tailscale;
4551
+ const tailscaleRoot = config.tailscale;
4552
+ const funnelEnabled = tailscale?.funnel === true || tailscaleRoot?.funnel === true;
4553
+ if (funnelEnabled) {
4554
+ findings.push({
4555
+ checkId: 'GATEWAY-008',
4556
+ name: 'Tailscale Funnel Exposure',
4557
+ description: 'Tailscale Funnel is enabled, exposing the agent to the public internet',
4558
+ category: 'gateway',
4559
+ severity: 'high',
4560
+ passed: false,
4561
+ message: 'Tailscale Funnel enabled - agent is publicly accessible from the internet',
4562
+ file: relativePath,
4563
+ fixable: false,
4564
+ fix: 'Disable Tailscale Funnel unless public access is intentional. Use Tailscale ACLs to restrict access.',
4565
+ });
4566
+ }
4498
4567
  // Write modified config back to file if any fixes were applied
4499
4568
  if (configModified) {
4500
4569
  try {
@@ -4873,6 +4942,71 @@ dist/
4873
4942
  fix: 'Disable autoFollow or review moltbook security settings',
4874
4943
  });
4875
4944
  }
4945
+ // CONFIG-007: Unrestricted Elevated Execution
4946
+ const tools = config.tools;
4947
+ const elevated = tools?.elevated;
4948
+ const exec = config.exec;
4949
+ const execApprovals = exec?.approvals;
4950
+ const hasUnrestrictedExec = elevated?.defaultLevel === 'full' ||
4951
+ execApprovals?.set === 'off';
4952
+ if (hasUnrestrictedExec) {
4953
+ findings.push({
4954
+ checkId: 'CONFIG-007',
4955
+ name: 'Unrestricted Elevated Execution',
4956
+ description: 'Elevated execution is set to full access without restrictions or approvals are bypassed',
4957
+ category: 'config',
4958
+ severity: 'critical',
4959
+ passed: false,
4960
+ message: elevated?.defaultLevel === 'full'
4961
+ ? 'tools.elevated.defaultLevel is "full" - all tools run with maximum privileges'
4962
+ : 'exec.approvals.set is "off" - execution approval is bypassed',
4963
+ file: relativePath,
4964
+ fixable: false,
4965
+ fix: 'Set tools.elevated.defaultLevel to "restricted" and enable exec.approvals',
4966
+ });
4967
+ }
4968
+ // CONFIG-008: Sandbox Disabled
4969
+ const sandbox = config.sandbox;
4970
+ const toolExec = tools?.exec;
4971
+ const sandboxDisabled = sandbox?.enabled === false ||
4972
+ toolExec?.sandbox === false;
4973
+ if (sandboxDisabled) {
4974
+ findings.push({
4975
+ checkId: 'CONFIG-008',
4976
+ name: 'Sandbox Disabled',
4977
+ description: 'Sandbox execution environment is explicitly disabled in config',
4978
+ category: 'config',
4979
+ severity: 'high',
4980
+ passed: false,
4981
+ message: sandbox?.enabled === false
4982
+ ? 'sandbox.enabled is false - code runs without isolation'
4983
+ : 'tools.exec.sandbox is false - tool execution is not sandboxed',
4984
+ file: relativePath,
4985
+ fixable: false,
4986
+ fix: 'Enable sandbox: set sandbox.enabled to true or tools.exec.sandbox to true',
4987
+ });
4988
+ }
4989
+ // CONFIG-009: Weak Gateway Token
4990
+ const gatewayConfig = config.gateway;
4991
+ const gatewayAuth = gatewayConfig?.auth;
4992
+ const tokenValue = gatewayAuth?.token || config.token;
4993
+ if (typeof tokenValue === 'string' &&
4994
+ tokenValue.length > 0 &&
4995
+ tokenValue.length < 24 &&
4996
+ !tokenValue.startsWith('${')) {
4997
+ findings.push({
4998
+ checkId: 'CONFIG-009',
4999
+ name: 'Weak Gateway Token',
5000
+ description: 'Gateway authentication token is too short (< 24 characters)',
5001
+ category: 'config',
5002
+ severity: 'high',
5003
+ passed: false,
5004
+ message: `Token is only ${tokenValue.length} characters - minimum 24 recommended`,
5005
+ file: relativePath,
5006
+ fixable: false,
5007
+ fix: 'Generate a stronger token: openssl rand -base64 32',
5008
+ });
5009
+ }
4876
5010
  }
4877
5011
  return findings;
4878
5012
  }
@@ -4891,6 +5025,16 @@ dist/
4891
5025
  'phantom-wallet',
4892
5026
  'youtube-downloader',
4893
5027
  'clawhub',
5028
+ 'clawhub1',
5029
+ 'clawhubb',
5030
+ 'cllawhub',
5031
+ 'clawhub-official',
5032
+ 'openclaw-official',
5033
+ 'openclaw1',
5034
+ 'opennclaw',
5035
+ 'insiderwallet',
5036
+ 'wallet-finder',
5037
+ 'crypto-insider',
4894
5038
  ];
4895
5039
  for (const skillFile of skillFiles) {
4896
5040
  const relativePath = path.relative(targetDir, skillFile);
@@ -5008,6 +5152,170 @@ dist/
5008
5152
  fixable: false,
5009
5153
  fix: 'Add installed_hash: with SHA-256 hash of the original skill content',
5010
5154
  });
5155
+ // SUPPLY-005: ClawHavoc C2 IP
5156
+ for (const ip of CLAWHAVOC_C2_IPS) {
5157
+ if (content.includes(ip)) {
5158
+ findings.push({
5159
+ checkId: 'SUPPLY-005',
5160
+ name: 'ClawHavoc C2 IP Detected',
5161
+ description: 'Skill contains known ClawHavoc command-and-control IP address',
5162
+ category: 'supply',
5163
+ severity: 'critical',
5164
+ passed: false,
5165
+ message: `Known C2 IP address found: ${ip}`,
5166
+ file: relativePath,
5167
+ fixable: false,
5168
+ fix: 'Remove this skill immediately - contains known malware C2 infrastructure',
5169
+ });
5170
+ break;
5171
+ }
5172
+ }
5173
+ // SUPPLY-006: Malware Filenames
5174
+ for (const filename of CLAWHAVOC_MALICIOUS_FILES) {
5175
+ if (content.toLowerCase().includes(filename.toLowerCase())) {
5176
+ findings.push({
5177
+ checkId: 'SUPPLY-006',
5178
+ name: 'ClawHavoc Malware Filename',
5179
+ description: 'Skill references known ClawHavoc malware payload filename',
5180
+ category: 'supply',
5181
+ severity: 'critical',
5182
+ passed: false,
5183
+ message: `Known malware filename referenced: "${filename}"`,
5184
+ file: relativePath,
5185
+ fixable: false,
5186
+ fix: 'Remove this skill immediately - references known malware payload',
5187
+ });
5188
+ break;
5189
+ }
5190
+ }
5191
+ // SUPPLY-007: ClickFix Pattern
5192
+ for (const pattern of CLAWHAVOC_CLICKFIX_PATTERNS) {
5193
+ const match = content.match(pattern);
5194
+ if (match) {
5195
+ findings.push({
5196
+ checkId: 'SUPPLY-007',
5197
+ name: 'ClawHavoc ClickFix Pattern',
5198
+ description: 'Skill contains social engineering instructions to execute malware',
5199
+ category: 'supply',
5200
+ severity: 'high',
5201
+ passed: false,
5202
+ message: `ClickFix social engineering pattern detected: "${match[0]}"`,
5203
+ file: relativePath,
5204
+ fixable: false,
5205
+ fix: 'Review and remove suspicious download/execute instructions',
5206
+ });
5207
+ break;
5208
+ }
5209
+ }
5210
+ // SUPPLY-008: Suspicious Archive Password
5211
+ const archiveMatch = content.match(CLAWHAVOC_ARCHIVE_PASSWORD);
5212
+ if (archiveMatch) {
5213
+ findings.push({
5214
+ checkId: 'SUPPLY-008',
5215
+ name: 'Suspicious Archive Password',
5216
+ description: 'Skill contains password-protected archive reference typical of malware distribution',
5217
+ category: 'supply',
5218
+ severity: 'high',
5219
+ passed: false,
5220
+ message: `Suspicious archive password pattern: "${archiveMatch[0]}"`,
5221
+ file: relativePath,
5222
+ fixable: false,
5223
+ fix: 'Investigate password-protected archive reference - common malware distribution technique',
5224
+ });
5225
+ }
5226
+ }
5227
+ return findings;
5228
+ }
5229
+ /**
5230
+ * OpenClaw CVE-specific checks (CVE-001, CVE-002)
5231
+ */
5232
+ async checkOpenclawCVE(targetDir, _autoFix) {
5233
+ const findings = [];
5234
+ // CVE-001: Vulnerable OpenClaw Version
5235
+ const pkgJsonPath = path.join(targetDir, 'package.json');
5236
+ try {
5237
+ const pkgContent = await fs.readFile(pkgJsonPath, 'utf-8');
5238
+ const pkg = JSON.parse(pkgContent);
5239
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
5240
+ const openclawVersion = deps?.openclaw || deps?.['@openclaw/core'];
5241
+ if (openclawVersion) {
5242
+ // Extract numeric version (strip ^ ~ >= etc.)
5243
+ const versionMatch = openclawVersion.match(/(\d{4})\.(\d{1,2})\.(\d{1,2})/);
5244
+ if (versionMatch) {
5245
+ const year = parseInt(versionMatch[1], 10);
5246
+ const month = parseInt(versionMatch[2], 10);
5247
+ const day = parseInt(versionMatch[3], 10);
5248
+ // Patch release: v2026.1.29
5249
+ const isVulnerable = year < 2026 ||
5250
+ (year === 2026 && month < 1) ||
5251
+ (year === 2026 && month === 1 && day < 29);
5252
+ findings.push({
5253
+ checkId: 'CVE-001',
5254
+ name: 'CVE-2026-25253: WebSocket Hijacking RCE',
5255
+ description: 'OpenClaw version vulnerable to CVE-2026-25253 (CVSS 8.8) - WebSocket hijacking enables 1-click RCE',
5256
+ category: 'cve',
5257
+ severity: 'critical',
5258
+ passed: !isVulnerable,
5259
+ message: isVulnerable
5260
+ ? `OpenClaw ${openclawVersion} is vulnerable to CVE-2026-25253 - upgrade to v2026.1.29+`
5261
+ : `OpenClaw ${openclawVersion} includes CVE-2026-25253 fix`,
5262
+ file: 'package.json',
5263
+ fixable: false,
5264
+ fix: 'Upgrade openclaw to v2026.1.29 or later: npm install openclaw@latest',
5265
+ });
5266
+ }
5267
+ }
5268
+ }
5269
+ catch {
5270
+ // No package.json or parse error - skip CVE-001
5271
+ }
5272
+ // CVE-002: Missing Control UI Origin Restrictions
5273
+ const configFiles = await this.findGatewayConfigFiles(targetDir);
5274
+ for (const configFile of configFiles) {
5275
+ const relativePath = path.relative(targetDir, configFile);
5276
+ try {
5277
+ const stats = await fs.stat(configFile);
5278
+ if (stats.size > MAX_FILE_SIZE)
5279
+ continue;
5280
+ const content = await fs.readFile(configFile, 'utf-8');
5281
+ const config = JSON.parse(content);
5282
+ const gateway = config.gateway;
5283
+ const controlUi = gateway?.controlUi;
5284
+ const hasAllowedOrigins = controlUi?.allowedOrigins && Array.isArray(controlUi.allowedOrigins) && controlUi.allowedOrigins.length > 0;
5285
+ // Only flag if auth is configured (no auth = lower risk)
5286
+ const hasAuth = gateway?.auth || config.auth || config.token || gateway?.token;
5287
+ if (hasAuth && !hasAllowedOrigins) {
5288
+ findings.push({
5289
+ checkId: 'CVE-002',
5290
+ name: 'CVE-2026-25253: Missing Control UI Origin Restrictions',
5291
+ description: 'Auth is configured but controlUi.allowedOrigins is missing - vulnerable to cross-origin WebSocket hijacking',
5292
+ category: 'cve',
5293
+ severity: 'critical',
5294
+ passed: false,
5295
+ message: 'Auth configured without controlUi.allowedOrigins - cross-origin requests can steal auth tokens',
5296
+ file: relativePath,
5297
+ fixable: false,
5298
+ fix: 'Add gateway.controlUi.allowedOrigins with your allowed origins (e.g., ["http://localhost:3000"])',
5299
+ });
5300
+ }
5301
+ else if (hasAuth && hasAllowedOrigins) {
5302
+ findings.push({
5303
+ checkId: 'CVE-002',
5304
+ name: 'CVE-2026-25253: Control UI Origin Restrictions',
5305
+ description: 'Control UI origin restrictions are configured',
5306
+ category: 'cve',
5307
+ severity: 'critical',
5308
+ passed: true,
5309
+ message: 'controlUi.allowedOrigins is configured',
5310
+ file: relativePath,
5311
+ fixable: false,
5312
+ fix: 'No action needed',
5313
+ });
5314
+ }
5315
+ }
5316
+ catch {
5317
+ continue;
5318
+ }
5011
5319
  }
5012
5320
  return findings;
5013
5321
  }