Back to skill

Security audit

KlausNomi

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed Nomi API command-line skill with normal API-key, network, room, avatar, and local-state behavior for its purpose, and I found no hidden or deceptive activity.

Install only if you are comfortable giving the skill access to your Nomi account through NOMI_API_KEY. Treat chats, profile data, room notes, and saved summaries as potentially sensitive, clear the local nomi/ directory when needed, and require explicit confirmation before room updates or deletions.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Tainted flow: 'req' from os.environ.get (line 61, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/nomi.py (reported line 64)May include surrounding context.

python
req = request.Request(url, data=body, headers=headers, method=method)

    try:
        with request.urlopen(req, timeout=_timeout_seconds()) as response:
            content = response.read()
            content_type = response.headers.get("Content-Type", "")
            return content, content_type

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description suggests simple conversation functionality, but the documented commands also support metadata retrieval, avatar downloads, room management, local file persistence, and networked API operations. This mismatch can mislead users and security reviewers about the skill's real behavior, which is dangerous because broader capabilities may be invoked without informed consent or proper review.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill exposes capabilities that imply environment access, local file writes, and network use, but it does not declare an explicit tool scope such as permissions or allowed-tools. That makes the skill's effective authority less transparent to users and reviewers, increasing the risk of unintended data access or outbound communication when invoked.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill mentions that data may be kept in the local nomi/ directory between sessions, but it does not present this as a prominent user-facing warning in the description. Users may share sensitive conversation content or room notes without realizing that non-secret context can persist locally, creating privacy and retention risks on the host system.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/nomi.py (reported line 14)May include surrounding context.

python
from typing import Any
from urllib import error, request

BASE_URL = "https://api.nomi.ai/v1"
DEFAULT_TIMEOUT_SECONDS = 120.0
AVATAR_OUTPUT_DIR = Path("nomi") / "avatars"

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest description is narrowly framed around engaging in conversations with Nomi AI companions. The code goes beyond conversation by creating, updating, and deleting rooms, and elsewhere writes avatar images to disk, which are broader account/content management operations rather than just conversation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The avatar command fetches companion avatar content and saves it under a local directory. Downloading media and writing files is not implied by a description limited to engaging in conversations via a CLI.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.