Azure API Management is very powerful and you get a lot of functionality out of the box but leaking information can easily be overlooked.
There are several ways information can be leaked when configuring the Azure API Management. Setting up appropriate policies and using the right product subscription keys provide powerful ways to address these issues that are not obvious at first glance. Here is a typical response header list from API Management:
Pragma: no-cache Transfer-Encoding: chunked Host: echoapi.cloudapp.net Ocp-Apim-Subscription-Key: ******removed by me**** X-Forwarded-For: 126.96.36.199 Ocp-Apim-Trace-Location: https://apimgmtstggrqmwb9qliqj0i.blob.core.windows.net/apiinspectorcontainer/hilgmMCs8cs0digVzu3K-A2-2?sv=2015-07-08&sr=b********* Cache-Control: no-cache Date: Thu, 01 JAN 2017 12:59:38 GMT X-AspNet-Version: 4.0.30319 X-Powered-By: Azure API Management - http://api.azure.com/,ASP.NET Content-Type: application/xml Expires: -1
So the response headers is giving away quite a bit of information, like: my underlying API url is not an API Management subscriber’s concern. If I as a consumer know how to access that API directly, what is the API Management purpose? Also, to help out a malicious user, if you cannot access the domain.. the URL we talked before, there’s the direct IP for the underlying API. Also, the subscription key seems redundant but it’s not really a security concern. Last batch of headers simply spells out in clear english what server and application is running in the background there.
Adding the following policy at the Product level will secure all of the above. We’ll talk about the trace location separately.
<outbound> <set-header name="X-Forwarded-For" exists-action="delete" /> <set-header name="X-Powered-By" exists-action="delete" /> <set-header name="X-AspNet-Version" exists-action="delete" /> <set-header name="X-Frame-Options" exists-action="override"> <value>deny</value> </set-header> <set-header name="X-Content-Type-Options" exists-action="override"> <value>nosniff</value> </set-header> <set-header name="X-XSS-Protection" exists-action="override"> <value>1; mode=block</value> </set-header> <base /> </outbound>
The policy above results in a much cleaner and secure set of headers, yet we still see the trace location:
Pragma: no-cache Transfer-Encoding: chunked X-XSS-Protection: 1; mode=block X-Frame-Options: deny X-Content-Type-Options: nosniff Ocp-Apim-Trace-Location: https://apimgmtstggrqmwb9qliqj0i.blob.core.windows.net/apiinspectorcontainer/hilgmMCs8cs0digVzu3K-A2-3?sv=2015**** Cache-Control: no-cache Date: Thu, 01 Jan 2017 13:26:58 GMT Content-Type: application/xml
Ocp-Apim-Trace-Location is a special one. It’s true that it requires a specific header for the trace to generate and be shared to the location. Basically the request needs to include the
Ocp-Apim-Trace: truein the list of headers, but the result is that you could simply copy the trace location url returned and you would be presented with the entire detail of the underlying technology stack. it’s extremely powerful for debug purposes and it’s an easy to overlook issue.
In short, the trace location dump file is only available for Administrative Accounts subscriptions. If the subscription ID provided in the request is one of a lower level account, the trace URL will not be returned. Make sure that you share the subscribers a subscription ID of a developer account and your underlying technology will remain private.
IF you already shared the Administrator’s key, you can create a developer subscription .. generate new keys for the administrator and use Powershell or Azure CLI to update the developer subscription with the originally shared key, so that your subscribers are not impacted by the need to update applications that may already be in production.
Not using Certificate Validation
More a concern when the request is to authenticate the client. The client receives the connection to the server over Https and that is secured with an x509 certificate. When working with x509 certificates in Azure Api Management it is possible to accept an x509 certificate from the client call, lookup that certificate in a list of accepted certs and authenticate the client back. As a certificate thumprint can be reversed engineered, this method inconjunction with the API Key and the API Authentication method selected by the developer proves to be very secure. More than that, the API Management can present the client with a certificate while authenticating to the underlying API with a diferent one.