Skip to main content
emnode
Compliance Low severity MCSB PV-2

Microsoft Defender for Cloud · Azure Functions

CORS should not allow every resource to access Function Apps

Written and reviewed by Emnode · Last reviewed

What does the recommendation "CORS should not allow every resource to access Function Apps" check?

Flags any function app whose Cross-Origin Resource Sharing allowed origins list contains the wildcard '*', meaning a browser script on any website can issue cross-origin requests to your HTTP-triggered functions. It inspects the function app's CORS configuration only, the allowedOrigins array under the app's web configuration. It does not check the allowed origins on a deployment slot separately from production, does not evaluate whether 'support credentials' is enabled, and does not flag a long but explicit origins list. It also says nothing about authentication, IP or virtual-network restrictions, or what the function code itself does with a request once the browser has allowed it through.

Why does "CORS should not allow every resource to access Function Apps" matter?

CORS is a browser-enforced control, so a wildcard origin tells every browser that scripts from any site may read your function's responses. If a function returns data the caller is authorised to see through a cookie or bearer token, a malicious page the victim visits can call the endpoint in their existing session and read back the response. For an internal reporting API, an admin console, or a webhook handler that leaks order or account status, that is a quiet data-disclosure path that crosses no firewall, triggers no failed login, and leaves no obvious trace in access logs. The business consequence is the same as any silent exfiltration: personal or commercial data leaves through a trusted endpoint, and you usually learn about it from someone else. Restricting origins to the handful of front ends that actually call the app shrinks that surface to almost nothing without changing a single line of function code or touching your authentication design.

How do I fix "CORS should not allow every resource to access Function Apps"?

  1. Inspect the current allowed origins with 'az functionapp cors show --name <app> --resource-group <rg>'. If you see '*', it permits every origin.
  2. Remove the wildcard and add only the exact front-end origins you trust: 'az functionapp cors remove --name <app> --resource-group <rg> --allowed-origins "*"' then 'az functionapp cors add --name <app> --resource-group <rg> --allowed-origins https://app.contoso.com'. Repeat the add for each legitimate origin, including the scheme and any non-default port.
  3. Enforce it going forward with the built-in policy 'Function apps should not have CORS configured to allow every resource to access your apps'. Look the definition up by name rather than hardcoding its GUID: pid=$(az policy definition list --query "[?displayName=='Function apps should not have CORS configured to allow every resource to access your apps'].name" -o tsv); az policy assignment create --name funcapp-cors --policy "$pid" --scope <scope>.

Remediation script · bash

# Close the highest-impact Function app exposure first: wildcard CORS, remote
# debugging, weak TLS, and missing client certificates, app by app.
RG=my-rg
APP=ordersapiprod

# 1. Replace wildcard CORS with the origins that actually call the app.
az functionapp cors remove -g "$RG" -n "$APP" --allowed-origins "*"
az functionapp cors add    -g "$RG" -n "$APP" \
  --allowed-origins https://app.contoso.com https://admin.contoso.com

# 2. Turn off remote debugging and require modern TLS.
az functionapp config set -g "$RG" -n "$APP" \
  --remote-debugging-enabled false \
  --min-tls-version 1.2

# 3. Require incoming client certificates where the app expects them.
az functionapp update -g "$RG" -n "$APP" \
  --set clientCertEnabled=true --set clientCertMode=Required

# 4. Put App Service Authentication (Easy Auth) in front of an HTTP-triggered app
#    so anonymous callers are rejected before they reach your code.
az webapp auth update -g "$RG" -n "$APP" \
  --enabled true \
  --action LoginWithAzureActiveDirectory \
  --aad-client-id "$CLIENT_ID" \
  --aad-token-issuer-url "https://sts.windows.net/$TENANT_ID/"

# 5. Ratchet it shut: audit any future app that ships without authentication.
#    Look the built-in policy up by its exact display name, never hardcode the GUID.
pid=$(az policy definition list \
  --query "[?displayName=='Function apps should have authentication enabled'].name" -o tsv)
az policy assignment create \
  --name audit-funcapp-auth \
  --policy "$pid" \
  --scope "/subscriptions/00000000-0000-0000-0000-000000000000"

Full walkthrough (console steps, edge cases and verification) in the lesson Harden Azure Function apps.

Is "CORS should not allow every resource to access Function Apps" a false positive?

A genuinely public, anonymous, read-only function, for example one serving a static configuration blob with no per-user data and no credentialed responses, can legitimately keep '*'. In that case the wildcard is the intended design, not a leak, so suppress the finding with a documented exemption rather than narrowing origins you do not actually need to restrict.