Back to skill

Security audit

Nex Life Logger

Security checks for vulnerabilities and agentic risk

Overview

This is a real local life-logging tool, but it installs continuous activity monitoring and has under-disclosed privacy and credential-handling risks.

Install only if you intentionally want a persistent local activity recorder. Review setup.sh before running it, stop or disable the service when not needed, avoid configuring an API key unless you accept activity summaries being sent to that provider, prefer environment variables over the built-in key storage, and treat exports as highly private files.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
nex-life-logger.py:750
Finding

API Key Is Duplicated into Plaintext and Reversibly Encoded Files

Content
View full analysis
Remediation
View remediation

other

Warning
Location
lib/collector_headless.py:151
Finding

YouTube Video Identifiers Are Disclosed Before Privacy Filtering

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
setup.sh:74
Finding

Setup Installs Mutable and Unverified Third-Party Dependency Versions

Content
View full analysis
=1.0" \ "psutil>=5.9" \ "youtube-transcript-api>=0.6" echo " Dependencies installed." ``` ### Technical Analysis The setup script installs packages using lower-bound version constraints. These constraints allow pip to select any later release available at installation time. No lockfile, exact version pin, package hash, or trusted mirror configuration is supplied. The packages identified in the audit are legitimate packages; no evidence was found that the currently intended packages are malicious. The vulnerability is that the reviewed Skill does not determine the exact code that a future installation will execute. The unconditional pip upgrade creates an additional mutable installation step. A future compromised package release, index compromise, account takeover, or malicious transitive dependency could introduce code that was not present during this audit. This risk is amplified because installed modules run inside a persistent activity collector with access to browser history, active-window titles, locally stored transcripts, the activity database, and potentially LLM credentials. ### Attack Path 1. An attacker compromises a dependency publisher account, package-index distribution path, or transitive dependency. 2. A malicious package version is published while still satisfying `openai>=1.0`, `psutil>=5.9`, or `youtube-transcript-api>=0.6`. 3. A user follows the documented installation process and runs `setup.sh`. 4. Pip resolves and installs the malicious version because no exact pin or hash prevents it. 5. Package installation hooks or imported package code execute as the user. 6. The setup script installs ...[truncated 752 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (74)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file implements continuous background collection of browser history, active-window details, and transcript-derived context, but the usage/help text does not provide a meaningful privacy warning at the point of execution. Because this is surveillance-style functionality running headlessly, insufficient disclosure materially increases the risk of uninformed or accidental monitoring.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · lib/config.py (reported line 31)May include surrounding context.

python
# Sensitive window title keywords - windows matching these are NEVER logged
SENSITIVE_WINDOW_KEYWORDS = [
    "password", "passwd", "credential", "keychain", "vault",
    "1password", "lastpass", "bitwarden", "keepass", "dashlane",
    "private browsing", "incognito", "inprivate",
    "bank", "banking",

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · lib/user_filters.py (reported line 255)May include surrounding context.

python
# Sensitive window title keywords - windows matching these are NEVER logged
SENSITIVE_WINDOW_KEYWORDS = [
    "password", "passwd", "credential", "keychain", "vault",
    "1password", "lastpass", "bitwarden", "keepass", "dashlane",
    "private browsing", "incognito", "inprivate",
    "bank", "banking",

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The installer unconditionally creates and starts a persistent background collector via systemd or launchd, which causes continuous monitoring after setup. In the context of a life-logging tool that captures browser history, active windows, and media activity, auto-starting collection without an explicit consent prompt or strong warning materially increases privacy risk and can surprise users about ongoing surveillance.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README promotes silent tracking of browser history, active windows, and YouTube transcripts without presenting an equally prominent upfront warning about the scope and sensitivity of the collected data. Even if the tool is local-only, users may install it without fully understanding that it continuously records behavioral history, which creates meaningful privacy and consent risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill exposes significant capabilities—shell execution, file access, environment access, and potential network use—without declaring an explicit tool scope or permission boundary. Because the skill handles highly sensitive local activity data and includes setup/service commands, an agent could invoke powerful operations without clear user-visible constraints, increasing the chance of overreach or unintended data exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill centers on persistent background collection of browser history, active window focus, and transcripts, but the user-facing description does not prominently warn that this is highly sensitive surveillance data. Users may invoke or install the skill without appreciating the privacy implications, especially since it can run a background collector and retain detailed behavioral history.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger phrases are broad everyday requests like browsing history, productivity, and what I did yesterday, which can cause the skill to activate in loosely related conversations. In a skill that accesses sensitive local surveillance-style data and can start services or export data, overbroad activation increases the risk of unintended collection, querying, or disclosure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The collector imports and later uses YouTube transcript retrieval even though the skill description emphasizes local-only activity tracking. Fetching transcripts can send watched video identifiers or related metadata to external services, creating a discrepancy between user expectations and actual data flows.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code fetches YouTube transcripts for visited videos, extending collection beyond passive local logging into active retrieval of remote content. In a life-logging skill, that increases sensitivity because user viewing behavior is enriched and potentially disclosed to third parties without obvious consent at the collection point.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Transcript retrieval introduces outbound network activity tied to browsing history, but that behavior is not clearly disclosed in this collector flow. In a tool marketed around local activity tracking, undisclosed network transmission is especially risky because it violates user expectations about data locality and exposure.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · lib/collector_headless.py (reported line 303)May include surrounding context.

python
return appName & "|" & winTitle
            end tell
            '''
            result = subprocess.run(["osascript", "-e", script], capture_output=True, text=True, timeout=5)
            if result.returncode == 0:
                parts = result.stdout.strip().split("|", 1)
                process = parts[0] if parts else ""

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · lib/collector_headless.py (reported line 310)May include surrounding context.

python
title = parts[1] if len(parts) > 1 else ""
        else:
            import subprocess
            result = subprocess.run(["xdotool", "getactivewindow", "getwindowname"],
                                    capture_output=True, text=True, timeout=5)
            title = result.stdout.strip() if result.returncode == 0 else ""
            try:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · lib/collector_headless.py (reported line 314)May include surrounding context.

python
capture_output=True, text=True, timeout=5)
            title = result.stdout.strip() if result.returncode == 0 else ""
            try:
                pid_result = subprocess.run(["xdotool", "getactivewindow", "getwindowpid"],
                                            capture_output=True, text=True, timeout=5)
                if pid_result.returncode == 0:
                    import psutil

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The function exports multiple database tables into a single JSON file, including activities, summaries, keywords, and transcripts, which likely contain sensitive personal or behavioral data. Although the docstring states that it exports everything, there is no confirmation prompt, user-facing log/print, or explicit warning about the privacy impact of creating a full data dump.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code exports life-logging summaries into an HTML file, which can contain sensitive personal information, but the function only has a minimal docstring and provides no visible disclosure, confirmation, or logging to warn the user that private data is being written out. Under the code-file criteria, file writes affecting user data should have some form of user disclosure unless clearly warned elsewhere in the skill, which is not shown here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code extracts keywords from user activity data, including search queries, and elsewhere processes transcript text, which are privacy-sensitive inputs. There is no confirmation prompt, user-facing log/print, or explanatory comment/docstring in this file disclosing that personal activity content is being analyzed.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · lib/secure_key.py (reported line 7)May include surrounding context.

python
Storage methods by platform:
  - Windows: Windows Credential Manager (preferred) or DPAPI-encrypted file
  - macOS/Linux: Owner-only permission file (chmod 600). For stronger security,
    set the AI_API_KEY environment variable instead.

No API keys are stored or transmitted unless the user explicitly configures them.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · lib/secure_key.py (reported line 32)May include surrounding context.

python
def _win_store(key):
    import subprocess
    subprocess.run(["cmdkey", "/delete:" + SERVICE_NAME], capture_output=True)
    result = subprocess.run(
        ["cmdkey", "/generic:" + SERVICE_NAME, "/user:" + ACCOUNT_NAME, "/pass:" + key],
        capture_output=True, text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · lib/secure_key.py (reported line 78)May include surrounding context.

python
def _win_store(key):
    import subprocess
    subprocess.run(["cmdkey", "/delete:" + SERVICE_NAME], capture_output=True)
    result = subprocess.run(
        ["cmdkey", "/generic:" + SERVICE_NAME, "/user:" + ACCOUNT_NAME, "/pass:" + key],
        capture_output=True, text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
87% confidence
Finding

The code passes the API key as a command-line argument to cmdkey (/pass:<key>). On Windows, command-line arguments may be exposed to local process inspection, logging, crash dumps, EDR tooling, or other administrative monitoring, which can leak the secret even though the ultimate storage target is Credential Manager.

Content

Scanner excerpt · lib/secure_key.py (reported line 33)May include surrounding context.

python
def _win_store(key):
    import subprocess
    subprocess.run(["cmdkey", "/delete:" + SERVICE_NAME], capture_output=True)
    result = subprocess.run(
        ["cmdkey", "/generic:" + SERVICE_NAME, "/user:" + ACCOUNT_NAME, "/pass:" + key],
        capture_output=True, text=True,
    )

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code initializes and persists a local SQLite database containing behavioral data such as activities, summaries, keywords, and transcripts. For code files, SQP-2 applies when file writes affecting user data occur without confirmation, visible logging/print statements, or user-facing warnings; the docstrings here are implementation-focused and do not clearly warn users that this personal data is being stored on disk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function stores full transcript text in the transcripts table, which may contain sensitive personal or proprietary content. There is no confirmation prompt, visible user-facing notice, or warning in this file indicating that transcript data will be retained locally, so the persistence happens without disclosure under SQP-2's code-file criteria.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code sends raw user activity logs and YouTube transcript snippets to a configured external LLM provider via client.chat.completions.create(...). Although the project requires explicit provider configuration, there is no per-request consent, transmission-time warning, or visible data minimization at the point sensitive browsing/application history is exported, so highly personal behavioral data may be disclosed to third parties once configured.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

reset_to_defaults() removes the existing user_filters.json file via unlink(), which is a destructive operation because it discards customized settings. This function contains no confirmation prompt and no user-facing disclosure explaining that persisted user configuration will be deleted.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.