Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Feb 2, 2026

Why make this change?

POST to stored procedure/entity endpoints returns Location header with http:// scheme even when original request is HTTPS. This occurs behind reverse proxies (Azure API Management, Container Apps) where internal traffic uses HTTP but the X-Forwarded-Proto: https header is set.

What is this change?

Reuses existing SqlPaginationUtil.ResolveRequestScheme and ResolveRequestHost helpers (already used for pagination nextLink) in mutation handlers:

  • SqlPaginationUtil.cs: Changed privateinternal for ResolveRequestScheme, ResolveRequestHost, IsValidScheme, IsValidHost
  • SqlMutationEngine.cs: Use forwarded headers for stored procedure Location header
  • SqlResponseHelpers.cs: Use forwarded headers for entity Location header

Before:

POST https://my-app.azurecontainerapps.io/rest/SessionVote
→ Location: http://my-app.azurecontainerapps.io/rest/SessionVote  ❌

After:

POST https://my-app.azurecontainerapps.io/rest/SessionVote
→ Location: https://my-app.azurecontainerapps.io/rest/SessionVote  ✓

How was this tested?

  • Integration Tests
  • Unit Tests

Existing validation logic from pagination already handles header validation (scheme must be http/https, host validated for dangerous characters).

Sample Request(s)

POST /rest/MyStoredProcedure HTTP/1.1
Host: my-proxy.azure-api.net
X-Forwarded-Proto: https
X-Forwarded-Host: my-app.azurecontainerapps.io
Content-Type: application/json

{"param1": "value"}

Response now correctly includes:

HTTP/1.1 201 Created
Location: https://my-app.azurecontainerapps.io/rest/MyStoredProcedure
Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug]: POST to rest endpoint on https for stored proc returns a location header with insecure http scheme</issue_title>
<issue_description>### What happened?

A bug happened!

Posting to a stored procedure endpoint returns a location header that doesn't match the request incoming scheme. This results in errors on clients that don't allow insecure redirects.

The returned scheme should match the incoming scheme

POST https://<url>-api-stgwe.yellowfield-2df9f307.westeurope.azurecontainerapps.io/rest/SessionVote
201
259 ms
POST /dataapi-stg/rest/SessionVote HTTP/1.1
Content-Type: application/json
Authorization: Bearer 
User-Agent: PostmanRuntime/7.51.0
Accept: */*
Cache-Control: no-cache
Postman-Token: a2fadac6-067d-4a0b-8a5f-ba3b90d46ee8
Host: apim-sqlbits-api-management.azure-api.net
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 65
Cookie: acaAffinity="6ea9edfe43f98424"
 
{"SessionId":1232131,
"Email":"simon@asdsa.com",
"Vote":true
}
 
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Date: Mon, 22 Dec 2025 16:32:18 GMT
Cache-Control: private
Location: http://<url>-api-stgwe.yellowfield-2df9f307.westeurope.azurecontainerapps.io/rest/SessionVote
Transfer-Encoding: chunked
Strict-Transport-Security: max-age=31536000; includeSubDomains
x-ms-middleware-request-id: 42421e73-1ba6-496f-8dd7-88beee5a0489
x-ms-correlation-id: 5f147408-1cb2-40e9-b406-7dcac4fae555
Request-Context: appId=cid-v1:2845ea60-a09f-4c5c-9500-47f887b00b3a
 
{"value":[{"SessionId":123131},{"SessionId":1231231},{"SessionId":1232131}]}

Version

1.6.84

What database are you using?

Azure SQL

What hosting model are you using?

Container Apps

Which API approach are you accessing DAB through?

REST

Relevant log output


Code of Conduct

  • I agree to follow this project's Code of Conduct</issue_description>

<agent_instructions>Resolve this bug with as little code change as possible.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@JerryNixon ## Root Cause

The issue is in how DAB constructs the Location header for stored procedure POST requests. When building the location header URL, DAB is not properly respecting the incoming request's HTTPS scheme when behind a reverse proxy.

The Problem Code

Looking at SqlMutationEngine.cs for stored procedure handling:

HttpContext httpContext = GetHttpContext();
string locationHeaderURL = UriHelper.BuildAbsolute(
        scheme: httpContext.Request.Scheme,
        host: httpContext.Request.Host,
        pathBase: GetBaseRouteFromConfig(_runtimeConfigProvider.GetConfig()),
        path: httpContext.Request.Path);

The problem is that httpContext.Request.Scheme returns the scheme of the connection between the reverse proxy (Azure API Management) and the container app (HTTP), not the original client request scheme (HTTPS).

Why Regular Entity Inserts Work Better

Interestingly, for regular table/view POST operations, DAB uses SqlResponseHelpers.ConstructCreatedResultResponse(), which has the same issue:

locationHeaderURL = UriHelper.BuildAbsolute(
                    scheme: httpContext.Request.Scheme,
                    host: httpContext.Request.Host,
                    pathBase: baseRoute,
                    path: httpContext.Request.Path);

The Solution That Exists for Pagination

DAB already has the correct implementation for handling forwarded headers in the pagination utility (SqlPaginationUtil.cs):

public static string ConstructBaseUriForPagination(HttpContext httpContext, string? baseRoute = null)
{
    HttpRequest req = httpContext.Request;

    // use scheme from X-Forwarded-Proto or fallback to request scheme
    string scheme = ResolveRequestScheme(req);

    // Use host from X-Forwarded-Host or fallback to request host
    string host = ResolveRequestHost(req);
    
    return UriHelper.BuildAbsolute(
        scheme: scheme,
        host: new HostString(host),
        ...

The helper methods check for X-Forwarded-Proto and X-Forwarded-Host headers:

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes Azure/data-api-builder#3032

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.

… headers

Updated SqlMutationEngine.cs and SqlResponseHelpers.cs to use the
SqlPaginationUtil.ResolveRequestScheme and ResolveRequestHost methods
when constructing Location headers. This ensures that when behind a
reverse proxy (like Azure API Management), the Location header uses
the original client request scheme (HTTPS) instead of the internal
connection scheme (HTTP).

Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix insecure scheme in location header for stored proc Fix Location header to respect X-Forwarded-Proto and X-Forwarded-Host headers Feb 2, 2026
Copilot AI requested a review from JerryNixon February 2, 2026 23:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants