Back to skill

Security audit

Secrets Vault

Security checks for vulnerabilities and agentic risk

Overview

This is a local secrets vault, but its own code and docs expose credentials in ways users should review carefully before trusting it with sensitive data.

Treat this as review-required before installation. Do not store production or irreplaceable credentials in it unless the session hash is removed, secret values are no longer passed through command-line arguments, plaintext .env/export workflows are tightly controlled, and the missing documented scripts are resolved. No exfiltration or destructive backdoor behavior was found in the inspected 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
scripts/secrets_manager.py:61
Finding

Fast, Unsalted Master-Password Verifier Stored on Disk

Content
View full analysis

Vulnerability Details

File Location: scripts/secrets_manager.py, lines 61-69
Vulnerability Type: Insecure password storage and offline password-cracking oracle
Risk Level: High

Vulnerable Code:

python
def _save_session(self):
    """Save session state."""
    with open(SESSION_FILE, 'w') as f:
        json.dump({
            'created': datetime.now().isoformat(),
            'password_hash': hashlib.sha256(self.master_password.encode()).hexdigest()
        }, f)
    os.chmod(SESSION_FILE, 0o600)

Technical Analysis

The session file contains a raw SHA-256 hash of the vault's master password. SHA-256 is a fast general-purpose hash and is unsuitable for password storage without a unique salt and a computationally expensive password-based key derivation function.

This verifier undermines the vault's stronger PBKDF2 protection. An attacker who obtains ~/.secrets-vault/.session can test password guesses using one inexpensive SHA-256 operation per candidate instead of deriving each candidate through PBKDF2-HMAC-SHA256 with 600,000 iterations.

File mode 0600 limits direct access by other local users but does not protect against processes running under the same account, malware, exposed backups, copied home directories, or permission failures before chmod is applied. In addition, the verifier provides no functional session-unlock capability: _get_session_password() returns the hash, but unlock() explicitly does not use it for decryption.

Attack Path

  1. A user initializes or unlocks the vault, causing _save_session() to create ~/.secrets-vault/.session.
  2. An attacker obtains the file through same-user process access, malware, an exposed backup, or a copied home directory.
  3. The attacker extracts the hexadecimal SHA-256 digest from password_hash.
  4. The attacker performs an offline dictionary or brute-force attack by hashing candidate passwords with SHA-256 and compar ...[truncated 803 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove password_hash from the session file and never persist the master password or a reusable verifier.
  • Because the current hash cannot decrypt the vault, remove the session mechanism entirely and require the password for each separate process invocation.
  • If persistent session unlocking is required, generate a random short-lived session key and protect it with an operating-system credential facility such as macOS Keychain, Windows Credential Manager/DPAPI, or Linux Secret Service.
  • Store only non-sensitive session metadata, such as an expiration timestamp, in the filesystem.
  • Create sensitive files atomically with restrictive permissions at creation time rather than writing them before calling chmod.
  • Delete existing .session files during migration and advise users to rotate weak or reused master passwords because previous copies may remain in backups.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/secrets_manager.py:276
Finding

Secrets Exposed Through Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/secrets_manager.py, lines 276-287
Vulnerability Type: Sensitive information exposure through process arguments
Risk Level: Medium

Vulnerable Code:

python
parser.add_argument('command', choices=['init', 'unlock', 'lock', 'add', 'get', 'list', 'delete', 'update', 'generate'],
                    help='Command to execute')
parser.add_argument('name', nargs='?', help='Secret name')
parser.add_argument('--type', default='api_key', help='Secret type (api_key, database, password)')
parser.add_argument('--key', help='API key value')
parser.add_argument('--username', help='Username')
parser.add_argument('--password', help='Password')
parser.add_argument('--host', help='Database host')
parser.add_argument('--port', help='Database port')
parser.add_argument('--database', help='Database name')
parser.add_argument('--tags', help='Comma-separated tags')
parser.add_argument('--show', action='store_true', help='Show secret values')
parser.add_argument('--length', type=int, default=24, help='Password length for generate')
parser.add_argument('--master-password', help='Master password (for non-interactive use)')

The documentation also encourages this behavior in SKILL.md, including commands such as:

bash
python scripts/secrets_manager.py add api.openai \
  --type api_key \
  --key sk-xxxxxxxx \
  --tags openai,gpt
bash
python scripts/secrets_manager.py add db.production \
  --type database \
  --host db.example.com \
  --port 5432 \
  --database myapp \
  --username admin \
  --password secret123

Technical Analysis

The command-line interface accepts API keys, account passwords, and the vault master password as ordinary process arguments. Depending on the platform and execution environment, command arguments may be exposed through process listings, /proc process metadata, endpoint monitoring, audit systems ...[truncated 1456 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove or deprecate --key, --password, and --master-password for direct secret values.
  • Read secrets interactively with getpass.getpass() so terminal input is not echoed or retained in command history.
  • For automation, accept secrets from a permission-restricted file descriptor, standard input with explicit safeguards, or an operating-system/CI secret store.
  • If password files remain supported, validate that they are regular files owned by the expected user and reject overly permissive modes.
  • Update all documentation examples so credentials are never included directly in shell commands.
  • Warn users that command histories and telemetry containing past invocations should be removed or secured, and recommend rotating any credentials previously passed this way.

T08 · Insecure Dependencies

Note
Location
SKILL.md:27
Finding

Unpinned Third-Party Cryptography Dependency

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 27-31
Vulnerability Type: Unconstrained dependency installation and supply-chain risk
Risk Level: Low

Vulnerable Code:

markdown
### Prerequisites

```bash
pip install cryptography
text

### Technical Analysis

The installation instructions retrieve the latest available version of `cryptography` without a pinned version, lockfile, or package-hash verification. This makes installations non-reproducible and allows the executed dependency code to change after the skill has been reviewed.

No typosquatted package name or currently malicious package was identified: `cryptography` is consistent with the imports in `crypto_utils.py`. The risk is that a future compromised upstream release, package-index compromise, or incompatible release could be installed automatically under these instructions.

### Attack Path

1. A user prepares the skill by running the documented `pip install cryptography` command.
2. `pip` resolves whichever release is current from the configured package index.
3. If that release or index is compromised, attacker-controlled package content is downloaded and installed.
4. The malicious code may execute during installation or when `crypto_utils.py` imports the package.
5. Because the application handles master passwords and decrypted vault contents, a compromised dependency could read or disclose highly sensitive data under the user's privileges.

### Impact Assessment

A compromised dependency would execute with the privileges of the user installing or running the vault. It could access the user's files, environment variables, entered master password, and decrypted secrets available to the process. The finding represents supply-chain exposure rather than evidence that the currently named dependency is malicious.
Remediation
View remediation

Remediation Suggestions

  • Pin cryptography to a reviewed version or tightly controlled compatible range.
  • Provide a dependency lockfile generated from reviewed artifacts.
  • Record and verify package hashes, using a requirements file and pip install --require-hashes.
  • Install only from an explicitly trusted package index over TLS.
  • Use an isolated virtual environment and run installation without elevated privileges.
  • Establish a dependency-update process that reviews release notes, vulnerability advisories, provenance, and hashes before changing the pinned version.
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 69)May include surrounding context.

md
python scripts/secrets_manager.py add api.openai \

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 77)May include surrounding context.

md
python scripts/secrets_manager.py add api.openai \

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 88)May include surrounding context.

md
python scripts/secrets_manager.py add api.openai \

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 186)May include surrounding context.

md
python scripts/secrets_manager.py add api.openai \

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 264)May include surrounding context.

md
python scripts/secrets_manager.py add api.openai \

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · SKILL.md (reported line 102)May include surrounding context.

md
# Export as shell variables
python scripts/inject_env.py --shell

# Generate .env file
python scripts/inject_env.py --file .env

# Run command with injected secrets

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · SKILL.md (reported line 103)May include surrounding context.

md
# Export as shell variables
python scripts/inject_env.py --shell

# Generate .env file
python scripts/inject_env.py --file .env

# Run command with injected secrets

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · SKILL.md (reported line 240)May include surrounding context.

md
# Export as shell variables
python scripts/inject_env.py --shell

# Generate .env file
python scripts/inject_env.py --file .env

# Run command with injected secrets

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill documentation advertises capabilities that read/write files, access environment variables, and invoke shell commands, but the manifest does not declare any explicit tool scope or permissions boundary. In an agent ecosystem, this weakens least-privilege enforcement and makes it easier for a consumer to run the skill with broader access than expected.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The environment injection examples encourage exporting secrets into the shell and writing them to a .env file without clearly warning that this places decrypted secrets into plaintext process state, shell history, terminal logs, or files. Because this skill handles highly sensitive credentials, omission of that warning materially increases the chance of accidental disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The secure sharing section describes creating share links for secrets but does not explicitly warn that this moves sensitive data outside the local vault trust boundary. Even if encrypted and time-limited, sharing introduces risks such as link leakage, recipient compromise, logging, and operational misuse.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
87% confidence
Finding

The share-link workflow creates temporary persisted access paths to secrets outside the primary vault, which increases the window in which unauthorized parties could retrieve them if links or codes leak. Although the feature includes expiry and view limits, the documentation does not frame this persistence as a security-sensitive exception requiring strict operational controls.

Content

Scanner excerpt · SKILL.md (reported line 124)May include surrounding context.

3. Secure Sharing

Create time-limited, encrypted share links:

bash
# Create share from vault secret

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The cross-device sync instructions recommend storing the encrypted vault in third-party sync services without clearly warning about the larger attack surface from cloud compromise, account takeover, endpoint sync leakage, and retained historical copies. For a secrets-management skill, failing to state these risks can lead users to overtrust the protection offered by encryption alone.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The vault accepts the master password from an environment variable or an arbitrary file path, which weakens the security model for a secrets manager. Environment variables can leak through process inspection, logs, shell history wrappers, crash reports, or CI/CD environments, and file-based password ingestion can expose the master secret through weak file permissions or attacker-controlled path injection in surrounding automation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The delete_secret function permanently removes stored data and rewrites the vault, but it only prints a success message after the fact. There is no confirmation prompt, warning comment, or other disclosure that this action is destructive and may be irreversible.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Allowing secrets and the master password to be passed on the command line exposes them to local disclosure through process listings, shell history, audit logs, job runners, and monitoring tools. In the context of a secrets-management tool, this is especially risky because it undermines the core purpose of safely handling highly sensitive credentials.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The --show option allows stored secrets to be printed directly to stdout without any confirmation or warning, which can leak secrets into terminal scrollback, logs, screen recordings, or redirected output. For a vault utility, accidental disclosure during retrieval is a meaningful security weakness because the tool is expected to minimize exposure of plaintext secrets.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The docstring says this method gets a password from the session file if still valid, and the save method/docstring says it saves session state. In reality, the session file stores only a SHA-256 hash of the master password, and the unlock path acknowledges at L137-L138 that this value cannot be used for decryption, so the documented session behavior contradicts actual behavior.

Content

No source excerpt is available for this finding.