Files
FreshRSS/config.default.php
Inverle dcec27c69d Add SSRF mitigations using filter_var and CURLOPT_RESOLVE (#8400)
* Add SSRF mitigations using `filter_var` and `CURLOPT_RESOLVE`
The idea is to prevent FreshRSS from sending any HTTP requests to internal services, except for the ones that are explicitly allowed in the config.

Based on 6e82b46a48/lib/filelib.php (L3818) and https://github.com/symfony/symfony/blob/8.1/src/Symfony/Component/HttpClient/NoPrivateNetworkHttpClient.php

https://github.com/FreshRSS/simplepie/pull/76
https://github.com/FreshRSS/simplepie/pull/78

* Add allowlist setting in Web UI

* make readme

* Update app/i18n/fr/admin.php

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>

* make readme again

* make readme

* Further work

Still WIP and needs testing etc.

* Readd previous if check for domain combination allowlist

* Turn POST to GET after redirect

* Improve

* Update config.default.php

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>

* make readme

* Skip SSRF check if `CURLOPT_PROXY` is set

* make readme

* Fix `!empty()` mistake

* Respect max redirects feed option when fetching with `httpGet()`

* Respect max redirects during SimplePie fetching + fix bypass

bypass fix: `CURLOPT_FOLLOWLOCATION` was moved below so that emulated redirects are enforced.

* Avoid FreshRSS and Minz code in SimplePie
https://github.com/FreshRSS/FreshRSS/pull/8400#discussion_r2935375980

* Corrected hook code

* phpdoc wrong return type

* Add CIDR support in allowlist

* Implement simple DNS caching

* Suppress `dns_get_record()` warnings

* A bit of proof-reading

* Minor typo

* Fix proxy logic

* Fix HTTP POST redirect logic

* Proofread checkCIDR
Add fixes for several situations

* Remove credentials from URL in logs

* Ensure `CURLOPT_FOLLOWLOCATION` is `false` by setting it at the end

* Fix codesniffer long line

* Fix potential bypass due to wrong return value

If there were no records returned by `dns_get_record()`, no overrides to `CURLOPT_RESOLVE` would get passed,
and a potential bypass could occur, when cURL would try to resolve the domain by itself.

* Put the URL at the end in logs

* Add documentation and environment variable support

* make readme

* Fix wrong behavior in case of IP

* Fix duplicate selector in CSS

* Minor type check change

* i18n fr, en

* Minor type check change

* Fix whitespace i18n fr

* make fix-all

* Fix `$ips_ok` not being returned after domain records were cached

* make readme

* PHPStan fix

* make readme

* Minor syntax in SimplePie

* Only return `null` if no allowed IPs were found

* Add wildcard *, help message

* Consistent docs with help message

* i18n: pl

* SimplePie compatibility PHP 7.2

* make fix-all

* Sync SimplePie
* https://github.com/FreshRSS/simplepie/pull/76

* 💥 Breaking change in the Changelog

* Document `INTERNAL_HOST_ALLOWLIST` in Docker docs

* Remove `Cookie` and `Authorization` headers in `httpGet()` during cross-origin redirect

* Minor whitespace
And same comment convention than below

* Remove authentication headers and change POST to GET on redirect in SimplePie

* Remove .local in Docker example

* Fill in default ports when comparing URL origins

* Remove .local from other places than the Docker example

* Rewrite WebSub subscribe to use `httpGet()`

* make fix-all

* Also unset `CURLOPT_USERPWD` during redirects

* phpcs fix

* Always unset `CURLOPT_FOLLOWLOCATION`

* Bump SimplePie
https://github.com/FreshRSS/simplepie/pull/78

* Update logic for CURLOPT_FOLLOWLOCATION

* Fix PHPStan

* Changelog fix security section

* Update most common RSS Bridge case
https://hub.docker.com/r/rssbridge/rss-bridge

* Replace misleading 127.0.0.1:8080 example for Docker
This does not make sense for a Docker container

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-06-28 18:51:04 +02:00

262 lines
9.4 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
# Do not modify this file, which defines default values,
# but instead edit `./data/config.php` after the install process is completed,
# or edit `./data/config.custom.php` before the install process.
return [
# Set to `development` to get additional error messages,
# or to `production` to get only the most important messages.
'environment' => 'production',
# Used to make crypto more unique. Generated during install.
'salt' => '',
# Specify address of the FreshRSS instance,
# used when building absolute URLs, e.g. for WebSub.
# Examples:
# https://example.net/FreshRSS/p/
# https://freshrss.example.net/
'base_url' => '',
# Specify address of the FreshRSS auto-update server.
'auto_update_url' => 'https://update.freshrss.org',
# Natural language of the user interface, e.g. `en`, `fr`.
'language' => 'en',
# Title of this FreshRSS instance in the Web user interface.
'title' => 'FreshRSS',
# Meta description used when `allow_robots` is true.
'meta_description' => '',
# Override logo of this FreshRSS instance in the Web user interface.
# It is rendered inside an <a>...</a> element and must be valid HTML or text.
# Example: '<img class="logo" src="https://example.net/Hello.png" alt="Logo Example" /> Hello'
'logo_html' => '',
# Name of the default user. Also used as the public user for anonymous reading.
'default_user' => '_',
# Force users to validate their email address. If `true`, an email with a
# validation URL is sent during registration, and users cannot access their
# feed if they didnt access this URL.
'force_email_validation' => false,
# Allow or not visitors without login to see the articles
# of the default user.
'allow_anonymous' => false,
# Allow or not anonymous users to start the refresh process.
'allow_anonymous_refresh' => false,
# Login method:
# `none` is without password and shows only the default user;
# `form` is a conventional Web login form;
# `http_auth` is an access controlled by the HTTP Web server (e.g. `/FreshRSS/p/i/.htaccess` for Apache)
# if you use `http_auth`, remember to protect only `/FreshRSS/p/i/`,
# and in particular not protect `/FreshRSS/p/api/` if you would like to use the API (different login system).
'auth_type' => 'form',
# Whether reauthentication is required for performing sensitive actions e.g. promoting a user or applying an update
'reauth_required' => true,
# Time before asking for reauth
# Default: 1200s (20 min)
'reauth_time' => 1200,
# When using http_auth, automatically register any unknown user
'http_auth_auto_register' => true,
# Optionally, you can specify the $_SERVER key containing the email address used when registering
# the user (e.g. REMOTE_USER_EMAIL).
'http_auth_auto_register_email_field' => '',
# Allow or not the use of the API, used for mobile apps.
# End-point is https://freshrss.example.net/api/greader.php
# You need to set the users API password.
'api_enabled' => false,
# By default, FreshRSS will display a warning to logged-in admin users if the CSP policy is insecure.
# This setting can disable the warning.
# For more information see: https://freshrss.github.io/FreshRSS/en/admins/10_ServerConfig.html#security
'suppress_csp_warning' => false,
# Content-Security-Policy frame-ancestors
'csp.frame-ancestors' => "'none'",
# Enable or not the use of syslog to log the activity of
# SimplePie, which is retrieving RSS feeds via HTTP requests.
'simplepie_syslog_enabled' => true,
# Enable or not support of PubSubHubbub.
# /!\ It should NOT be enabled if base_url is not reachable by an external server.
'pubsubhubbub_enabled' => false,
# Allow or not Web robots (e.g. search engines) in HTML headers.
'allow_robots' => false,
# If true does nothing, if false restricts HTTP Referer via: meta referrer origin
'allow_referrer' => false,
# Number of feeds to refresh in parallel from the Web user interface.
# Faster with higher values. Reduce for server with little memory or database issues.
'nb_parallel_refresh' => 10,
'limits' => [
# Duration in seconds of the login cookie.
'cookie_duration' => FreshRSS_Auth::DEFAULT_COOKIE_DURATION,
# Duration in seconds of the SimplePie cache, during which a query to the RSS feed will return the local cached version.
# Especially important for multi-user setups.
# Might be overridden by HTTP response headers.
'cache_duration' => 800,
# Minimal cache duration (in seconds), overriding HTTP response headers `Cache-Control` and `Expires`.
'cache_duration_min' => 60,
# Maximal cache duration (in seconds), overriding HTTP response headers `Cache-Control` and `Expires`.
'cache_duration_max' => 86400,
# Default rate limit duration (in seconds), when HTTP response header `Retry-After` is absent.
'retry_after_default' => 1500,
# Maximal rate limit duration (in seconds), overriding HTTP response header `Retry-After`.
'retry_after_max' => 172800,
# SimplePie HTTP request timeout in seconds.
'timeout' => 20,
# If a user has not used FreshRSS for more than x seconds,
# then its feeds are not refreshed anymore.
'max_inactivity' => PHP_INT_MAX,
# Max number of feeds for a user.
'max_feeds' => 131072,
# Max number of categories for a user.
'max_categories' => 16384,
# Max number of accounts that anonymous users can create (only for Web form login type)
# 0 for an unlimited number of accounts
# 1 is to not allow user registrations (1 is corresponding to the admin account)
'max_registrations' => 1,
# Max amount of bytes that are allowed for upload of custom favicon
'max_favicon_upload_size' => 1048576, # 1 MiB
# Limits for regex, useful to limit regex during user searches
'regex_backtrack_limit' => 10000,
'regex_recursion_limit' => 100,
],
# Options used by cURL when making HTTP requests, e.g. when the SimplePie library retrieves feeds.
# https://php.net/manual/function.curl-setopt
'curl_options' => [
# Options to disable SSL/TLS certificate check (e.g. for self-signed HTTPS)
//CURLOPT_SSL_VERIFYHOST => 0,
//CURLOPT_SSL_VERIFYPEER => false,
# Options to use a proxy for retrieving feeds.
//CURLOPT_PROXYTYPE => CURLPROXY_HTTP,
//CURLOPT_PROXY => '127.0.0.1',
//CURLOPT_PROXYPORT => 8080,
//CURLOPT_PROXYAUTH => CURLAUTH_BASIC,
//CURLOPT_PROXYUSERPWD => 'user:password',
],
'db' => [
# Type of database: `sqlite` or `mysql` or 'pgsql'
'type' => 'sqlite',
# Database server
'host' => 'localhost',
# Database user
'user' => '',
# Database password
'password' => '',
# Database name
'base' => '',
# Tables prefix (useful if you use the same database for multiple things)
'prefix' => 'freshrss_',
# Additional connection string parameters, such as PostgreSQL 'sslmode=??;sslrootcert=??'
# https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS
'connection_uri_params' => '',
# Additional PDO parameters, such as offered by MySQL https://php.net/ref.pdo-mysql
'pdo_options' => [
//Pdo\Mysql::ATTR_SSL_KEY => '/path/to/client-key.pem',
//Pdo\Mysql::ATTR_SSL_CERT => '/path/to/client-cert.pem',
//Pdo\Mysql::ATTR_SSL_CA => '/path/to/ca-cert.pem',
],
],
# Configuration to send emails.
# These options are basically a mapping of the PHPMailer class attributes
# from the PHPMailer library.
#
# See https://phpmailer.github.io/PHPMailer/classes/PHPMailer-PHPMailer-PHPMailer.html#properties
'mailer' => 'mail', // 'mail' or 'smtp'
'smtp' => [
'hostname' => '', // the domain used in the Message-ID header
'host' => 'localhost', // the SMTP server address
'port' => 25,
'auth' => false,
'auth_type' => '', // 'CRAM-MD5', 'LOGIN', 'PLAIN', 'XOAUTH2' or ''
'username' => '',
'password' => '',
'secure' => '', // '', 'ssl' or 'tls'
'from' => 'root@localhost',
],
# Automatic SQLite export of each users database, triggered by `./cli/export-sqlite-auto.php`.
# Intended to be scheduled by an admin (e.g. via cron) for periodic on-server backups
# distinct from the manual `./cli/db-backup.php` / `./cli/db-restore.php` migration workflow.
'auto_sqlite_export' => [
# Enable the automatic export. When false, `./cli/export-sqlite-auto.php` exits without writing.
'enabled' => false,
# Number of past exports to retain per user. Older files are pruned after a successful export.
'retention' => 7,
],
# List of enabled FreshRSS extensions.
'extensions_enabled' => [
],
# Extensions configurations
'extensions' => [],
# Disable self-update,
'disable_update' => false,
# Trusted IPs (e.g. of last proxy) that are allowed to send unsafe HTTP headers.
# The connection IP used during FreshRSS setup is automatically added to this list.
# Will be checked against CONN_REMOTE_ADDR (if available, to be robust even when using Apache mod_remoteip)
# or REMOTE_ADDR environment variable.
# This array can be overridden by the TRUSTED_PROXY environment variable.
# Read the documentation before configuring this https://freshrss.github.io/FreshRSS/en/admins/09_AccessControl.html
'trusted_sources' => [
'127.0.0.0/8',
'::1/128',
],
# Requests to internal hosts such as 127.0.0.1 are blocked by default
# Blocked ranges include:
# - 10.0.0.0/8
# - 172.16.0.0/12
# - 192.168.0.0/16
#
# Here you can add overrides for particular IP/domain:port combinations
# Examples: 127.0.0.1:8080, rss-bridge:80, etc.
#
# CIDR is permitted too
# Examples: 0.0.0.0/0, ::/0 (to allow any IPv4 or any IPv6)
#
# Setting * disables this check completely, allowing any host to be accessed (unsafe)
'internal_host_allowlist' => [],
];