mirror of
https://github.com/FreshRSS/FreshRSS.git
synced 2026-06-29 01:35:35 -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 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>
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());
|
|
}
|
|
}
|
|
}
|