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.
# 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
# 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
# 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
| Security Test | Method | Risk |
|---|---|---|
| All subtitle provider credentials in one endpoint | GET /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 request | High |
| Sonarr and Radarr API key extraction | GET /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 key | High |
| Content library exposure via subtitle history | GET /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 instances | Medium |
| bazarr.db credential storage | Read 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 directory | High |
| No authentication by default | HTTP 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 port | High |
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