From 085d10118ddb8f23a24d98d3951cee6576f9d1e0 Mon Sep 17 00:00:00 2001
From: FreddleSpl0it <75116288+FreddleSpl0it@users.noreply.github.com>
Date: Wed, 28 Oct 2026 16:36:16 +0100
Subject: [PATCH] [Nginx][Web] Client address and autodiscover adjustments
---
data/conf/nginx/templates/nginx.conf.j2 | 7 ++
.../nginx/templates/sites-default.conf.j2 | 3 +-
data/web/autodiscover.php | 85 +++++++++----------
3 files changed, 51 insertions(+), 44 deletions(-)
diff --git a/data/conf/nginx/templates/nginx.conf.j2 b/data/conf/nginx/templates/nginx.conf.j2
index 861c7e560..d97bb8b99 100644
--- a/data/conf/nginx/templates/nginx.conf.j2
+++ b/data/conf/nginx/templates/nginx.conf.j2
@@ -47,6 +47,13 @@ http {
default "";
}
+ # Client address for PHP: on the internal sogo-auth listener nginx itself is the client,
+ # the real address comes from the X-Real-IP header set by /sogo-auth-verify
+ map $sogo_auth_internal $mailcow_client_ip {
+ "1" $http_x_real_ip;
+ default $remote_addr;
+ }
+
{% if HTTP_REDIRECT %}
# HTTP to HTTPS redirect
server {
diff --git a/data/conf/nginx/templates/sites-default.conf.j2 b/data/conf/nginx/templates/sites-default.conf.j2
index 842c50a54..9cd60a343 100644
--- a/data/conf/nginx/templates/sites-default.conf.j2
+++ b/data/conf/nginx/templates/sites-default.conf.j2
@@ -116,7 +116,8 @@ location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
- fastcgi_param HTTP_X_REAL_IP $remote_addr;
+ fastcgi_param REMOTE_ADDR $mailcow_client_ip;
+ fastcgi_param HTTP_X_REAL_IP $mailcow_client_ip;
# trusted internal-auth marker; empty for external clients (see nginx.conf map)
fastcgi_param SOGO_AUTH_INTERNAL $sogo_auth_internal;
fastcgi_read_timeout 3600;
diff --git a/data/web/autodiscover.php b/data/web/autodiscover.php
index 3e31dc3dd..e2d70bbae 100644
--- a/data/web/autodiscover.php
+++ b/data/web/autodiscover.php
@@ -144,41 +144,15 @@ try {
}
$username = trim((string)$email);
-try {
- $stmt = $pdo->prepare("SELECT `mailbox`.`name`, `mailbox`.`active` FROM `mailbox`
- INNER JOIN `domain` ON `mailbox`.`domain` = `domain`.`domain`
- WHERE `mailbox`.`username` = :username
- AND `mailbox`.`active` = '1'
- AND `domain`.`active` = '1'");
- $stmt->execute(array(':username' => $username));
- $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
-}
-catch(PDOException $e) {
- // Database error - return error response with complete XML
- list($usec, $sec) = explode(' ', microtime());
-?>
-
-
- 500
- Database Error
-
-
-
-
- time(),
"ua" => $_SERVER['HTTP_USER_AGENT'],
- "user" => $email,
+ "user" => "none",
"ip" => $_SERVER['REMOTE_ADDR'],
- "service" => "Error: mailbox not found or inactive"
+ "service" => "Error: invalid email address in request"
)
);
$redis->lPush('AUTODISCOVER_LOG', $json);
@@ -202,13 +176,33 @@ if (empty($MailboxData)) {
prepare("SELECT `mailbox`.`name`, `mailbox`.`active` FROM `mailbox`
+ INNER JOIN `domain` ON `mailbox`.`domain` = `domain`.`domain`
+ WHERE `mailbox`.`username` = :username
+ AND `mailbox`.`active` = '1'
+ AND `domain`.`active` = '1'");
+ $stmt->execute(array(':username' => $username));
+ $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
+}
+catch(PDOException $e) {
+ // Database error - return error response with complete XML
+ list($usec, $sec) = explode(' ', microtime());
+?>
+
+
+ 500
+ Database Error
+
+
+
+
+ $_SERVER['HTTP_USER_AGENT'],
"user" => $email,
"ip" => $_SERVER['REMOTE_ADDR'],
- "service" => $autodiscover_config['autodiscoverType']
+ // The answer is the same, only the log tells unknown or inactive mailboxes apart
+ "service" => (empty($MailboxData)) ? "Error: mailbox not found or inactive" : $autodiscover_config['autodiscoverType']
)
);
$redis->lPush('AUTODISCOVER_LOG', $json);
$redis->lTrim('AUTODISCOVER_LOG', 0, 100);
+ if (empty($MailboxData)) {
+ $redis->publish("F2B_CHANNEL", "Autodiscover: Invalid mailbox attempt by " . $_SERVER['REMOTE_ADDR']);
+ error_log("Autodiscover: Invalid mailbox attempt by " . $_SERVER['REMOTE_ADDR']);
+ }
}
catch (RedisException $e) {
$_SESSION['return'][] = array(
@@ -243,7 +242,7 @@ if ($autodiscover_config['autodiscoverType'] == 'imap') {
=$autodiscover_config['imap']['server'];?>
=$autodiscover_config['imap']['port'];?>
off
- =$email;?>
+ =htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?>
off
on
on
@@ -253,7 +252,7 @@ if ($autodiscover_config['autodiscoverType'] == 'imap') {
=$autodiscover_config['smtp']['server'];?>
=$autodiscover_config['smtp']['port'];?>
off
- =$email;?>
+ =htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?>
off
on
on
@@ -265,15 +264,15 @@ if ($autodiscover_config['autodiscoverType'] == 'imap') {
?>
CalDAV
- https://=$autodiscover_config['caldav']['server'];?>/SOGo/dav/=$email;?>/
+ https://=$autodiscover_config['caldav']['server'];?>/SOGo/dav/=htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?>/
off
- =$email;?>
+ =htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?>
CardDAV
- https://=$autodiscover_config['carddav']['server'];?>/SOGo/dav/=$email;?>/
+ https://=$autodiscover_config['carddav']['server'];?>/SOGo/dav/=htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?>/
off
- =$email;?>
+ =htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?>
en:en
=htmlspecialchars($displayname, ENT_XML1 | ENT_QUOTES, 'UTF-8');?>
- =$email;?>
+ =htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?>