mirror of
https://github.com/FreshRSS/FreshRSS.git
synced 2026-09-12 21:50:57 -04:00
* 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 https://github.com/moodle/moodle/blob/6e82b46a480826d1a85394d9e5087f7d82d1dd52/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>
51 lines
1.9 KiB
PHP
51 lines
1.9 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* @property bool $allow_anonymous
|
|
* @property bool $allow_anonymous_refresh
|
|
* @property-read bool $allow_referrer
|
|
* @property bool $allow_robots
|
|
* @property bool $api_enabled
|
|
* @property string $archiving
|
|
* @property 'form'|'http_auth'|'none' $auth_type
|
|
* @property array{enabled:bool,retention:int} $auto_sqlite_export
|
|
* @property-read bool $reauth_required
|
|
* @property-read int $reauth_time
|
|
* @property-read string $auto_update_url
|
|
* @property-read array<int,mixed> $curl_options
|
|
* @property string $default_user
|
|
* @property string $email_validation_token
|
|
* @property bool $force_email_validation
|
|
* @property-read bool $http_auth_auto_register
|
|
* @property-read string $http_auth_auto_register_email_field
|
|
* @property string $language
|
|
* @property string $closed_registration_message
|
|
* @property array<string,int> $limits
|
|
* @property-read string $logo_html
|
|
* @property-read string $meta_description
|
|
* @property-read int $nb_parallel_refresh
|
|
* @property-read bool $pubsubhubbub_enabled
|
|
* @property-read string $salt
|
|
* @property-read bool $simplepie_syslog_enabled
|
|
* @property-read bool $suppress_csp_warning
|
|
* @property array<string> $trusted_sources
|
|
* @property array<string> $internal_host_allowlist
|
|
* @property array<string,array<string,mixed>> $extensions
|
|
*/
|
|
final class FreshRSS_SystemConfiguration extends Minz_Configuration {
|
|
|
|
/** @throws Minz_FileNotExistException */
|
|
public static function init(string $config_filename, ?string $default_filename = null): FreshRSS_SystemConfiguration {
|
|
parent::register('system', $config_filename, $default_filename);
|
|
try {
|
|
$conf = parent::get('system');
|
|
ini_set('pcre.backtrack_limit', $conf->limits['regex_backtrack_limit']);
|
|
ini_set('pcre.recursion_limit', $conf->limits['regex_recursion_limit']);
|
|
return $conf;
|
|
} catch (Minz_ConfigurationNamespaceException $ex) {
|
|
FreshRSS::killApp($ex->getMessage());
|
|
}
|
|
}
|
|
}
|