Back to skill

Security audit

Kami Video Search

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to do what it claims, but it handles private camera footage and credentials with several under-disclosed or unsafe behaviors that warrant review before installation.

Review this carefully before installing. Use it only if you are comfortable uploading camera frames or videos to Kamivision for analysis, store credentials outside shared or backed-up folders, redact RTSP URLs, avoid the curl-to-bash setup path, and restrict KAMI_API_URL to the intended HTTPS Kamivision endpoint. Treat background recording, automatic deletion, and stop commands as high-impact operations that should stay under explicit user control.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
setup.sh:47
Finding

Mutable Remote Installer Is Downloaded and Executed Without Verification

Content
View full analysis
/dev/null; then echo " Installing pyenv first..." curl -fsSL https://pyenv.run | bash export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)" fi pyenv install 3.10 -s ``` The same unsafe installation pattern is recommended to users at `setup.sh:72`: ```bash echo " - Linux: curl https://pyenv.run | bash && pyenv install 3.10" ``` ### Technical Analysis The setup process pipes the current response from `https://pyenv.run` directly into Bash. The retrieved content is neither pinned to a reviewed version nor checked against a checksum or cryptographic signature. HTTPS protects the connection under normal circumstances, but it does not make a mutable upstream response reproducible or safe. Compromise of the upstream service, its hosting account, DNS, certificate infrastructure, or deployment pipeline would allow the effective installer payload to change after this Skill was reviewed. Installing Python is necessary for the declared functionality, but executing an unreviewed remote shell response is not the minimum privilege or safest mechanism required to install it. ### Attack Path 1. The user follows `SKILL.md` and runs `bash setup.sh`. 2. The host does not already have Python 3.10, Homebrew, Conda, or pyenv. 3. The script requests content from `https://pyenv.run`. 4. A compromised or malicious upstream returns attacker-controlled shell commands. 5. Bash executes those commands immediately with all privileges and data access of the user running setup. 6. The payload may alter files, steal credentials, install per ...[truncated 457 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
stream_recoder2.py:437
Finding

Surveillance Footage and API Credentials Can Be Sent to an Arbitrary Configured Endpoint

Content
View full analysis
str: with open(video_path, "rb") as f: return base64.b64encode(f.read()).decode("utf-8") def _extract_frames_base64(video_path: str, sample_fps: int = 1) -> List[str]: """Extract frames from video at specified fps, return base64-encoded JPEG list""" import cv2 cap = cv2.VideoCapture(video_path) if not cap.isOpened(): logger.warning( "Cannot open video for frame extraction: %s", video_path) return [] src_fps = cap.get(cv2.CAP_PROP_FPS) if src_fps <= 0: src_fps = 25.0 interval = max(1, int(src_fps / sample_fps)) frames_b64 = [] frame_idx = 0 while True: ret, frame = cap.read() if not ret: break if frame_idx % interval == 0: _, buf = cv2.imencode(".jpg", frame) frames_b64.append(base64.b64encode(buf.tobytes()).decode("utf-8")) frame_idx += 1 cap.release() return frames_b64 def _kami_detect_video(video_path: str, cfg: "Config") -> dict: """ Call Kamivision /v1/detect to generate description + embedding for video. Based on SUMMARY_UPLOAD_MODE, upload full video or extracted frame list. Returns {"summary": "...", "embedding": [...]} """ url = cfg.KAMI_API_URL if cfg.SUMMARY_UPLOAD_MODE == "video": b64 = _video_to_base64(video_path) payload = { "detectType": cfg.SUMMARY_DETECT_TYPE, "detectSubType": cfg.SUMMARY_DETECT_SUB_TYPE, "prompt": cfg.SUMMARY_PROMPT, "imageFile": "", "videoFile": b64, "skillId": cfg.skillId } else: frames = _extract_frames_base64(video_path, cfg.SUMMARY_SAMPLE_FPS) payload = ...[truncated 2547 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
stream_recoder2.py:151
Finding

API Key Is Persisted in Plaintext Despite Encryption Claims

Content
View full analysis
"Config": """Load config from JSON file, use defaults for unspecified fields""" cfg = cls() if os.path.exists(path): with open(path, "r", encoding="utf-8") as f: data = json.load(f) for k, v in data.items(): if hasattr(cfg, k): setattr(cfg, k, v) return cfg def to_json(self, path: str): """Export current config to JSON""" data = {k: v for k, v in vars(self.__class__).items() if not k.startswith("_") and not callable(v)} # Override with instance values data.update({k: v for k, v in self.__dict__.items()}) with open(path, "w", encoding="utf-8") as f: json.dump(data, f, indent=2, ensure_ascii=False) ``` The configuration explicitly contains the credential field: ```json "KAMI_API_URL": "https://kamiclaw-skill-api.kamihome.com/v1/detect", "KAMI_API_KEY": "", ``` ### Technical Analysis The Skill instructs users to place `KAMI_API_KEY` in `stream_config.json`. Configuration loading and export use ordinary JSON reads and writes without encryption, an operating-system key store, secret indirection, or explicit restrictive file permissions. The file is created using the process's default permissions as affected by its umask. On systems with permissive defaults or shared project directories, other users or processes may be able to read the key. Configuration export also serializes instance values, potentially copying a configured key into another plaintext file. This contradicts the README statement that the API key is stored locally in encrypted form. ### Attack Path 1. A user configures a valid Kamivision API key in `stream_config.json`. 2. The key remains as plaintext JSON or is written ...[truncated 634 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
stream_recoder2.py:1121
Finding

Unverified PID File Allows Termination of Unrelated Processes

Content
View full analysis
Optional[int]: """Read PID file, return PID or None""" if not os.path.exists(pid_file): return None try: with open(pid_file, "r") as f: return int(f.read().strip()) except (ValueError, OSError): return None def _is_pid_alive(pid: int) -> bool: """Check if process is alive""" try: os.kill(pid, 0) return True except OSError: return False ``` The stop operation trusts and signals that value directly: ```python def _stop_daemon(cfg: Config) -> dict: """Stop background recording process, return status JSON""" pid_file = _get_pid_file(cfg) pid = _read_pid(pid_file) if pid is None: return {"status": "not_running", "device_id": cfg.DEVICE_ID, "message": f"[{cfg.DEVICE_ID}] No running recording process found"} if not _is_pid_alive(pid): os.remove(pid_file) return {"status": "not_running", "device_id": cfg.DEVICE_ID, "message": f"[{cfg.DEVICE_ID}] Process (PID={pid}) no longer exists, PID file cleaned up"} # Send SIGTERM for graceful stop os.kill(pid, signal.SIGTERM) # Wait up to 10 seconds for _ in range(20): if not _is_pid_alive(pid): break time.sleep(0.5) if _is_pid_alive(pid): os.kill(pid, signal.SIGKILL) time.sleep(0.5) if os.path.exists(pid_file): os.remove(pid_file) ``` ### Technical Analysis The implementation treats any integer found in `recorder.pid` as the recorder process. It checks only whether a process with that PID exists. It does not verify the executable path, command line, process start time, ownership, session, or a recorder-specific authentication token. PIDs are reu ...[truncated 1257 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Dependency Installation Is Not Reproducibly Pinned or Integrity-Verified

Content
View full analysis
=1.21.0,<2.0.0 requests>=2.28.0,<3.0.0 opencv-python>=4.6.0,<5.0.0 ``` The setup script installs the resolved versions directly: ```bash $PIP install --upgrade pip -q $PIP install -r "$REQUIREMENTS" -q ``` ### Technical Analysis All dependencies use broad version ranges rather than exact reviewed versions. Installation therefore depends on the state of the configured package index at setup time. No lockfile, artifact hash, package signature, or `--require-hashes` enforcement is present. The package names appear to be legitimate and no typosquatting or dependency confusion was identified in the reviewed file. The weakness is that future releases within the accepted ranges can be installed without another Skill review. A compromised package publisher, package index, or dependency account could consequently introduce malicious code. ### Attack Path 1. An upstream dependency account, release pipeline, or configured package index is compromised. 2. A malicious version is published within one of the accepted version ranges. 3. The user runs `setup.sh`. 4. pip resolves the newly published version because it satisfies the range. 5. Installation hooks or imported package code execute with the privileges of the user running setup or the recorder. 6. The malicious dependency can access local configuration, API credentials, camera streams, and recordings. ### Impact Assessment A malicious dependency may achieve arbitrary code execution as the installing or runtime user. It could read surveillance footage, steal the API key and RTSP credentials, modify recordings, or establish further persistence. Exploitation depends on compromise of an upstream package or package source; no currently malicious package was established by this audit. ]]>
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (34)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is presented as a recorder/search utility, but it also includes environment bootstrapping and dependency installation behavior. This mismatch can cause the agent to perform unexpected system modification and network-fetching actions outside the user's likely understanding, which is risky in a user-invocable skill.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Routing unmatched requests to the 'closest intent' can cause the agent to execute sensitive actions such as starting/stopping recording, modifying config, or showing logs based on ambiguous language. In a surveillance-related skill, mistaken intent resolution can affect privacy, availability, and user trust.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
99% confidence
Finding

Fetching an external script and piping it directly into bash is a high-risk pattern because it grants immediate code execution to unaudited remote content. In a setup script for a camera recorder, this behavior is not essential to core functionality and broadens the trust boundary beyond the skill's stated purpose.

Content

Scanner excerpt · setup.sh (reported line 53)May include surrounding context.

sh
echo "   Installing via pyenv (user-level, no sudo required)..."
        if ! command -v pyenv &>/dev/null; then
            echo "   Installing pyenv first..."
            curl -fsSL https://pyenv.run | bash
            export PYENV_ROOT="$HOME/.pyenv"
            export PATH="$PYENV_ROOT/bin:$PATH"
            eval "$(pyenv init -)"

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

The '| bash' chaining pattern removes any opportunity to validate, pin, or inspect downloaded content before execution. If the remote source is compromised or altered, the installer becomes an arbitrary command execution vector during environment setup.

Content

Scanner excerpt · setup.sh (reported line 53)May include surrounding context.

sh
echo "   Installing via pyenv (user-level, no sudo required)..."
        if ! command -v pyenv &>/dev/null; then
            echo "   Installing pyenv first..."
            curl -fsSL https://pyenv.run | bash
            export PYENV_ROOT="$HOME/.pyenv"
            export PATH="$PYENV_ROOT/bin:$PATH"
            eval "$(pyenv init -)"

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · setup.sh (reported line 72)May include surrounding context.

sh
if ! command -v "$PYTHON_CMD" &>/dev/null && [ ! -f "$PYTHON_CMD" ]; then
        echo "❌ Installation failed. Please install Python 3.10 manually:"
        echo "   - macOS:  brew install python@3.10"
        echo "   - Linux:  curl https://pyenv.run | bash && pyenv install 3.10"
        echo "   - conda:  conda install python=3.10"
        exit 1
    fi

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The default configuration hardcodes RTSP credentials directly in source code. Embedded secrets are easily leaked through source distribution, logs, backups, screenshots, or repository history, and in this context they grant access to a surveillance stream.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Recorded surveillance content is transmitted to an external API endpoint without an explicit user-facing warning in the operational flow. Because the data consists of camera footage and potentially full video files, the privacy and confidentiality impact is significant if users expect local-only processing or if the third-party service is compromised or misconfigured.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The entire skill description, examples, and user interaction model are presented only in Chinese, including all sample commands the user is expected to say. There is no indication that other languages are supported or that Chinese is a required locale for a justified region-specific use case, which creates a language-policy concern.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README advertises broad natural-language control such as saying '开始录制' to trigger actions, without defining strict invocation boundaries, confirmations, or exclusion cases. In an agent-integrated skill, overly generic triggers can cause accidental activation or unintended execution from ordinary conversation, logs, or transcribed ambient speech.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The search examples use open-ended everyday language without clearly separating passive discussion from actionable search commands. In a voice/chat agent context, this ambiguity increases the chance of unintended searches or command confusion, which can expose sensitive clips, consume API credits, or interfere with operator expectations.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README makes a strong local-storage/privacy claim while the same document also states that frames or video may be uploaded to an external AI API for analysis. This can mislead users into exposing sensitive surveillance footage under false assumptions about data residency and disclosure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The privacy section says data is local and does not leak, but elsewhere the skill documents transmission of images or video to a remote API. In a camera-recording product, inaccurate privacy representations are especially risky because users may process highly sensitive footage of homes, children, customers, or employees.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill instructs the agent to read and write configuration files, run shell commands, create a virtual environment, and access network resources, yet it declares no explicit tool restrictions. That makes the effective capability surface broader than what a reviewer or runtime policy can easily validate, increasing the risk of unintended file/system/network actions in a user-invocable skill.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Several trigger phrases like 'what happened' or 'show recent' are broad and may match casual conversation not intended to invoke surveillance actions. Because the skill handles camera feeds and logs, loose triggers raise the chance of accidental disclosure or unintended recorder control.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill asks users to provide RTSP URLs that commonly embed usernames and passwords, and states these values are written to a local config file, but it does not clearly warn users that sensitive credentials will be stored locally. This can lead to inadvertent credential exposure through local file access, backups, logs, or later display.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The confirmation flow instructs the agent to display camera summaries that include full STREAM_URL values, which may contain embedded usernames and passwords. Echoing secrets back to the user or chat transcript increases the chance of credential leakage through conversation history, screenshots, logs, or shoulder surfing.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Scenario C explicitly tells the agent to display configured cameras with their DEVICE_ID and STREAM_URL, which can reveal saved RTSP credentials from the config file. Because this occurs during normal operation, it creates a repeatable secret disclosure path whenever a user asks to confirm existing configuration.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · setup.sh (reported line 37)May include surrounding context.

sh
done
fi

# If not found, try to install (no sudo required)
if [ -z "$PYTHON_CMD" ]; then
    echo "⚠️  Python 3.10 not found. Attempting to install..."
    if command -v brew &>/dev/null; then

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · setup.sh (reported line 49)May include surrounding context.

sh
done
fi

# If not found, try to install (no sudo required)
if [ -z "$PYTHON_CMD" ]; then
    echo "⚠️  Python 3.10 not found. Attempting to install..."
    if command -v brew &>/dev/null; then

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · setup.sh (reported line 50)May include surrounding context.

sh
done
fi

# If not found, try to install (no sudo required)
if [ -z "$PYTHON_CMD" ]; then
    echo "⚠️  Python 3.10 not found. Attempting to install..."
    if command -v brew &>/dev/null; then

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The setup script downloads and immediately executes code from https://pyenv.run via a shell pipeline. This creates a supply-chain execution path where compromise of the remote endpoint, DNS/TLS interception, or an unexpected upstream change can lead to arbitrary code execution on the user's machine during setup.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script performs a network fetch and executes the result without a strong, explicit warning or consent step describing that arbitrary third-party code will run locally. Even if intended for convenience, silent remote code execution in an installer materially increases the risk of user compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code performs irreversible deletion of recorded video files and associated index records. While the high-level feature list mentions automatic cleanup, the deletion path itself has no confirmation prompt and no prominent user warning that retention cleanup will remove stored recordings.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code exports either full recorded video segments or extracted image frames to an external Kamivision API for summarization and embeddings, which materially expands the skill's data-handling beyond local recording/search. In a multi-camera surveillance context, this can leak sensitive footage, bystanders, home interiors, and behavioral data to a third party, especially because this transfer is automatic when description generation is enabled.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

This HTTP POST sends surveillance-derived payloads to an external service, including either extracted frames or full video content plus metadata. In the context of a camera recorder, external transmission materially increases privacy, confidentiality, and compliance risk, especially because it occurs as part of routine segment processing.

Content

Scanner excerpt · stream_recoder2.py (reported line 501)May include surrounding context.

python
last_error = None
    for attempt in range(1, cfg.KAMI_API_RETRY + 1):
        try:
            resp = http_requests.post(
                url, headers=headers, json=payload, timeout=60)
            resp.raise_for_status()
            data = resp.json()

Static analysis

No suspicious patterns detected.