CVE-2026-76876 Overview
Craftplan versions before 0.5.1 contain a broken access control vulnerability [CWE-862] in the Settings API resource. The read policy on the Settings resource uses an unconditional always-allow authorization check, which bypasses all identity verification. Unauthenticated attackers can send a GET request to the settings API endpoint with a valid record ID and retrieve decrypted SMTP passwords, email API keys, and email API secrets. The flaw exposes credentials that adversaries can reuse to send phishing emails, pivot into connected mail infrastructure, or abuse third-party APIs billed to the victim.
Critical Impact
Unauthenticated remote attackers can read decrypted SMTP passwords and email API secrets by issuing a single GET request to the Settings API.
Affected Products
- Craftplan versions prior to 0.5.1
- Craftplan Settings API endpoint (/settings)
- Craftplan deployments exposing the HTTP API to untrusted networks
Discovery Timeline
- 2026-08-21 - CVE-2026-76876 published to NVD
- 2026-08-25 - Last updated in NVD database
Technical Details for CVE-2026-76876
Vulnerability Analysis
Craftplan exposes a REST resource for application Settings that stores integration credentials, including SMTP passwords and email API secrets. The framework serves these values through a GET /settings/:id route that is governed by an Ash resource authorization policy. The read policy is defined with an always-allow check, so the framework returns the record without verifying the caller's identity or scope. The response contains credential fields in decrypted form, which means an attacker who guesses or enumerates a valid record identifier obtains usable secrets rather than ciphertext.
The consequences extend beyond simple information disclosure. Recovered SMTP credentials permit outbound mail relaying from a trusted sender domain. Recovered email API keys and secrets allow programmatic sending, template access, and address book retrieval through the connected provider.
Root Cause
The root cause is a missing authorization check on a sensitive resource action [CWE-862]. The Settings resource action :get was exposed on the public API router without policy gating tied to the requesting actor. A secondary contributor is the plug api_key_auth behavior, which allowed requests to progress without an established current_user context when no API key was presented.
Attack Vector
Exploitation requires network access to the Craftplan HTTP API and knowledge of a Settings record identifier. No credentials, tokens, or user interaction are required. An attacker issues an unauthenticated GET request to the settings endpoint and parses credential fields from the JSON response.
// Vendor security patch - route hardening
// Source: https://github.com/puemos/craftplan/commit/317acd584b68887f592dc3b97f47703dd63b1bf
routes do
base("/settings")
- get(:get)
+ get(:api_get)
patch(:update)
end
// Vendor security patch - API key auth plug behavior
// Source: https://github.com/puemos/craftplan/commit/317acd584b68887f592dc3b97f47703dd63b1bf
@moduledoc """
Plug that authenticates requests using API keys (`cpk_` prefixed Bearer tokens).
-Skips if a current_user is already assigned (e.g. from JWT auth).
+Uses an already assigned current_user as the Ash actor (e.g. from JWT auth).
On success, assigns `current_user` and `current_api_key` and stores
scopes in process dictionary for policy checks.
"""
The fix replaces the unrestricted :get action with a scoped :api_get action and reworks the API key authentication plug so an existing current_user is used as the Ash actor for policy checks rather than causing authentication to be skipped.
Detection Methods for CVE-2026-76876
Indicators of Compromise
- Unauthenticated HTTP GET requests to /settings/:id returning 200 status codes in Craftplan access logs.
- Outbound SMTP authentication events from unfamiliar IP addresses using credentials stored in Craftplan Settings.
- Email provider API calls originating from IPs that have never previously used the configured API key.
- Spikes in GET /settings traffic from a small set of source IPs enumerating numeric or UUID record identifiers.
Detection Strategies
- Alert on any request to /settings/:id that lacks an Authorization header or a valid session cookie.
- Deploy a Web Application Firewall (WAF) rule that blocks GET requests to the settings resource from outside trusted management networks.
- Correlate SMTP relay logs with Craftplan Settings modification timestamps to detect credential reuse from a compromised leak.
- Baseline expected callers of the settings endpoint and flag deviations in user-agent, IP ASN, or request rate.
Monitoring Recommendations
- Ingest Craftplan application logs and reverse-proxy access logs into a centralized SIEM for retrospective hunting.
- Rotate and monitor all SMTP passwords and email API secrets configured before upgrading to 0.5.1.
- Enable email provider audit logs and alert on new API key usage patterns or template sends outside business hours.
How to Mitigate CVE-2026-76876
Immediate Actions Required
- Upgrade Craftplan to version 0.5.1 or later, which introduces the scoped :api_get action and fixes the authorization plug.
- Rotate every credential previously stored in Craftplan Settings, including SMTP passwords, email API keys, and email API secrets.
- Restrict network exposure of the Craftplan API to trusted administrative networks until patching is complete.
- Review reverse-proxy and application logs for prior unauthenticated GET requests to /settings and treat any matches as confirmed disclosure.
Patch Information
The vendor released Craftplan 0.5.1 with commit 317acd584b68887f592dc3b97f47703dd63b1bf, which rewires the Settings route to a policy-gated :api_get action and requires the API key auth plug to establish an actor before Ash policy evaluation. See the GitHub commit, the Craftplan v0.5.1 release notes, and the VulnCheck advisory.
Workarounds
- Place the Craftplan API behind an authenticating reverse proxy that rejects unauthenticated requests to /settings*.
- Add an IP allowlist at the load balancer or firewall limiting the settings endpoint to administrative source addresses.
- If patching is delayed, remove or blank sensitive credential fields in the Settings record and configure integrations through environment variables instead.
# Example nginx configuration blocking unauthenticated access to the Settings API
location ~ ^/settings(/|$) {
allow 10.0.0.0/8;
deny all;
proxy_pass http://craftplan_upstream;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

