Back to skill

Security audit

Janee

Security checks across malware telemetry and agentic risk

Overview

Janee is a coherent local API-key proxy, but its defaults and URL handling can give agents broad authenticated API access beyond what users may expect.

Review carefully before installing. Use only narrowly scoped API keys, define explicit allow/deny rules for every capability, avoid production financial or write-capable credentials, and do not rely on autoApprove, sessions, or revoke as strong safety controls. Treat `~/.janee/config.yaml`, backups, sessions, and logs as sensitive local files.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (19)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill documentation describes MCP tool exposure and outbound network/API execution capabilities, but the skill metadata does not declare corresponding permissions. Undeclared capabilities reduce transparency and can bypass user or platform expectations about what the skill is allowed to do, which is especially sensitive for a security-focused secret-management skill that can proxy authenticated requests.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README recommends or exemplifies `autoApprove: true` during capability creation without an explicit warning that this allows the agent to perform external API actions autonomously once access is configured. In a secrets-broker tool for AI agents, normalizing auto-approval materially increases the chance of unintended charges, data modification, or other side effects if the agent is prompt-injected or misaligned.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The documentation states that when no rules are defined, requests are allowed by default, but it does not clearly warn that this can grant effectively unrestricted API access to the configured service. In this product context, broad defaults are especially dangerous because the whole tool is designed to let agents invoke real external APIs using stored credentials.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The command interactively collects API keys, HMAC secrets, and arbitrary auth headers, then persists them via saveYAMLConfig without any visible warning that they will be stored in the local YAML config. In a secrets-management tool, silently writing plaintext credentials to disk can expose sensitive material through weak file permissions, backups, source-control mistakes, or later accidental disclosure.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The configuration file stores the masterKey in the same YAML document as the encrypted service credentials, so compromise of the file defeats the protection provided by encryption at rest. In a secrets-management tool this is especially risky because users may incorrectly assume the stored secrets are meaningfully protected without being warned that the file itself is effectively the single point of compromise.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The logger persistently records API request metadata to local disk without any indication in this code of user notice, consent, or retention controls. In a secrets-management context, even logging only service, method, path, status, and timing can reveal sensitive usage patterns, secret names embedded in paths, or operational behavior that an attacker or local user could mine from the filesystem.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
Denied requests are also written to disk without user-facing disclosure, and these entries may capture sensitive attempted actions and user-supplied reason strings. In a secrets-management skill, blocked access attempts can reveal protected resource identifiers, policies, and operator intent, creating a useful reconnaissance source if the host is compromised or shared.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The server performs arbitrary outbound HTTP/HTTPS requests using agent-supplied path, method, headers, and body, but this file provides no user-facing disclosure, consent, or confirmation at execution time. In a secrets-management MCP server, silent network transmission is especially sensitive because agents may proxy privileged requests or exfiltrate sensitive data through configured services without meaningful human awareness.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
stripe:
    service: stripe
    ttl: 1h
    autoApprove: true

  stripe_sensitive:
    service: stripe
Confidence
91% confidence
Finding
autoApprove

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
const ttl = ttlInput.trim() || '1h';

      const autoApproveInput = await rl.question('Auto-approve? (Y/n): ');
      const autoApprove = !autoApproveInput || autoApproveInput.toLowerCase() === 'y' || autoApproveInput.toLowerCase() === 'yes';

      const requiresReasonInput = await rl.question('Requires reason? (y/N): ');
      const requiresReason = requiresReasonInput.toLowerCase() === 'y' || requiresReasonInput.toLowerCase() === 'yes';
Confidence
71% confidence
Finding
autoApprove

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
const ttl = ttlInput.trim() || '1h';

      const autoApproveInput = await rl.question('Auto-approve? (Y/n): ');
      const autoApprove = !autoApproveInput || autoApproveInput.toLowerCase() === 'y' || autoApproveInput.toLowerCase() === 'yes';

      const requiresReasonInput = await rl.question('Requires reason? (y/N): ');
      const requiresReason = requiresReasonInput.toLowerCase() === 'y' || requiresReasonInput.toLowerCase() === 'yes';
Confidence
71% confidence
Finding
autoApprove

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
const ttl = ttlInput.trim() || '1h';

      const autoApproveInput = await rl.question('Auto-approve? (Y/n): ');
      const autoApprove = !autoApproveInput || autoApproveInput.toLowerCase() === 'y' || autoApproveInput.toLowerCase() === 'yes';

      const requiresReasonInput = await rl.question('Requires reason? (y/N): ');
      const requiresReason = requiresReasonInput.toLowerCase() === 'y' || requiresReasonInput.toLowerCase() === 'yes';
Confidence
71% confidence
Finding
autoApprove

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
const ttl = ttlInput.trim() || '1h';

      const autoApproveInput = await rl.question('Auto-approve? (Y/n): ');
      const autoApprove = !autoApproveInput || autoApproveInput.toLowerCase() === 'y' || autoApproveInput.toLowerCase() === 'yes';

      const requiresReasonInput = await rl.question('Requires reason? (y/N): ');
      const requiresReason = requiresReasonInput.toLowerCase() === 'y' || requiresReasonInput.toLowerCase() === 'yes';
Confidence
71% confidence
Finding
autoApprove

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
config.capabilities[capName] = {
        service: serviceName,
        ttl,
        autoApprove,
        requiresReason
      };
Confidence
67% confidence
Finding
autoApprove

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
newConfig.capabilities[service.name] = {
        service: service.name,
        ttl: '1h',
        autoApprove: true
      };
    }
  }
Confidence
90% confidence
Finding
autoApprove

Known Vulnerable Dependency: @modelcontextprotocol/sdk==1.25.3 — 1 advisory(ies): CVE-2026-25536 (@modelcontextprotocol/sdk has cross-client data leak via shared server/transport)

High
Category
Supply Chain
Confidence
95% confidence
Finding
@modelcontextprotocol/sdk==1.25.3

Known Vulnerable Dependency: js-yaml==4.1.1 — 1 advisory(ies): CVE-2026-53550 (JS-YAML: Quadratic-complexity DoS in merge key handling via repeated aliases)

Low
Category
Supply Chain
Confidence
87% confidence
Finding
js-yaml==4.1.1

Known Vulnerable Dependency: vitest==3.2.4 — 1 advisory(ies): CVE-2026-47429 (When Vitest UI server is listening, arbitrary file can be read and executed)

Critical
Category
Supply Chain
Confidence
89% confidence
Finding
vitest==3.2.4

Known Vulnerable Dependency: @modelcontextprotocol/sdk==1.0.0 — 2 advisory(ies): CVE-2026-0621 (Anthropic's MCP TypeScript SDK has a ReDoS vulnerability); CVE-2025-66414 (Model Context Protocol (MCP) TypeScript SDK does not enable DNS rebinding protec)

High
Category
Supply Chain
Confidence
97% confidence
Finding
@modelcontextprotocol/sdk==1.0.0

VirusTotal

56/56 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

No suspicious patterns detected.