Back to skill

Security audit

Miniflux

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says for Miniflux, but it stores and reuses an API key in ways that need careful review before installation.

Install only if you are comfortable giving the skill a Miniflux API key that can read and modify your feed state. Prefer MINIFLUX_URL and MINIFLUX_API_KEY environment variables over --api-key, use an HTTPS Miniflux URL you control, avoid running it in shared environments, and check or restrict permissions on ~/.local/share/miniflux/config.json if you ever use CLI flags.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/miniflux-cli.py:27
Finding
Miniflux API key is stored in a plaintext configuration file without enforced restrictive permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/miniflux-cli.py`, lines 27-32 **Vulnerability Type**: Plaintext credential storage with insecure file permissions **Risk Level**: High ### Vulnerable Code ```python def save_config(base_url: str, api_key: str): CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True) with open(CONFIG_PATH, "w") as f: json.dump({"base_url": base_url, "api_key": api_key}, f, indent=2) ``` ### Technical Analysis The `save_config` function writes the Miniflux API key directly to `~/.local/share/miniflux/config.json`. The code does not explicitly set restrictive permissions on either the configuration directory or file. The resulting permissions depend on the process umask. Under a common `022` umask, a newly created file can be readable by other local users. The code also does not correct insecure permissions on an existing configuration file or protect against the destination being a symbolic link. Although credential storage supports the declared Miniflux functionality, storage in a broadly readable plaintext file exceeds the minimum privileges necessary. Only the account running the Skill should be able to access the credential. ### Attack Path 1. A user invokes the CLI with a Miniflux API key. 2. The CLI calls `save_config` and writes the API key to `config.json`. 3. The file is created with permissions derived from the current umask or retains insecure existing permissions. 4. Another local account, process, or compromised application reads the file. 5. The attacker uses the recovered API key to authenticate to the configured Miniflux server. A symbolic-link attack may also be possible when an attacker can manipulate the configuration path before the file is opened, potentially redirecting the credential into another file accessible to the attacker. ### Impact Assessment Successful exploitation discloses the Miniflux API key and server URL. The privileges available to an attacker depend on ...[truncated 448 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create the configuration directory with mode `0700`. - Create the configuration file atomically with mode `0600`. - Explicitly verify and repair permissions when an existing file is loaded or overwritten. - Reject symbolic links and non-regular files before reading or writing the credential. - Write to a securely created temporary file and atomically replace the destination. - Prefer an operating-system credential store or secret-management service rather than plaintext JSON. - Store non-sensitive settings such as the server URL separately from the API key. - Document how users can rotate a key if the configuration file was previously created with unsafe permissions. For example, open the file using flags equivalent to `O_CREAT | O_EXCL | O_WRONLY | O_NOFOLLOW` with mode `0600`, then atomically replace the intended regular file. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/miniflux-cli.py:35
Finding
Unvalidated server URL can transmit the API key over plaintext HTTP or to an unintended host<![CDATA[ ## Vulnerability Details **File Location**: `scripts/miniflux-cli.py`, lines 35-59 **Vulnerability Type**: Sensitive credential transmission without transport or destination validation **Risk Level**: High ### Vulnerable Code ```python def create_client(args) -> miniflux.Client: config = load_config() base_url = args.url or os.environ.get("MINIFLUX_URL") or config.get("base_url") api_key = args.api_key or os.environ.get("MINIFLUX_API_KEY") or config.get("api_key") if not base_url: print("Error: Miniflux URL not configured.", file=sys.stderr) print("Set MINIFLUX_URL environment variable or use --url", file=sys.stderr) print(f"Config file: {CONFIG_PATH}", file=sys.stderr) sys.exit(1) if not api_key: print("Error: Miniflux API key not configured.", file=sys.stderr) print("Set MINIFLUX_API_KEY environment variable or use --api-key", file=sys.stderr) print(f"Config file: {CONFIG_PATH}", file=sys.stderr) sys.exit(1) if args.url or args.api_key: save_config(base_url, api_key) return miniflux.Client(base_url, api_key=api_key) ``` ### Technical Analysis The server URL is accepted from a command-line argument, environment variable, or configuration file and passed directly to `miniflux.Client`. There is no validation of: - The URL scheme. - Whether TLS is required. - The destination host. - Embedded URL credentials. - Whether the configured origin unexpectedly changed. Network communication and API-key authentication are necessary for the declared Miniflux functionality. However, allowing an unrestricted destination or plaintext HTTP transport is not necessary. If an `http://` URL is used, the API credential and returned feed data can be exposed to network interception. If an attacker influences `--url`, `MINIFLUX_URL`, or the configuration file, the credential can be sent directly to an attacker-controlled server. ### Attack Path #### Plaintext inte ...[truncated 1268 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Parse the URL before constructing the client. - Require `https://` for non-local destinations. - If local plaintext Miniflux deployments must be supported, require a conspicuous opt-in flag and restrict it to loopback addresses. - Reject unsupported schemes, malformed hosts, URL fragments, and embedded credentials. - Warn or require confirmation when changing the saved server origin while reusing an existing API key. - Do not automatically pair a previously stored API key with a newly supplied server URL. - Preserve normal TLS certificate validation and do not add insecure certificate-bypass options. - Consider an optional administrator-defined hostname allowlist for managed Agent deployments. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/miniflux-cli.py:51
Finding
API key accepted through command-line arguments and silently persisted<![CDATA[ ## Vulnerability Details **File Location**: `scripts/miniflux-cli.py`, lines 51-52 and 332-333 **Vulnerability Type**: Credential exposure through process arguments and unexpected persistence **Risk Level**: Medium ### Vulnerable Code ```python if args.url or args.api_key: save_config(base_url, api_key) ``` ```python parser.add_argument("--url", help="Miniflux server URL") parser.add_argument("--api-key", help="Miniflux API key") ``` The documented setup procedure also encourages this invocation pattern: ```bash uv run scripts/miniflux-cli.py --url="https://miniflux.example.org" --api-key="xxx" list ``` ### Technical Analysis Secrets supplied as command-line arguments can be exposed through several operating-system and operational channels: - Shell history. - Process inspection utilities. - Process accounting. - CI/CD execution records. - Agent tool-call transcripts. - Debugging and monitoring telemetry. - Wrapper-script logs. In addition, supplying either `--url` or `--api-key` triggers `save_config(base_url, api_key)`. This means that a one-time CLI option silently causes the resolved API key to be stored persistently. Supplying only `--url` can also cause a key obtained from the environment or an existing configuration to be written again. Accepting a server URL as a CLI argument is reasonable, but accepting a long-lived API key in process arguments and persisting it automatically are not minimum-privilege requirements for Miniflux access. ### Attack Path 1. A user follows the documented example and places the API key in `--api-key`. 2. The shell records the command, or the argument appears in process or Agent execution telemetry. 3. An attacker with access to that history, process metadata, or log store retrieves the key. 4. The CLI also writes the key to the configuration file without asking for explicit consent. 5. The attacker reuses the key to access the Miniflux API. In shared automation environments, the log reader may be a ...[truncated 489 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove or deprecate `--api-key`. - Accept the key through a protected environment variable, a file descriptor, standard input, an interactive hidden prompt, or an operating-system credential store. - Add a dedicated `configure` command for intentional persistent configuration. - Require explicit user confirmation before storing a secret. - Do not persist credentials merely because `--url` was supplied. - Ensure help text and documentation never recommend placing secrets directly in shell commands. - If temporary backward compatibility is required, emit a security warning and provide a `--no-save` default. - Advise users to remove affected shell-history entries, review execution logs, and rotate keys that may have been exposed. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/miniflux-cli.py:3
Finding
Runtime dependency is automatically downloaded using an open-ended version constraint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/miniflux-cli.py`, lines 3-6 **Vulnerability Type**: Unpinned automatically resolved third-party dependency **Risk Level**: Medium ### Vulnerable Code ```python # /// script # requires-python = ">=3.12" # dependencies = ["miniflux>=1.1.4"] # /// ``` The project documentation states that execution automatically installs dependencies through `uv`, but the project contains no reviewed lockfile or integrity hashes. ### Technical Analysis The constraint `miniflux>=1.1.4` permits any future compatible release selected by the package resolver. Consequently, the code that executes can change after this Skill has been reviewed, without any change to the audited repository. The imported dependency runs in the same Python process as the Skill: ```python import miniflux ``` It therefore has access to the process environment, filesystem privileges, command-line arguments, and Miniflux API key available to the CLI. An upstream package compromise or malicious future release could execute code when imported. This is a supply-chain weakness rather than evidence that the current `miniflux` package is malicious. No typosquatted package or known malicious version was established during the static audit. ### Attack Path 1. A future version satisfying `miniflux>=1.1.4` is compromised or published with malicious code. 2. On a fresh environment or dependency update, `uv run` resolves and downloads that version. 3. The script imports `miniflux`, executing package initialization code. 4. The malicious dependency accesses the API key, environment, filesystem, or network using the Skill process's privileges. 5. Credentials or local data may be transmitted externally, or Miniflux operations may be altered. The same risk applies if the package index or dependency-resolution path is compromised. ### Impact Assessment A compromised dependency executes with all privileges of the user running the Skill. Potential impac ...[truncated 507 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin the dependency to an exact reviewed version rather than using `>=`. - Generate and commit a lockfile containing resolved transitive dependencies. - Use cryptographic hashes where supported to verify downloaded artifacts. - Configure an explicit trusted package index instead of relying on ambient resolver configuration. - Perform dependency updates through a reviewed process with security scanning and release-diff inspection. - Consider vendoring a minimal reviewed client or implementing the small required API surface with a standard HTTP library if this reduces supply-chain exposure. - Run the Skill in a constrained environment with limited filesystem and network access so that a compromised dependency cannot access unrelated user data. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README explicitly instructs users to pass a URL and API key via CLI flags and states that these values are saved to ~/.local/share/miniflux/config.json, but it does not warn that this results in local persistent storage of sensitive credentials, likely in plaintext. API keys for feed-management access can be abused by other local users, malware, backups, or logging/history mechanisms, leading to unauthorized access to the user's Miniflux instance.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill advertises executable behavior that can read environment variables and persist configuration, but it does not declare any explicit tool scope or permissions boundary. In an agent setting, this weakens reviewability and can lead to unintended access to secrets or filesystem writes because consumers cannot tell from the manifest what capabilities the skill requires.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill instructs users to pass API keys via CLI flags and notes that they may be saved to a local config file, but it does not clearly warn about credential exposure risks. CLI arguments may be visible in shell history or process listings, and persisted credentials on disk may be accessible to other local processes or users if not protected.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The CLI stores the Miniflux API key on disk in a JSON config file, expanding the exposure window of a bearer credential beyond the current session. In agent environments, local state may be readable by other tools, users, backups, or logs, so unnecessary persistence materially increases the risk of credential theft.

Tainted flow: 'CONFIG_PATH' from os.environ.get (line 21, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
def save_config(base_url: str, api_key: str):
    CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
    with open(CONFIG_PATH, "w") as f:
        json.dump({"base_url": base_url, "api_key": api_key}, f, indent=2)
Confidence
85% confidence
Finding
The config file path is derived from XDG_DATA_HOME, which is taken directly from the environment, and the tool writes credentials to that path without validating that it is safe or intended. In an agent or multi-tenant context, a manipulated environment could redirect the API key to an attacker-controlled location or an unexpected file, causing credential disclosure or overwriting sensitive files accessible to the process.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The tool silently persists a sensitive API key to disk when --url or --api-key is supplied, without warning the user that a long-lived secret will be written locally. This is dangerous because users may reasonably expect CLI credentials to be session-only, and silent persistence increases the chance of accidental disclosure through shared filesystems, backups, or later compromise.

Description-Behavior Mismatch

Medium
Confidence
80% confidence
Finding
The manifest focuses on listing/reading articles, marking them read, and managing feeds/categories, which suggests interaction with existing Miniflux content state. The refresh command initiates server-side feed polling/update activity, a broader operational action not described in the manifest text.

Missing User Warnings

Low
Confidence
86% confidence
Finding
The documentation includes commands that change Miniflux state, such as marking articles read or unread and refreshing feeds, without clearly warning that these operations modify remote data. In an agent workflow this can cause unintended actions or data integrity issues if a user expects read-only browsing behavior from a content-access skill.

Missing User Warnings

Low
Confidence
81% confidence
Finding
The script performs remote API operations against the configured Miniflux server, potentially transmitting article metadata, feed state changes, and credentials. While this is part of the CLI's purpose, the code lacks any direct user-facing warning at execution time about contacting the remote server or using supplied credentials.

Static analysis

No suspicious patterns detected.