Avoid wildcards in APIM CORS policies

March 21, 2025 ยท View on GitHub

SYNOPSIS

Avoid using wildcard for any configuration option in CORS policies.

DESCRIPTION

The API Management cors policy adds cross-origin resource sharing (CORS) support to an operation or APIs.

CORS is not a security feature. CORS is a W3C standard that allows a server to relax the same-origin policy enforced by modern browsers. CORS uses HTTP headers that allows API Management (and other HTTP servers) to indicate any allowed origins.

Using wildcard (*) in any policy is overly permissive and may reduce the effectiveness of browser same-origin policy enforcement.

RECOMMENDATION

Consider configuring the CORS policy by specifying explicit values for each property.

EXAMPLES

Configure API Management policy

To deploy API Management CORS policies that pass this rule:

  • When configuring cors policies provide the exact values for all properties.
  • Avoid using wildcards for any property of the cors policy including:
    • allowed-origins
    • allowed-methods
    • allowed-headers
    • expose-headers

For example a global scoped policy:

<policies>
  <inbound>
    <cors allow-credentials="true">
      <allowed-origins>
        <origin>https://contoso.developer.azure-api.net</origin>
        <origin>https://developer.contoso.com</origin>
      </allowed-origins>
      <allowed-methods preflight-result-max-age="300">
        <method>GET</method>
        <method>PUT</method>
        <method>POST</method>
        <method>PATCH</method>
        <method>HEAD</method>
        <method>DELETE</method>
        <method>OPTIONS</method>
      </allowed-methods>
      <allowed-headers>
        <header>Content-Type</header>
        <header>Cache-Control</header>
        <header>Authorization</header>
      </allowed-headers>
    </cors>
  </inbound>
  <backend>
    <forward-request />
  </backend>
  <outbound />
  <on-error />
</policies>

Configure with Azure template

To deploy API Management CORS policies that pass this rule:

  • Configure an policy sub-resource.
  • Avoid using wildcards * for any CORS policy element in properties.value property. Instead provide exact values.

For example a global scoped policy:

{
  "type": "Microsoft.ApiManagement/service/policies",
  "apiVersion": "2022-08-01",
  "name": "[format('{0}/{1}', parameters('name'), 'policy')]",
  "properties": {
    "value": "<policies><inbound><cors allow-credentials=\"true\"><allowed-origins><origin>https://contoso.developer.azure-api.net</origin><origin>https://developer.contoso.com</origin></allowed-origins><allowed-methods preflight-result-max-age=\"300\"><method>GET</method><method>PUT</method><method>POST</method><method>PATCH</method><method>HEAD</method><method>DELETE</method><method>OPTIONS</method></allowed-methods><allowed-headers><header>Content-Type</header><header>Cache-Control</header><header>Authorization</header></allowed-headers></cors></inbound><backend><forward-request /></backend><outbound /><on-error /></policies>",
    "format": "xml"
  },
  "dependsOn": [
    "[resourceId('Microsoft.ApiManagement/service', parameters('name'))]"
  ]
}

Configure with Bicep

To deploy API Management CORS policies that pass this rule:

  • Configure an policy sub-resource.
  • Avoid using wildcards * for any CORS policy element in properties.value property. Instead provide exact values.

For example a global scoped policy:

resource globalPolicy 'Microsoft.ApiManagement/service/policies@2022-08-01' = {
  parent: service
  name: 'policy'
  properties: {
    value: '<policies><inbound><cors allow-credentials="true"><allowed-origins><origin>https://contoso.developer.azure-api.net</origin><origin>https://developer.contoso.com</origin></allowed-origins><allowed-methods preflight-result-max-age="300"><method>GET</method><method>PUT</method><method>POST</method><method>PATCH</method><method>HEAD</method><method>DELETE</method><method>OPTIONS</method></allowed-methods><allowed-headers><header>Content-Type</header><header>Cache-Control</header><header>Authorization</header></allowed-headers></cors></inbound><backend><forward-request /></backend><outbound /><on-error /></policies>'
    format: 'xml'
  }
}

NOTES

The rule only checks against rawxml and xml policy formatted content.

When using Azure Bicep, the policy XML can be loaded from an external file by using the loadTextContent function.