diff options
| author | 2022-04-02 21:40:30 +0200 | |
|---|---|---|
| committer | 2022-04-02 21:40:30 +0200 | |
| commit | 2aba861bc983555faf6dd96c5daa4e40e5328c54 (patch) | |
| tree | 68d63f76d0ce79e06cb3cabaaaeb3cd82849c175 /lib | |
| parent | 191abf5ba541107c5a1c5f14202b99e17bee2074 (diff) | |
Add HTTP_REMOTE_USER header for auth (#4063)
* add HTTP_REMOTE_USER header for auth
* add ip whitelist for HTTP_REMOTE_USER header
* add IPv6 support for header auth
* fix formatting
* A few fixes
* Add some default trusted sources
* Fix IPv6 doc
* More standard header names
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/lib_rss.php | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/lib/lib_rss.php b/lib/lib_rss.php index b6fde6437..677e4a413 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -555,14 +555,67 @@ function get_user_configuration($username) { } /** + * Converts an IP (v4 or v6) to a binary representation using inet_pton + * + * @param string $ip the IP to convert + * @return string a binary representation of the specified IP + */ +function ipToBits(string $ip): string { + $binaryip = ''; + foreach (str_split(inet_pton($ip)) as $char) { + $binaryip .= str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT); + } + return $binaryip; +} + +/** + * Check if an ip belongs to the provided range (in CIDR format) + * + * @param string $ip the IP that we want to verify (ex: 192.168.16.1) + * @param string $range the range to check against (ex: 192.168.16.0/24) + * @return boolean true if the IP is in the range, otherwise false + */ +function checkCIDR(string $ip, string $range): bool { + $binary_ip = ipToBits($ip); + list($subnet, $mask_bits) = explode('/', $range); + $mask_bits = intval($mask_bits); + $binary_subnet = ipToBits($subnet); + + $ip_net_bits = substr($binary_ip, 0, $mask_bits); + $subnet_bits = substr($binary_subnet, 0, $mask_bits); + + return $ip_net_bits === $subnet_bits; +} + +/** + * Check if the client is allowed to send unsafe headers + * This uses the REMOTE_ADDR header to determine the sender's IP + * and the configuration option "trusted_sources" to get an array of the authorized ranges + * + * @return boolean, true if the sender's IP is in one of the ranges defined in the configuration, else false + */ +function checkTrustedIP(): bool { + if (!empty($_SERVER['REMOTE_ADDR'])) { + foreach (FreshRSS_Context::$system_conf->trusted_sources as $cidr) { + if (checkCIDR($_SERVER['REMOTE_ADDR'], $cidr)) { + return true; + } + } + } + return false; +} + +/** * @return string */ function httpAuthUser() { if (!empty($_SERVER['REMOTE_USER'])) { return $_SERVER['REMOTE_USER']; + } elseif (!empty($_SERVER['HTTP_REMOTE_USER']) && checkTrustedIP()) { + return $_SERVER['HTTP_REMOTE_USER']; } elseif (!empty($_SERVER['REDIRECT_REMOTE_USER'])) { return $_SERVER['REDIRECT_REMOTE_USER']; - } elseif (!empty($_SERVER['HTTP_X_WEBAUTH_USER'])) { + } elseif (!empty($_SERVER['HTTP_X_WEBAUTH_USER']) && checkTrustedIP()) { return $_SERVER['HTTP_X_WEBAUTH_USER']; } return ''; |
