Reto Peter created CAMEL-23070:
----------------------------------

             Summary: AS2AsyncMDNServerConnection uses strict 
RequestValidateHost — async MDNs rejected with HTTP 421
                 Key: CAMEL-23070
                 URL: https://issues.apache.org/jira/browse/CAMEL-23070
             Project: Camel
          Issue Type: Bug
          Components: camel-as2
    Affects Versions: 4.18.0
            Reporter: Reto Peter


The async MDN receiver (\{{AS2AsyncMDNServerConnection}}) uses 
\{{RequestValidateHost}} in its HttpProcessor, which enforces strict host 
header validation per HttpCore 5.3+. This causes incoming async MDN requests to 
be rejected with HTTP 421 "Not authoritative"
   when the \{{Host}} header doesn't exactly match the server's expected 
hostname.

  The main AS2 receiver (\{{AS2ServerConnection}}) does not use 
\{{RequestValidateHost}}, so it accepts any \{{Host}} header. This is an 
inconsistency — async MDNs are rejected while regular AS2 messages are accepted.
  \{panel}

  h3. Root Cause

  In \{{AS2AsyncMDNServerConnection.RequestListenerThread}} constructor (line 
~105):

  \{code:java|title=AS2AsyncMDNServerConnection.java (Camel 4.18.0)}
  public RequestListenerThread(int port, SSLContext sslContext) throws 
IOException {
      setName(REQUEST_LISTENER_THREAD_NAME_PREFIX + port);
      // ...
      HttpProcessor httpProcessor = new DefaultHttpProcessor(new 
RequestValidateHost());  // <-- STRICT
      registry = new RequestHandlerRegistry<>();
      handler = new BasicHttpServerRequestHandler(registry);
      httpService = new HttpService(httpProcessor, handler);
  }
  \{code}

  But in \{{AS2ServerConnection.initProtocolProcessor()}} (line ~655):

  \{code:java|title=AS2ServerConnection.java (Camel 4.18.0)}
  protected HttpProcessor initProtocolProcessor(
          String as2Version, String originServer, String serverFqdn, String 
mdnMessageTemplate) {
      return HttpProcessorBuilder.create()
              .addFirst(new AS2ConsumerConfigInterceptor())
              .add(new ResponseContent(true))
              .add(new ResponseServer(originServer))
              .add(new ResponseDate())
              .add(new ResponseConnControl())
              .add(new ResponseMDN(as2Version, serverFqdn, mdnMessageTemplate))
              .build();                                                         
 // <-- NO RequestValidateHost
  }
  \{code}

  The main AS2 server uses \{{HttpProcessorBuilder}} with response interceptors 
only — no \{{RequestValidateHost}}. The async MDN server uses 
\{{DefaultHttpProcessor}} with only \{{RequestValidateHost}} and no response 
interceptors at all.

  h3. Impact

  - Partners that send async MDNs with a \{{Host}} header that doesn't match 
the server's configured hostname get HTTP 421 "Not authoritative"
  - This is common in production environments with load balancers, reverse 
proxies, or NAT where the external hostname differs from the internal one
  - The sender thinks the MDN delivery failed and may retry or flag the 
transmission as unconfirmed
  - Meanwhile, the original AS2 message was received successfully (because 
\{{AS2ServerConnection}} has no host validation)

  h3. Steps to Reproduce

  Configure a Camel AS2 server with async MDN enabled on a separate port

  Have a partner send an AS2 message requesting async MDN delivery

  Partner sends the async MDN to the callback URL

  If the \{{Host}} header in the MDN request doesn't exactly match the server's 
hostname: HTTP 421 "Not authoritative"

  This is easy to trigger in environments with:
  - Load balancers or reverse proxies (external hostname differs from internal)
  - Docker/Kubernetes (container hostname differs from service hostname)
  - NAT configurations
  - Partners that set \{{Host}} header to the IP address instead of the hostname

  h3. Proposed Fix

  Remove \{{RequestValidateHost}} from the async MDN server and add the same 
response interceptors as the main AS2 server:

  \{code:diff|title=Fix in AS2AsyncMDNServerConnection.java}
   public RequestListenerThread(int port, SSLContext sslContext) throws 
IOException {
       setName(REQUEST_LISTENER_THREAD_NAME_PREFIX + port);
       // ...
  - HttpProcessor httpProcessor = new DefaultHttpProcessor(new 
RequestValidateHost());
  - HttpProcessor httpProcessor = HttpProcessorBuilder.create()
         .add(new ResponseContent(true))
         .add(new ResponseDate())
         .add(new ResponseServer(null))
         .add(new ResponseConnControl())
         .build();
  -    registry = new RequestHandlerRegistry<>();
     handler = new BasicHttpServerRequestHandler(registry);
     httpService = new HttpService(httpProcessor, handler);
   }
  \{code}

  This makes the async MDN receiver consistent with the main AS2 receiver:
  - No strict host validation (same as \{{AS2ServerConnection}})
  - Standard response interceptors are added (\{{ResponseContent}}, 
\{{ResponseDate}}, etc.) — the current code has none, which means async MDN 
responses may also be missing standard HTTP headers

  h3. Additional Issue: Missing Response Interceptors

  Note that the current \{{AS2AsyncMDNServerConnection}} creates the 
HttpProcessor with only \{{RequestValidateHost}} and no response interceptors:

  \{code:java}
  HttpProcessor httpProcessor = new DefaultHttpProcessor(new 
RequestValidateHost());
  \{code}

  This means HTTP responses from the async MDN receiver may be missing standard 
headers like \{{Content-Length}}, \{{Date}}, and \{{Connection}}. The proposed 
fix addresses both issues.

  h3. Our Workaround

  We use reflection after endpoint initialization to replace the 
\{{HttpProcessor}} on the async MDN server's \{{HttpService}} with a permissive 
processor built via \{{HttpProcessorBuilder}} (with standard response 
interceptors but no \{{RequestValidateHost}}).

  h3. Test Scenario

  Tested with OpenAS2 sending async MDNs.

  Before fix: Async MDNs rejected with HTTP 421 when Host header doesn't match.
  After replacing HttpProcessor: Async MDNs accepted regardless of Host header 
value.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to