Back to skill

Security audit

Keepass-CLI

Security checks for vulnerabilities and agentic risk

Overview

This KeePass skill is not clearly malicious, but it gives an agent broad password-vault access and uses secret-handling patterns that can leak credentials.

Review before installing. Use only with a dedicated or low-risk KeePass database unless you are comfortable giving the agent broad vault read/write authority. Avoid storing the master password in a plaintext .env file where possible, avoid passing real passwords or OTP seeds on command lines, pin dependencies for serious use, and treat --show-secrets, --include-data, and --permanent as high-risk operations.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
keepass_cli.py:604
Finding

Entry passwords and OTP secrets are exposed through command-line arguments

Content
View full analysis

Vulnerability Details

File Location: keepass_cli.py:604-605 and keepass_cli.py:618-623
Vulnerability Type: Sensitive information exposure through process arguments
Risk Level: High

The CLI requires entry passwords and optionally accepts OTP provisioning URIs as ordinary command-line arguments.

python
add.add_argument("--otp", help="otpauth URI")
add.add_argument("--password", required=True, help="Password to store on the entry")
python
edit.add_argument("--new-title")
edit.add_argument("--username")
edit.add_argument("--password", help="New password to set on the entry")
edit.add_argument("--url")
edit.add_argument("--notes")
edit.add_argument("--otp")

The associated documentation confirms that this is the intended secret-input mechanism:

markdown
`add-entry` requires `--password`; `edit-entry --password` sets a new one.
Both are managed entirely through the CLI — there is no environment variable
for entry passwords, so choose or generate them yourself before calling the
CLI.

Technical Analysis

Command-line arguments are not an appropriate transport for high-value secrets. Depending on the execution environment, arguments may be exposed through:

  • Shell history.
  • Process inspection facilities.
  • Agent or orchestration execution logs.
  • Endpoint monitoring and audit systems.
  • Error reports or debugging telemetry that record complete invocations.
  • Wrapper scripts and job-control systems that persist command lines.

OTP provisioning URIs commonly contain reusable TOTP seed material. Disclosure of such a URI may therefore compromise a second authentication factor, not merely transient authentication output.

The database master password is handled more safely through an environment variable, but equivalent protection is not provided for entry passwords or OTP seeds. Documentation warns users not to log these invocations, but a warning does not pre ...[truncated 1395 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace secret-bearing command-line flags with protected standard-input handling.
  • For human use, read secrets with a no-echo prompt such as getpass.getpass().
  • For automated use, support a dedicated inherited file descriptor or standard input with an explicit JSON request contract.
  • If file-based input is necessary, require an owner-readable file, reject permissive file modes where supported, avoid following unsafe symbolic links, and document secure deletion limitations.
  • Keep secret values out of exception messages, debug output, command summaries, and telemetry.
  • Deprecate --password and --otp gradually, and emit a warning until they are removed.
  • Document secure invocation examples that do not interpolate secrets into shell command lines.
  • Add automated tests confirming that secrets do not appear in normal stdout, stderr, exception output, or process arguments under the recommended workflow.

T08 · Insecure Dependencies

Warning
Location
skill.md:29
Finding

Installation instructions use unpinned third-party dependencies

Content
View full analysis

Vulnerability Details

File Location: skill.md:29-31
Vulnerability Type: Uncontrolled third-party dependency resolution
Risk Level: Medium

The documented setup procedure installs dependencies without version or integrity constraints:

bash
# 1. install dependencies
python -m pip install python-dotenv pykeepass
# 2. create a .env file using the example provided above

Technical Analysis

The installation command asks pip to resolve the latest available releases of python-dotenv, pykeepass, and their transitive dependencies at installation time. No lock file, exact version constraints, package hashes, or reviewed artifact source is provided.

This means the code executed in a deployed environment can differ from the code considered during this audit. A compromised future release, compromised maintainer account, malicious transitive dependency, or incompatible update could introduce arbitrary behavior into installation or runtime.

No evidence was found that the currently named packages are typosquatted or intentionally malicious. The risk arises from uncontrolled future dependency resolution rather than a confirmed malicious dependency in the project.

Attack Path

  1. A user follows the documented installation command.
  2. Pip queries its configured package index and resolves package versions available at that time.
  3. A compromised or malicious package release, or a malicious transitive dependency, is selected because no reviewed version or hash is required.
  4. Package installation logic or imported runtime code executes in the Skill's Python environment.
  5. The malicious dependency inherits the process's access to the local filesystem, environment variables, KeePass database, keyfile, and decrypted secrets handled by the CLI.

Impact Assessment

Dependency code executes with the privileges of the user installing or running the Skill. In this context, that can include access to `KEEP ...[truncated 477 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin exact reviewed versions for direct and transitive dependencies.
  • Provide a lock file generated through a reproducible dependency-management process.
  • Record cryptographic hashes for every permitted distribution.
  • Install with hash verification, such as pip install --require-hashes -r requirements.txt.
  • Prefer a controlled package index or artifact repository for production deployment.
  • Add automated dependency vulnerability and provenance checks.
  • Review dependency updates before regenerating the lock file instead of resolving new releases automatically during deployment.
  • Run installation and the CLI under a dedicated, minimally privileged account or isolated virtual environment.
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

The skill instructs users to place the KeePass master password in a local .env file and automatically load it on startup. Although common in developer tooling, storing a high-value secret in a plaintext file increases exposure through accidental commits, local file disclosure, backups, or broader-than-intended filesystem access; in this context, compromise of that password unlocks the entire secrets database.

Content

Scanner excerpt · skill.md (reported line 33)May include surrounding context.

bash
# 1. install dependencies
python -m pip install python-dotenv pykeepass
# 2. create a .env file using the example provided above

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The --include-data flag causes list-attachments to return attachment contents as base64, which may expose sensitive file data. While the code documents the flag in argparse help, there is no explicit user-facing warning in output, confirmation step, or broader disclosure beyond the inline option text.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

Exposing transformed_key provides low-level derived key material tied to database decryption, which is more sensitive than normal CRUD functionality and can facilitate offline abuse or unintended credential reuse by downstream components. In an agent skill context, returning or caching this material broadens the secret boundary from database contents to cryptographic internals.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

Exposing database salt/KDF parameters is not equivalent to exposing plaintext credentials, but it reveals cryptographic metadata unnecessary for typical entry/group/attachment management. In combination with other leaked material or misuse by an autonomous agent, it can aid offline analysis and expands capability beyond the declared purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation explicitly shows writing decrypted KeePass database content to disk as plaintext XML without strong warnings about secret exposure, insecure storage, backups, or log leakage. Given this skill's domain is password vault management, examples that normalize plaintext export materially increase the risk of credential disclosure by users or autonomous agents.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documented xml()/dump_xml() functionality can export the full decrypted KeePass payload as plaintext XML, which includes secrets such as usernames, passwords, OTP URIs, notes, and attachment metadata. In a non-interactive JSON CLI marketed for autonomous database management, this materially increases the chance of accidental bulk secret exfiltration to disk or logs beyond ordinary entry management.

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 · skill.md (reported line 175)May include surrounding context.

md
- **Never pass your database password as a CLI argument.** Read it from `KEEPASS_DATABASE_PASSWORD` only, so you don't leak it into shell history, process listings, or shared logs.
- **Entry passwords go through the CLI by design.** `--password` on `add-entry`/`edit-entry` is how you set them; avoid logging command invocations that include one.
- **Don't commit** your `.env` file to version control. Add it to `.gitignore`.
- **Lock down file permissions** on your `.env` file and `.kdbx` database to owner read/write only (`chmod 600`).
- **Ask for secrets only when you need them.** Pass `--show-secrets` only when you actually need the password/OTP value, and avoid echoing that output anywhere it could be logged.
- **Treat `--permanent` as irreversible.** `delete-entry` and `delete-group` land in the Recycle Bin by default — only pass `--permanent` when you deliberately want to skip that safety net.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

This file accesses KEEPASS_DATABASE_PASSWORD as the database credential source, which is a sensitive environment variable. Although the docstring explains where the password comes from, it does not warn about the sensitivity of storing or supplying credentials this way or the operational risks for agent-driven use.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring says 'Create a new group and all parent groups, if necessary', which implies path creation or recursive parent creation. The implementation only constructs a single Group and appends it to destination_group, with no logic to create missing parent groups.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
99% confidence
Finding

The return documentation states 'Group: newly added group', which contradicts the actual function purpose and return value. The code creates an Entry, appends it, and returns entry.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation for Group.append says 'Add copy of an entry to this group', implying duplication. The code directly appends e._element or entries._element, which re-parents the existing XML node instead of creating a copy, so the behavior is materially different from what the documentation claims.

Content

No source excerpt is available for this finding.