Back to skill

Security audit

Karakeep

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its Karakeep bookmark purpose, but its API key handling and network safeguards need user review before installation.

Review this before installing if your Karakeep bookmarks or token are sensitive. Prefer using an HTTPS instance URL, avoid relying on the hardcoded default URL, restrict permissions on `~/.config/karakeep/config.json`, and consider pinning or preinstalling dependencies in a controlled environment.

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

Warning
Location
scripts/karakeep-cli.py:27
Finding

API Key Stored in a Plaintext Configuration File Without Explicit Permission Hardening

Content
View full analysis

Vulnerability Details

File Location: scripts/karakeep-cli.py, lines 27-31
Vulnerability Type: Plaintext sensitive credential storage
Risk Level: Medium

Vulnerable Code

python
def save_config(url, api_key):
    config_path = os.path.expanduser("~/.config/karakeep/config.json")
    os.makedirs(os.path.dirname(config_path), exist_ok=True)
    with open(config_path, 'w') as f:
        json.dump({"url": url, "api_key": api_key}, f)

Technical Analysis

The login command persists the Karakeep API key directly in a plaintext JSON file. Neither the configuration directory nor the file is created with an explicit owner-only permission mode. Consequently, their effective permissions depend on the invoking process's umask and any preexisting directory or file permissions.

The code also writes directly to the destination file rather than creating a restricted temporary file and atomically replacing the configuration. Although no race-condition exploit is confirmed from the available code alone, direct writes make robust permission and integrity handling more difficult.

Attack Path

  1. A user invokes the documented login command with a valid Karakeep API key.
  2. save_config() writes that key to ~/.config/karakeep/config.json as plaintext.
  3. On a system with a permissive umask, inherited ACL, or preexisting broadly readable configuration file, another local account or process reads the file.
  4. The attacker extracts the api_key and associated instance URL.
  5. The attacker uses the stolen bearer credential against the Karakeep API.

Impact Assessment

Exploitation requires local read access to the configuration file, such as access through another local account, a compromised process, an overly broad ACL, or a backup process that exposes the file. It does not directly grant operating-system privilege escalation.

A stolen API key may allow the attacker to exercise all Karak ...[truncated 340 chars]

Remediation
View remediation

Remediation Suggestions

  • Create ~/.config/karakeep with owner-only permissions, such as mode 0700.
  • Create the configuration file with mode 0600 using an API that applies the restrictive mode at file creation time.
  • Verify and repair permissions on an existing configuration file before writing credentials.
  • Write through a securely created temporary file in the same directory, flush it, apply mode 0600, and atomically replace the destination.
  • Prefer an operating-system credential manager or keyring rather than storing the API key in JSON.
  • Document that environment variables can also be exposed to other processes or diagnostic tooling and should not be treated as a complete secret-management solution.
  • Consider supporting short-lived, narrowly scoped API tokens to reduce the impact of credential disclosure.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/karakeep-cli.py:44
Finding

Bearer Credentials Can Be Transmitted Over Unencrypted HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/karakeep-cli.py, lines 44-47
Related Input Location: scripts/karakeep-cli.py, lines 103-104
Vulnerability Type: Missing HTTPS enforcement for authenticated requests
Risk Level: High

Vulnerable Code

python
full_url = f"{url.rstrip('/')}{endpoint}"

try:
    response = requests.request(method, full_url, headers=headers, json=data, params=params)

The server URL is accepted without scheme validation:

python
login_parser = subparsers.add_parser("login")
login_parser.add_argument("--url", help="Karakeep instance URL")
login_parser.add_argument("api_key")

The credential attached to the request is constructed immediately before the vulnerable request:

python
headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json"
}

Technical Analysis

The CLI accepts an arbitrary instance URL and concatenates it with API endpoints without requiring an https:// scheme. Every API request includes the Karakeep API key as an HTTP bearer token.

If a user configures an http:// URL, requests sends the authorization header and bookmark data without transport encryption. An attacker with the ability to observe or modify network traffic can recover the bearer token because bearer credentials do not provide protection against interception or replay.

The issue applies to listing, searching, and adding bookmarks because all operations use the shared make_request() function.

Attack Path

  1. A user runs login --url http://example-karakeep.local API_KEY, or an existing configuration supplies an HTTP URL.
  2. The CLI stores or loads the HTTP URL and API key.
  3. The user invokes list, list --search, or add.
  4. make_request() constructs an HTTP URL and sends Authorization: Bearer API_KEY.
  5. An attacker on the same wireless network, local network segment, proxy path, or anot ...[truncated 883 chars]
Remediation
View remediation

Remediation Suggestions

  • Parse the configured URL with a standard URL parser and require the scheme to be https.
  • Reject URLs with missing schemes, embedded credentials, malformed hosts, or unexpected URL components.
  • If plaintext HTTP is necessary for local development, require an explicit option such as --allow-insecure-http and restrict it to loopback addresses by default.
  • Display a prominent warning before any insecure request and never silently downgrade from HTTPS.
  • Retain TLS certificate verification; do not introduce a general-purpose option that disables verification.
  • Consider restricting redirects or validating redirect destinations before forwarding the authorization header.
  • Remove ambiguous URL defaults and require the user to explicitly configure the intended trusted Karakeep instance.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:14
Finding

Unpinned Third-Party Dependency Is Resolved During Normal Skill Execution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 14-33
Vulnerability Type: Unpinned runtime dependency and supply-chain exposure
Risk Level: Medium

Vulnerable Instructions

bash
uv run --with requests skills/karakeep/scripts/karakeep-cli.py login --url <instance_url> <api_key>
bash
uv run --with requests skills/karakeep/scripts/karakeep-cli.py add <url>
bash
uv run --with requests skills/karakeep/scripts/karakeep-cli.py list --limit 10
bash
uv run --with requests skills/karakeep/scripts/karakeep-cli.py list --search "title:react is:fav"

Technical Analysis

The documented commands use uv run --with requests without a pinned version or a reviewed lockfile. This causes dependency resolution to occur as part of normal command execution and allows the selected package version to change after the Skill has been reviewed.

The risk depends on the package indexes and resolver configuration used in the execution environment. If an index is compromised, replaced, or configured to prefer an untrusted source, a malicious or unauthorized package artifact can be installed and imported by the Python process. An incompatible future package release can also unexpectedly change runtime behavior even in the absence of a malicious package.

This is a supply-chain weakness rather than evidence that the legitimate requests package is malicious.

Attack Path

  1. The user or agent follows a documented command containing uv run --with requests.
  2. uv resolves the unpinned dependency using the environment's configured package indexes and cache.
  3. An attacker compromises a configured index, controls an added index or mirror, poisons package resolution, or otherwise causes an unauthorized artifact to be selected.
  4. The dependency is installed into the runtime environment.
  5. karakeep-cli.py executes import requests.
  6. Code in the selected ...[truncated 888 chars]
Remediation
View remediation

Remediation Suggestions

  • Pin requests and all transitive dependencies to reviewed versions.
  • Maintain and distribute a committed lockfile generated from a trusted package source.
  • Use hash verification so package artifacts must match expected cryptographic hashes.
  • Configure uv to use an explicitly trusted package index and avoid unreviewed supplemental indexes.
  • Resolve and install dependencies during a controlled build or deployment phase rather than during each normal Skill invocation.
  • Periodically update pinned versions through a documented review and vulnerability-management process.
  • Consider executing the Skill in a constrained environment with limited filesystem access, network access, and credential exposure to reduce the impact of a dependency compromise.
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (1)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes a Python script that uses network access and reads/writes configuration and secrets, but the manifest does not declare any tool scope such as permissions or allowed-tools. This creates a trust and containment gap: an agent or reviewer cannot easily tell that running the skill may access environment variables, write config files, and make outbound requests to a Karakeep instance.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.