Skip to content

[Bug] ASGI cookie conversion serializes an absent Domain attribute and breaks __Host- cookies #1902

Description

@jlowin

Expected Behavior

This surfaced in FastMCP issue #4748. FastMCP's OAuth consent flow emits a valid __Host- cookie, but when the application runs on Azure Functions, the browser receives a Domain attribute and rejects it.

Azure Functions should preserve the absence of Domain in this ASGI response:

Set-Cookie: __Host-test=value; Path=/; Secure; HttpOnly; SameSite=Lax

__Host- cookies require Secure, Path=/, and no Domain attribute.

Actual Behavior

The Python ASGI response path parses Set-Cookie into a structured cookie and serializes the missing domain as a present, empty domain. The final response contains domain= or surfaces the Function App hostname as its effective domain. Browsers therefore reject the __Host- cookie; in FastMCP this causes the consent POST's CSRF check to fail.

Steps to Reproduce

  1. Deploy the ASGI application below to Azure Functions.
  2. Request its HTTP endpoint over HTTPS.
  3. Inspect the final Set-Cookie header and the browser cookie warnings.
  4. Observe that the response includes a Domain attribute and the browser rejects __Host-test.

Relevant code being tried

import azure.functions as func


async def asgi_app(scope, receive, send):
    assert scope["type"] == "http"

    await send(
        {
            "type": "http.response.start",
            "status": 200,
            "headers": [
                (b"content-type", b"text/plain"),
                (
                    b"set-cookie",
                    b"__Host-test=value; Path=/; Secure; HttpOnly; SameSite=Lax",
                ),
            ],
        }
    )
    await send(
        {
            "type": "http.response.body",
            "body": b"ok",
            "more_body": False,
        }
    )


app = func.AsgiFunctionApp(
    app=asgi_app,
    http_auth_level=func.AuthLevel.ANONYMOUS,
)

Relevant log output

No application error is logged. The failure appears in the response header and browser cookie warning.

requirements.txt file

azure-functions==1.24.0

Where are you facing this problem?

Production Environment

Function app name

Not publicly shareable

Additional Information

azure-functions-python-library removes the raw header and parses it with SimpleCookie:
https://github.com/Azure/azure-functions-python-library/blob/dev/azure/functions/http.py#L113-L116

The worker then passes the empty cookie_entity['domain'] value to to_nullable_string, creating a present RPC domain:
https://github.com/Azure/azure-functions-python-worker/blob/dev/workers/azure_functions_worker/bindings/datumdef.py#L232-L245

The existing end-to-end test expects an attribute-free cookie to become foo=bar; domain=; path=:
https://github.com/Azure/azure-functions-python-worker/blob/dev/workers/tests/unittests/test_http_functions.py#L374-L379

A targeted fix would omit the RPC domain when cookie_entity['domain'] is empty while preserving explicit domains. A __Host- regression test can verify that the final response contains Path=/; Secure and no Domain.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions