Mar 27, 2026 - For details about updated CVE-2025-53521 (BIG-IP APM vulnerability), refer to K000156741.

Forum Discussion

jomedusa's avatar
jomedusa
Icon for Cirrus rankCirrus
May 12, 2026

LTM Policy for HTTP Host rewrite

We have a policy to rewrite the http host from the original client request to what the backend servers are expecting in the host header.  I have noticed that I get a CORs error when going to a full swagger page.  Is there a way within the profile to rewrite the response header back to what the client originally requested.

 

Thanks,

 

Joe

1 Reply

  • Hi jomedusa​ ,

     

    LTM Policies are preferred when it meets all the criteria, but there are some limitations that require an iRule.  In  this case you might need to leverage a stream profile + iRule to handle the Swagger CORS issue.  You can opt for hybird LTM Policy + Irule but I don't like to mix these deployments as it created admin overheard and complexity.  BTW  check out our BIG-IP iRules Assistant Irules Assistant, this is what I used to help create and validate the iRule.  

    You will need a HTTP, Stream,  profile ( keep the src/target empty.  If your using a compression profile be aware that stream operations dont work on gzip HTTP bodies.

     

    when HTTP_REQUEST {
        # Preserve what the client asked for
        set client_host [HTTP::host]
    
        # Rewrite Host header to what backend expects
        HTTP::header replace Host "backend.internal.example.com"
    
        # Disable compression so STREAM can inspect the body
        HTTP::header remove "Accept-Encoding"
    
        # Default off; enable selectively on response
        STREAM::disable
    }
    
    when HTTP_RESPONSE {
        # Fix CORS allow-origin if backend echoes its own hostname/scheme
        if { [HTTP::header exists "Access-Control-Allow-Origin"] } {
            HTTP::header replace "Access-Control-Allow-Origin" "https://$client_host"
        }
    
        # Fix Location header on 3xx (or use HTTP profile Redirect Rewrite = Matching)
        if { [HTTP::header exists "Location"] } {
            HTTP::header replace Location \
                [string map "backend.internal.example.com $client_host" [HTTP::header Location]]
        }
    
        # Body rewrite: swagger.json, HTML, JS that reference the internal host
        switch -glob -- [string tolower [HTTP::header "Content-Type"]] {
            "application/json*" -
            "application/*+json*" -
            "text/html*" -
            "text/javascript*" -
            "application/javascript*" {
                STREAM::expression "@backend.internal.example.com@$client_host@"
                STREAM::enable
            }
        }
    }

    Here is what our AI Assistant calculated from the iRule above:

    1. Objective
      • Preserve the client’s original Host header for later use.
      • Rewrite the Host header to the internal backend hostname so the server sees what it expects.
      • Disable compression on the request so that the response body can be inspected and rewritten.
      • On the response, restore CORS and redirect headers to the client’s host and rewrite in-body references to match the original host.
    2. Execution Flow
      • HTTP_REQUEST
      – set client_host to the value of the incoming Host header (HTTP::host).
      – replace the Host header with “backend.internal.example.com” (HTTP::header replace Host).
      – remove the Accept-Encoding header to disable compression (HTTP::header remove "Accept-Encoding").
      – disable the stream filter by default (STREAM::disable).
    • HTTP_RESPONSE
      – if “Access-Control-Allow-Origin” exists, replace its value with “https://” (HTTP::header replace).
      – if “Location” exists, map any “backend.internal.example.com” in its value back to the original client_host (string map+HTTP::header replace).
      – inspect the Content-Type header; for JSON, HTML, or JavaScript types, set up a stream expression to rewrite in-body “backend.internal.example.com” to client_host (STREAM::expression) and enable the stream filter (STREAM::enable).

    Summary
    This iRule fronts an internal backend by swapping the Host header on requests and then, on the way back, transparently restoring client-facing host references in CORS, redirects, and body content for supported MIME types.