mahdignb
mahdignb

Reputation: 1

Kestrel throws "400 Bad Request: Invalid Target" for URLs with non-ASCII characters when using NGINX as reverse proxy

I am currently migrating a project from IIS to NGINX, and I’m encountering an issue when handling URLs that contain non-ASCII characters. Previously, on IIS, URLs with non-ASCII characters worked fine. Now, with my new setup, NGINX is proxying requests to a Kestrel server. However, when I try to access URLs containing non-ASCII characters (e.g., Cyrillic or accented characters), Kestrel throws a 400 Bad Request: Invalid Target error.

Here's the key part of my NGINX configuration:

location / {
    proxy_pass http://127.0.0.1:8092;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_cache_bypass $http_upgrade;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

How can I modify the URL (particularly encoding the non-ASCII characters) before passing it to Kestrel in a way that Kestrel can process it without throwing the 400 Bad Request: Invalid Target error? I would prefer to handle this in NGINX without altering proxy_pass or other things that is better than this

I cannot modify the calling URLs. Kestrel processes the request before any middleware runs, so I cannot fix the URL at the application level. Kestrel throws a 400 Bad Request: Invalid Target error when the URL contains non-ASCII characters.

I also tried access_by_lua_block but it didnt worked and uri that is going to my application was not changing.

location / {
    access_by_lua_block {
        -- Function to escape only the query string
        local function escape_query_string(uri)
            -- Split the URI into path and query string
            local path, query = uri:match("([^?]*)%?(.*)")
            if not query then
                ngx.log(ngx.ERR, "No query string found in URI.")
                return uri -- No query string to escape
            end

            -- Escape the query string
            local escaped_query = ngx.escape_uri(query)

            -- Recombine the path and escaped query string
            return path .. "?" .. escaped_query
        end

        -- Get the original URI
        local original_uri = ngx.var.request_uri
        ngx.log(ngx.ERR, "Original URI: ", original_uri)

        -- Escape only the query string
        local escaped_uri = escape_query_string(original_uri)
        ngx.log(ngx.ERR, "Escaped URI: ", escaped_uri)

        -- Set the URI to the escaped version
        ngx.req.set_uri(escaped_uri)
        ngx.log(ngx.ERR, "URI set to: ", ngx.var.request_uri)
    }

    proxy_pass http://127.0.0.1:8092;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_cache_bypass $http_upgrade;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Upvotes: 0

Views: 78

Answers (0)

Related Questions