Back to skill

Security audit

Nex Vault

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real local document-vault tool, but its Telegram setup can execute shell input and modifies shell startup files, so it needs review before use.

Review this before installing. Do not use the Telegram configuration commands as written unless fixed; store credentials in a restricted config file or keyring instead. Treat Telegram alerts as sending document metadata to a third party, and avoid untrusted export filenames because they may overwrite files outside the vault export folder.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
nex-vault.py:480
Finding

Shell Command Injection Through Telegram Configuration Input

Content
View full analysis
> ~/.bashrc']) print("Telegram Bot Token saved. Run 'source ~/.bashrc' to apply.") print(FOOTER) elif args.action == 'set-telegram-chat': chat_id = input("Enter Telegram Chat ID: ") import subprocess subprocess.run(['bash', '-c', f'echo "export NEX_VAULT_TELEGRAM_CHAT_ID={chat_id}" >> ~/.bashrc']) ``` ### Technical Analysis The Telegram token and chat ID are accepted as untrusted interactive input and interpolated directly into commands executed by `bash -c`. Bash parses command substitutions, backticks, quote-breaking sequences, redirections, and other shell metacharacters in the resulting command. The apparent double quoting does not prevent command substitution. For example, an input containing `$(touch /tmp/nex-vault-pwned)` causes Bash to execute `touch` while evaluating the constructed command. A malicious value can also break out of the quoting context to run more complex commands. No format validation, shell escaping, or separation between data and executable shell syntax is applied. ### Attack Path 1. An attacker supplies or recommends a purported Telegram token or chat ID containing shell syntax. 2. The user or an automated Agent runs `nex-vault config set-telegram-token` or `nex-vault config set-telegram-chat`. 3. The malicious value is entered at the prompt. 4. The CLI interpolates it into the argument passed to `bash -c`. 5. Bash evaluates the injected command substitution or quote-breaking payload. 6. The payload executes with all privileges of the user running Nex Vault. A minimal command-substitution payload is: ```text $(touch /tmp/nex-vault-pw ...[truncated 504 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
nex-vault.py:480
Finding

Telegram Credentials Persisted in Plaintext Shell Startup File

Content
View full analysis
> ~/.bashrc']) print("Telegram Bot Token saved. Run 'source ~/.bashrc' to apply.") print(FOOTER) elif args.action == 'set-telegram-chat': chat_id = input("Enter Telegram Chat ID: ") import subprocess subprocess.run(['bash', '-c', f'echo "export NEX_VAULT_TELEGRAM_CHAT_ID={chat_id}" >> ~/.bashrc']) ``` ### Technical Analysis The configuration commands append the Telegram bot token and chat ID to `~/.bashrc` as unencrypted text. The implementation does not inspect or tighten that file's permissions. Because the values are exported, every process launched from a subsequent interactive Bash session inherits the credentials. This unnecessarily expands secret exposure beyond Nex Vault itself. Shell startup files are also commonly included in workstation backups and diagnostic collections. The bot token is an authentication credential: anyone who obtains it may be able to invoke Telegram Bot API operations as that bot, subject to Telegram's API permissions and bot configuration. ### Attack Path 1. The user configures Telegram through the Nex Vault CLI. 2. The token is appended in plaintext to `~/.bashrc`. 3. The user sources the file or starts a new Bash session. 4. The token becomes available in the shell environment and is inherited by unrelated child processes. 5. A local process, backup reader, support bundle recipient, or user with access to `.bashrc` obtains the token. 6. The exposed token is used to impersonate or misuse the Telegram bot. ### Impact Assessment Exposure may allow unauthorized use of the configur ...[truncated 404 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
nex-vault.py:459
Finding

Unrestricted Export Path Allows Overwriting User-Writable Files

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
setup.sh:94
Finding

Setup Installs Mutable Unpinned Dependencies Without Integrity Verification

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (26)

Tainted flow: 'token' from input (line 482, user input) → subprocess.run (code execution)

Critical
Category
Data Flow
Confidence
100% confidence
Finding

User input from input() flows directly into subprocess.run with bash -c, creating a direct command-injection sink. Because the payload is appended to ~/.bashrc, exploitation can yield immediate arbitrary code execution plus persistence across future shell sessions.

Content

Scanner excerpt · nex-vault.py (reported line 484)May include surrounding context.

python
elif args.action == 'set-telegram-token':
        token = input("Enter Telegram Bot Token: ")
        import subprocess
        subprocess.run(['bash', '-c', f'echo "export NEX_VAULT_TELEGRAM_BOT_TOKEN={token}" >> ~/.bashrc'])
        print("Telegram Bot Token saved. Run 'source ~/.bashrc' to apply.")
        print(FOOTER)

Tainted flow: 'chat_id' from input (line 489, user input) → subprocess.run (code execution)

Critical
Category
Data Flow
Confidence
100% confidence
Finding

The chat_id value is collected from interactive input and then passed unsafely into a bash -c command. This enables command injection and persistent compromise via ~/.bashrc modification, which is especially dangerous because it affects the user's login environment beyond the application's scope.

Content

Scanner excerpt · nex-vault.py (reported line 491)May include surrounding context.

python
elif args.action == 'set-telegram-chat':
        chat_id = input("Enter Telegram Chat ID: ")
        import subprocess
        subprocess.run(['bash', '-c', f'echo "export NEX_VAULT_TELEGRAM_CHAT_ID={chat_id}" >> ~/.bashrc'])
        print("Telegram Chat ID saved. Run 'source ~/.bashrc' to apply.")
        print(FOOTER)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill includes functionality that spawns a shell and modifies ~/.bashrc, behavior that exceeds the expected scope of a local document vault and creates persistence side effects on the host. In context, this makes any injection bug more dangerous and exposes users to hidden long-term system modification.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
94% confidence
Finding

The configuration workflow persists sensitive Telegram credentials through shell execution into ~/.bashrc without clearly warning about the security and privacy consequences. This both broadens credential exposure and amplifies the risk of command injection and persistent host modification.

Content

No source excerpt is available for this finding.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

The YARA hit is not evidence of intentional malware, but it does match risky persistence-like behavior because the code appends data into ~/.bashrc. In combination with unsanitized input and bash -c, this becomes a genuine security issue: an attacker can inject commands and achieve persistence through the shell profile.

Content

Scanner excerpt · nex-vault.py (reported line 484)May include surrounding context.

python
ault.db'}")
        print(f"Telegram Bot Token: {'Configured' if TELEGRAM_BOT_TOKEN else 'Not configured'}")
        print(f"Telegram Chat ID: {TELEGRAM_CHAT_ID if TELEGRAM_CHAT_ID else 'Not configured'}")
        print(f"\n{FOOTER}")

    elif args.action == 'set-telegram-token':
        token = input("Enter Telegram Bot Token: ")
        import subprocess
        subprocess.run(['bash', '-c', f'echo "export NEX_VAULT_TELEGRAM_BOT_TOKEN={token}" >> ~/.bashrc'])
        print("Telegram Bot Token saved. Run 'source ~/.bashrc' to apply.")
        print(FOOTER)

    elif args.action == 'set-telegram-chat':
        chat_id = input("Enter Telegram Chat ID: ")
        import subprocess
        subprocess.run(['bash', '-c', f'echo "export NEX_VAULT_TELEGRAM_CHAT_ID={chat_id}" >> ~/.bashrc'])
        print("Telegram Chat ID saved. Run 'source ~/.bashrc' to apply.")
        print(FOOTER)

    elif args.action == 'test-telegram':
        if not TELEGRAM_BOT_TOKEN or not TELEGRAM_CHAT_ID:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README encourages configuring Telegram alerts for a vault that stores sensitive contract and document metadata, but it does not warn users that alert contents or related metadata may be transmitted to Telegram, a third-party service. In this context, even seemingly limited notifications about expirations, counterparties, or contract status can disclose sensitive business information and create an avoidable confidentiality risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares executable behavior that touches environment variables, local files, shell commands, and optional networked Telegram notifications, but it does not declare an explicit tool/permission scope. That creates a trust gap: an agent or platform may invoke powerful operations without a clear least-privilege contract, increasing the chance of unintended file access, shell execution, or data disclosure from sensitive business documents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill advertises optional Telegram alerts but does not prominently warn that document-derived data may leave the local machine and be transmitted to a third-party messaging service. Because the skill manages sensitive contracts and business records, users may incorrectly assume all data remains local, leading to inadvertent disclosure of expiration dates, parties, or other confidential metadata.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger list includes broad terms like "contract," "insurance," "termination," "renewal," and "deadlines," which are common in ordinary conversation. Over-broad activation can cause the skill to run in contexts the user did not intend, potentially exposing local document metadata, reading files, or prompting configuration of notifications during unrelated conversations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code sends alert contents, including document names and deadline details, to Telegram, an external third-party service, without any evidence in this file of explicit user consent, warning, redaction, or data-minimization. In a contract/document vault context, those messages can contain sensitive business metadata, so external transmission materially increases confidentiality risk even though the transport uses HTTPS.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

The function transmits alert messages to api.telegram.org, which is an external network destination. Because alert text is built from document names and deadlines, this can leak sensitive contract and business information outside the local system; in a secure document vault skill, that context makes the exposure more concerning than in a generic messaging app integration.

Content

Scanner excerpt · lib/alerter.py (reported line 128)May include surrounding context.

python
if not TELEGRAM_BOT_TOKEN or not TELEGRAM_CHAT_ID:
        return False

    url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
    data = urllib.parse.urlencode({
        'chat_id': TELEGRAM_CHAT_ID,
        'text': message,

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/doc_parser.py (reported line 39)May include surrounding context.

python
def _extract_pdf(file_path):
    """Extract text from PDF using pdftotext."""
    try:
        result = subprocess.run(
            ['pdftotext', str(file_path), '-'],
            capture_output=True,
            text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The image extraction path sends the full file to the external tesseract process, and the PDF fallback can route scanned PDFs into the same OCR path. Although there are warnings when the binary is missing, there is no user-facing disclosure here that document contents will be processed by an external subprocess, which matters for potentially sensitive contract files.

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/doc_parser.py (reported line 95)May include surrounding context.

python
def _extract_image(file_path):
    """Extract text from image using OCR (tesseract)."""
    try:
        result = subprocess.run(
            ['tesseract', str(file_path), 'stdout'],
            capture_output=True,
            text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The export_documents function returns all stored document records, which may include party_contact, notes, and raw_text, but provides no confirmation prompt, logging, or visible warning to the user that sensitive vault contents are being exported. Although the docstring states the function exports documents, there is no explicit disclosure about the privacy impact of exporting the full dataset.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The tool presents itself as a secure local vault but can send document-derived alert content to Telegram, which transfers potentially sensitive business metadata to a third-party service. In a document-management context, contract names, parties, dates, and renewal details can themselves be confidential even if full documents are not transmitted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Telegram notifications send alert messages derived from vault contents without an explicit warning about third-party disclosure. For a contract vault, even summary alert text may reveal sensitive counterparties, renewal timing, or internal operational details to external infrastructure.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

This command spawns a shell and interpolates attacker-controlled input directly into a bash command that appends to ~/.bashrc. A crafted Telegram token containing shell metacharacters or command substitutions can trigger arbitrary command execution and also establish persistence by modifying the user's shell startup file.

Content

Scanner excerpt · nex-vault.py (reported line 484)May include surrounding context.

python
elif args.action == 'set-telegram-token':
        token = input("Enter Telegram Bot Token: ")
        import subprocess
        subprocess.run(['bash', '-c', f'echo "export NEX_VAULT_TELEGRAM_BOT_TOKEN={token}" >> ~/.bashrc'])
        print("Telegram Bot Token saved. Run 'source ~/.bashrc' to apply.")
        print(FOOTER)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

This code launches bash and embeds untrusted chat_id input into a shell command that appends to ~/.bashrc. An attacker can inject shell syntax to execute arbitrary commands and persist changes in the user's environment whenever the shell is started.

Content

Scanner excerpt · nex-vault.py (reported line 491)May include surrounding context.

python
elif args.action == 'set-telegram-chat':
        chat_id = input("Enter Telegram Chat ID: ")
        import subprocess
        subprocess.run(['bash', '-c', f'echo "export NEX_VAULT_TELEGRAM_CHAT_ID={chat_id}" >> ~/.bashrc'])
        print("Telegram Chat ID saved. Run 'source ~/.bashrc' to apply.")
        print(FOOTER)

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 63)May include surrounding context.

sh
echo "  WARNING: Missing tools: $MISSING_TOOLS"
    echo "  Install them for full document parsing support:"
    if [ "$PLATFORM" = "linux" ]; then
        echo "    sudo apt-get install poppler-utils tesseract-ocr"
    elif [ "$PLATFORM" = "macos" ]; then
        echo "    brew install poppler tesseract"
    fi

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

sh
echo "  (The tool will continue with limited functionality)"
fi

# Step 3: Create data directory
echo "[3/6] Creating data directory..."
mkdir -p "$DATA_DIR"
if [ "$PLATFORM" != "windows" ]; then

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 · setup.sh (reported line 74)May include surrounding context.

sh
echo "[3/6] Creating data directory..."
mkdir -p "$DATA_DIR"
if [ "$PLATFORM" != "windows" ]; then
    chmod 700 "$DATA_DIR"
fi
echo "  Data directory: $DATA_DIR"

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The code reads Telegram bot credentials from environment variables, which is access to sensitive configuration data. While the variable names and comments indicate notification use, there is no user-facing warning, prompt, or explanatory docstring/comment near the credential access itself describing that credentials will be used.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The comment and patterns explicitly optimize date extraction for Belgian/EU formats and include Dutch/English month names, which bakes in a locale preference. There is no visible user choice or configuration here to select locale behavior, so this may violate a policy against forcing a specific language or locale without opt-in.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The inline comment states the current behavior is a soft delete by marking status as removed, while the user-facing message says the document was removed from tracking, which can imply actual deletion. This documentation/behavior mismatch may mislead operators about whether document records still exist in storage.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.