Security review found no exploitable issue — none of the 3 endpoints
accept user input, so there's no injection surface (upstream URLs are
hardcoded constants, output is XML-escaped). These are defense-in-depth
only: deny direct HTTP access to cache/, and cap CURLOPT_MAXREDIRS to
avoid a hung request on a misbehaving upstream.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Same imio.smartweb JSON API as the Python script, but each feed regenerates
on demand (15 min file cache) instead of via cron, so it works on plain
PHP shared hosting with no server config access. Also adds facebook.php,
a caching proxy for the user's FetchRSS Atom feed so all three feeds live
under one domain and can be shared as stable URLs.
Tested with PHP 8.3 CLI: valid XML, real data (40 news, 12 events, proxied
Facebook feed).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>