Bazarr Security Testing: API Key, Subtitle Provider Credentials, and Sonarr/Radarr Integration

Bazarr is the subtitle management application in the *arr stack, automatically downloading subtitles for every movie and TV episode managed by Radarr and Sonarr. Its security profile is defined by the breadth of third-party credentials it stores: subtitle provider accounts (OpenSubtitles, Subscene, Addic7ed, LegendasDivX, OpenSubtitles.com) each require separate login credentials that Bazarr stores; Bazarr's API key in Settings > General provides access to all configuration including every stored subtitle provider credential; the /api/system/settings endpoint returns the full configuration including subtitle provider usernames and passwords; Bazarr stores the Sonarr and Radarr API keys and base URLs in its configuration, accessible via the same settings endpoint; and Bazarr's subtitle history endpoints reveal the complete content library. This guide covers systematic Bazarr security assessment.

Table of Contents

  1. API Key and Settings Extraction
  2. Subtitle Provider Credential Extraction
  3. Content Library Exposure via History
  4. Bazarr Security Hardening

API Key and Settings Extraction

# Bazarr API — key-based access to all configuration and subtitle management
BAZARR_URL="https://bazarr.example.com"
API_KEY="your-bazarr-api-key"

# Get Bazarr system status and version
curl -s "${BAZARR_URL}/api/system/status" \
  -H "X-API-KEY: ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Bazarr version: {d.get(\"bazarr_version\")}')
print(f'Python version: {d.get(\"python_version\")}')
print(f'OS: {d.get(\"operating_system\")}')
" 2>/dev/null

# Get full system settings — contains all provider credentials and arr integration details
curl -s "${BAZARR_URL}/api/system/settings" \
  -H "X-API-KEY: ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
general = d.get('general',{})
print(f'Host: {general.get(\"ip\")}:{general.get(\"port\")}')
print(f'Base URL: {general.get(\"base_url\")}')
print(f'Auth type: {general.get(\"auth_type\")}')

# Sonarr integration
sonarr = d.get('sonarr',{})
print(f'Sonarr base URL: {sonarr.get(\"base_url\")}')
print(f'Sonarr API key: {sonarr.get(\"apikey\")}')
print(f'Sonarr SSL: {sonarr.get(\"ssl\")}')

# Radarr integration
radarr = d.get('radarr',{})
print(f'Radarr base URL: {radarr.get(\"base_url\")}')
print(f'Radarr API key: {radarr.get(\"apikey\")}')
print(f'Radarr SSL: {radarr.get(\"ssl\")}')
" 2>/dev/null

Subtitle Provider Credential Extraction

# Bazarr subtitle providers — stores username/password for each enabled provider
BAZARR_URL="https://bazarr.example.com"
API_KEY="your-bazarr-api-key"

# Extract all subtitle provider credentials from settings
curl -s "${BAZARR_URL}/api/system/settings" \
  -H "X-API-KEY: ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
providers = d.get('providers',{})
print(f'Enabled providers: {len([k for k,v in providers.items() if isinstance(v,dict) and v.get(\"enabled\")])}')

# Common subtitle providers and their credential fields
provider_fields = {
    'opensubtitles': ['username','password'],
    'opensubtitlescom': ['username','password'],
    'subscene': ['username','password'],
    'addic7ed': ['username','password'],
    'legendasdivx': ['username','password'],
    'napiprojekt': ['username','password'],
    'titlovi': ['username','password'],
    'betaseries': ['token'],
    'bsplayer': ['username','password'],
    'subdl': ['api_key'],
    'subssabbz': ['username','password'],
}

for provider, fields in provider_fields.items():
    pdata = providers.get(provider,{})
    if pdata:
        for field in fields:
            val = pdata.get(field,'')
            if val:
                print(f'  {provider}.{field}: {val}')
" 2>/dev/null

# List all enabled subtitle providers
curl -s "${BAZARR_URL}/api/providers" \
  -H "X-API-KEY: ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
enabled = d.get('data',[])
print(f'Active providers: {len(enabled)}')
for p in enabled:
    print(f'  {p.get(\"name\")} — {p.get(\"status\",{}).get(\"status\",\"unknown\")}')
" 2>/dev/null

Content Library Exposure via History

# Bazarr subtitle history — reveals complete content library
BAZARR_URL="https://bazarr.example.com"
API_KEY="your-bazarr-api-key"

# Get episode subtitle history — reveals all TV shows and episodes
curl -s "${BAZARR_URL}/api/episodes/history?page=1&per_page=100" \
  -H "X-API-KEY: ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
total = d.get('total','?')
data = d.get('data',[])
print(f'Total episode history records: {total}')
for item in data[:10]:
    print(f'  [{item.get(\"action\")}] {item.get(\"sonarr_series_title\")} S{item.get(\"season_number\",\"?\")}E{item.get(\"episode_number\",\"?\")} — provider: {item.get(\"provider\")}')
" 2>/dev/null

# Get movie subtitle history — reveals all movies in Radarr
curl -s "${BAZARR_URL}/api/movies/history?page=1&per_page=100" \
  -H "X-API-KEY: ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
total = d.get('total','?')
data = d.get('data',[])
print(f'Total movie history records: {total}')
for item in data[:10]:
    print(f'  [{item.get(\"action\")}] {item.get(\"radarr_title\")} ({item.get(\"radarr_year\")}) — provider: {item.get(\"provider\")}')
" 2>/dev/null

Bazarr Security Hardening

Bazarr Security Hardening Checklist:
Security TestMethodRisk
All subtitle provider credentials in one endpointGET /api/system/settings — returns the full configuration JSON including OpenSubtitles username/password, Subscene credentials, Addic7ed credentials, and API keys for every configured subtitle provider in a single requestHigh
Sonarr and Radarr API key extractionGET /api/system/settings — sonarr.apikey and radarr.apikey fields return the API keys and base URLs for the connected Sonarr and Radarr instances; lateral movement to the full arr stack from a single Bazarr API keyHigh
Content library exposure via subtitle historyGET /api/episodes/history and /api/movies/history — returns every TV show and movie that has had subtitle activity; reveals the complete content library managed by the linked Sonarr and Radarr instancesMedium
bazarr.db credential storageRead bazarr.db Settings table — contains all subtitle provider credentials and arr API keys in plaintext; accessible via path traversal or direct filesystem access to the Bazarr data directoryHigh
No authentication by defaultHTTP request to Bazarr URL without credentials — Bazarr does not require authentication until explicitly configured; default installations are accessible to anyone who can reach the host on the configured portHigh

Automate Bazarr Security Testing

Ironimo tests Bazarr deployments for subtitle provider credential extraction from the settings API (OpenSubtitles, Subscene, Addic7ed, and others), Sonarr and Radarr API key retrieval via the Bazarr settings endpoint, content library exposure through subtitle history, authentication bypass when no credentials are configured, bazarr.db credential storage analysis, and API key rotation validation.

Start free scan