#3564·h2o

h2o accepts a request where host contains 2 @ symbols

Author: Srinut22Created Mar 29, 2026Updated Apr 7, 2026

Hi, we ran into this issue when we ran the h2o server in a Docker container on port 8080.

Test Case Information

Request:

printf 'GET http://[email protected]@evil.test/public/index.html HTTP/1.1\r\nHost: [email protected]@evil.test\r\nConnection: close\r\n\r\n' | nc localhost 8080

Response:

HTTP/1.1 404 File Not Found
Connection: close
Content-Length: 9
Server: h2o/2.3.0-DEV@725e54bc9
content-type: text/plain; charset=utf-8

Affected Version:

h2o version 2.3.0-DEV@725e54bc9
OpenSSL: OpenSSL 3.0.2 15 Mar 2022
mruby: YES
fusion: YES
ssl-zerocopy: YES
ktls: YES
key-exchanges: secp521r1, secp384r1, x25519, secp256r1

h2o.conf

# h2o.conf
user: root
hosts:
  "default":
    strict-match: ON
    listen:
      port: 80
    paths:
      "/":
        file.dir: /usr/share/h2o/htdocs

Notes

RFC 3986 section 3.2 states:

authority = [ userinfo "@" ] host [ ":" port ]

It seems that the appropriate response would be to return a 400 because the hostname has 2 @ symbols, which is not permitted. This is because the @ is a reserved character per RFC 3986 section 2.2:

reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

and the userinfo field cannot contain an @ symbol per RFC section 3.2.1

userinfo = *( unreserved / pct-encoded / sub-delims / ":" )