The Call is Coming from Inside the House: Unrestricted SSRF in Miniflux
Jan 8, 2026·4 min read
Executive Summary (TL;DR)
Miniflux's media proxy feature, designed to protect user privacy, failed to validate destination IP addresses. Authenticated attackers can trick the server into fetching internal resources (like AWS metadata or local admin panels) by embedding malicious URLs in RSS feeds. Fixed in version 2.2.16.
A logic flaw in Miniflux's media proxy allows authenticated users to turn the server against itself, probing internal networks and cloud metadata services via Server-Side Request Forgery (SSRF).
The Hook: Privacy That Backfires
Miniflux is the darling of the self-hosted RSS community. It is minimal, fast, and written in Go. One of its standout privacy features is the Media Proxy. The concept is simple: when you load an RSS feed containing images from third-party servers, you don't want your browser pinging those servers directly. That leaks your IP address and allows tracking.
So, Miniflux acts as a middleman. It rewrites <img src="http://tracker.com/pixel.png"> into something like https://your-miniflux.com/proxy/SIGNATURE/BASE64_URL. Your browser talks to Miniflux; Miniflux talks to the tracker. Your IP stays safe.
It is a great feature, assuming Miniflux is careful about who it talks to. But in versions prior to 2.2.16, Miniflux was a little too helpful. It would fetch absolutely anything you asked it to—including resources that should never be accessible from the outside world.
The Flaw: The Confused Deputy
The vulnerability here is a textbook Server-Side Request Forgery (SSRF). The flaw resides in internal/ui/proxy.go. To prevent the proxy from being abused as an open relay by the entire internet, Miniflux correctly implemented an HMAC signature system. The server signs the URL, and when a request comes in, it verifies the signature.
Here is the logic failure: The server verified authorization (is this request signed by me?) but completely skipped destination validation (is this target safe?).
Because the signature is generated automatically when Miniflux renders a feed, an attacker doesn't need to forge the signature. They just need to get Miniflux to sign a malicious URL for them. Once signed, the proxy handler sees a valid signature and blindly executes the HTTP request, even if the destination is localhost, 192.168.1.1, or the deadly 169.254.169.254.
The Code: Blind Trust
In the vulnerable version, the proxy handler essentially functioned like this (simplified for clarity):
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 1. Verify HMAC signature (The lock on the front door)
if !isValidSignature(r) {
http.Error(w, "Forbidden", 403)
return
}
// 2. Decode the target URL
targetURL := decode(r.URL.Path)
// 3. FETCH IT BLINDLY (The open back window)
resp, err := client.Get(targetURL)
if err != nil {
// ...
}
// ... stream response to user
}There was no step 2.5. There was no "blocklist" for private IP ranges (RFC 1918) or loopback addresses. The fix involves resolving the hostname to an IP address before the request is made and checking that IP against a list of forbidden ranges.
The Exploit: Feeding the Beast
Exploiting this requires a valid account, but in a multi-user instance or an open-registration instance, that is trivial. The attack chain leverages the RSS parser itself to do the heavy lifting.
Step 1: The Trap The attacker hosts a malicious RSS feed. Inside one of the items, they embed an image tag pointing to an internal resource.
<item>
<title>Free AWS Creds</title>
<description>
<![CDATA[
<img src="http://169.254.169.254/latest/meta-data/iam/security-credentials/admin-role">
]]>
</description>
</item>Step 2: The Signature
The attacker subscribes to this feed in Miniflux. When they view the feed, Miniflux parses the HTML, finds the <img> tag, and rewrites it to use the proxy. Miniflux signs the URL for the internal AWS metadata endpoint.
Step 3: The Exfiltration
The attacker inspects the page source, grabs the signed URL (e.g., /proxy/d7a8.../aHR0cDovLzE2OS...), and requests it. Miniflux dutifully fetches the AWS credentials and serves them back to the attacker as if they were a standard JPEG.
The Impact: Cloud Compromise
The impact depends entirely on where Miniflux is hosted.
Cloud Environments (AWS, GCP, Azure): This is critical. Accessing the instance metadata service (169.254.169.254) often returns temporary IAM credentials. An attacker can use these to steal data from S3 buckets, shut down instances, or pivot further into the cloud infrastructure.
Home Labs / On-Prem: Miniflux often sits in a Docker container on a home server. An attacker could scan the local network (192.168.x.x) to find router admin interfaces, unauthenticated Redis instances, or other web services that assume "local means safe."
The Fix: Trust No One
The remediation is straightforward: Upgrade to Miniflux 2.2.16. This version introduces strict IP filtering in the proxy handler. It resolves the target domain and rejects the request if the IP falls into loopback, link-local, or private network ranges.
If you cannot upgrade immediately, you must disable the media proxy feature entirely. Set the environment variable:
MEDIA_PROXY_MODE=noneThis kills the privacy feature but closes the security hole until you can patch.
Official Patches
Technical Appendix
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:NAffected Systems
Affected Versions Detail
| Product | Affected Versions | Fixed Version |
|---|---|---|
Miniflux Miniflux | <= 2.2.15 | 2.2.16 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network |
| CVSS | 6.5 (Medium) |
| Privileges | Low (Authenticated) |
| Impact | High Confidentiality Loss |
| Exploit Status | Proof of Concept |
MITRE ATT&CK Mapping
Server-Side Request Forgery (SSRF)
Known Exploits & Detection
Vulnerability Timeline
Subscribe to updates
Get the latest CVE analysis reports delivered to your inbox.