aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGravatar drosoCode <44530920+drosoCode@users.noreply.github.com> 2022-04-02 21:40:30 +0200
committerGravatar GitHub <noreply@github.com> 2022-04-02 21:40:30 +0200
commit2aba861bc983555faf6dd96c5daa4e40e5328c54 (patch)
tree68d63f76d0ce79e06cb3cabaaaeb3cd82849c175 /lib
parent191abf5ba541107c5a1c5f14202b99e17bee2074 (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.php55
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 '';