Skip to content

Avoid wildcards in APIM CORS policies#

Security · API Management · Rule · 2023_03 · Important

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 propeties.
  • 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:

API Management 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:

Azure Template snippet
{
  "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:

Azure Bicep snippet
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.

Comments