]> git.kaiwu.me - nginx.git/commitdiff
Mail: host validation.
authorRoman Arutyunyan <arut@nginx.com>
Thu, 26 Feb 2026 07:52:53 +0000 (11:52 +0400)
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>
Tue, 24 Mar 2026 18:33:23 +0000 (22:33 +0400)
Now host name resolved from client address is validated to only contain
the characters specified in RFC 1034, Section 3.5.  The validation allows
to avoid injections when using the resolved host name in auth_http and
smtp proxy.

Reported by Asim Viladi Oglu Manizada, Colin Warren,
Xiao Liu (Yunnan University), Yuan Tan (UC Riverside), and
Bird Liu (Lanzhou University).

src/mail/ngx_mail_smtp_handler.c

index 1e26c2c8d7b971b57fc408ec26d235108b4ed4a7..97bbd70631a4baa089689666119adf15f15b2342 100644 (file)
@@ -13,6 +13,7 @@
 
 
 static void ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx);
+static ngx_int_t ngx_mail_smtp_validate_host(ngx_str_t *name);
 static void ngx_mail_smtp_resolve_name(ngx_event_t *rev);
 static void ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx);
 static void ngx_mail_smtp_block_reading(ngx_event_t *rev);
@@ -127,6 +128,20 @@ ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx)
         return;
     }
 
+    if (ngx_mail_smtp_validate_host(&ctx->name) != NGX_OK) {
+        ngx_log_error(NGX_LOG_ERR, c->log, 0,
+                      "%V resolved to invalid host name \"%V\"",
+                      &c->addr_text, &ctx->name);
+
+        s->host = smtp_tempunavail;
+
+        ngx_resolve_addr_done(ctx);
+
+        ngx_mail_smtp_greeting(s, s->connection);
+
+        return;
+    }
+
     c->log->action = "in resolving client hostname";
 
     s->host.data = ngx_pstrdup(c->pool, &ctx->name);
@@ -149,6 +164,36 @@ ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx)
 }
 
 
+static ngx_int_t
+ngx_mail_smtp_validate_host(ngx_str_t *name)
+{
+    u_char      ch;
+    ngx_uint_t  i;
+
+    if (name->len == 0) {
+        return NGX_DECLINED;
+    }
+
+    for (i = 0; i < name->len; i++) {
+        ch = name->data[i];
+
+        /* allow only characters from RFC 1034, Section 3.5 */
+
+        if ((ch >= 'a' && ch <= 'z')
+            || (ch >= 'A' && ch <= 'Z')
+            || (ch >= '0' && ch <= '9')
+            || ch == '-' || ch == '.')
+        {
+            continue;
+        }
+
+        return NGX_DECLINED;
+    }
+
+    return NGX_OK;
+}
+
+
 static void
 ngx_mail_smtp_resolve_name(ngx_event_t *rev)
 {