Protect background API in Azure API management

There are many articles about how to protect an API in Azure API management. Most of them target the API in the API management itself. So for example I imported an API (see Introduction to API management part 1) and can now access them via: https://codehollowtestapi.azure-api.net/simpleapi. After the creation, I secured the API (in API management service) with Azure Active Directory Introduction to Azure API management (part 2). Everything’s fine, but what about the API that is running in the background? In my case the webservice URL of the backend service is: https://codehollowsimpleapi.azurewebsites.net/
This service was public available (and easily accessible via Swagger – you’re welcome ;)). Sure, you need to know the URL, but if you know it, then you can easily use it and spam my API. All my efforts in building up an API management were useless.

20161010_06_apimanagement

A more common scenario is, that you have an existing API for your users, applications or for your internal developers. After some time and growth, you introduce the API management service. You tell your customers to switch to the new APIs and two weeks later you want to “turn off” the original API (the real webservice in the background). You will immediately face the question – how to protect an existing API that is running in the background and that is called by the API management service? And how to do it without any additional costs?

20161010_01_backgroundapiaccess

How to protect the background API?

There are a few ways to protect the background API. You can simply create a new, unreadable URL and migrate your service to the new URL. It’s okay, but not really secure. Another way is to protect your API e.g. with HTTP basic authentication and let the API management authenticate to your background API by using policies.
The simplest way in my opinion is to restrict the calls to your background API to the IP of the API management service.

20161010_02_backgroundapiipfilter

The IP filter is configurable in the web.config. So you don’t need to create an app gateway including a web application firewall (WAF). You also don’t need to put your app service into a virtual network and connect the API management with the backend. It’s a simple configuration in the web.config. If you want, you can modify it directly in Azure by modifying the web.config with the app service editor. Just extend the config by:

<system.webServer>
  <security>
    <!-- IP Whitelist-->
    <ipSecurity allowUnlisted="false" denyAction="Forbidden">
      <!-- denyActions: "AbortRequest", "Unauthorized", "Forbidden" (default), "NotFound" -->
      <clear />
      <add ipAddress="127.0.0.1" allowed="true" />
      <!-- azure api management -->
      <add ipAddress="[API Management IP]" allowed="true"/>
    </ipSecurity>
  </security>
</system.webServer>

I added the localhost IP so that we can still debug and test the API on our development machines. If you change the web.config in your Visual Studio project and you try to run the application, you will receive the following error:

in .net Core:
Unable to start process C:\Program Files\dotnet\dotnet.exe. The web server request failed with status code 500, Internal Server Error. The full response has been written to C:\Users\…\AppData\Local\Temp\HttpFailure 01-04-48.html.

in .net 4.5 and others you’ll receive an internal server error with the following information in “config error”:
This configuration section cannot be used at this path. This happens when the section is locked at a parent level. Locking is either by default (overrideModeDefault=”Deny”), or set explicitly by a location tag with overrideMode=”Deny” or the legacy allowOverride=”false”.

This can fixed by modifying the …\VisualStudioProjectFolder\.vs\config\applicationhost.config file. Simply replace:

<!-- replace -->
<section name="ipSecurity" overrideModeDefault="Deny" />
<!-- by: -->
<section name="ipSecurity" overrideModeDefault="Allow" />

From now on, all users that access https://codehollowsimpleapi.azurewebsites.net/ receive the following message:
You do not have permission to view this directory or page.

How to get the IP of the API management service?

Go to the Azure portal (classic), select the API management service and go to the Dashboard:

20161010_03_apimanagementip

Directly change web.config with app service editor

If you want to change the security directly for your running API application, then you can use the app service editor for it. Just go to the Azure portal, select your web app and scroll down to the “Development Tools” section:

20161010_04_appserviceeditor
20161010_05_appserviceeditor

Scroll down to the web.config and insert the ipSecurity section into it:

Categories:

3 Responses

  1. Great article – This def. helps keep prying eyes away from our backend API without having to resort to ASE or WAF etc.

    • Many thanks for your feedback! Good to know where my posts are helpful to solve the issues of my readers.
      If you have anything to add or suggestions for blog posts/topics, please let me know.

  2. What will happen when Azure platform tries to ping the API app Service to check its health, that connection will also be refused right? how do you allow Azure backbone/platform to still allow connect to your service for health and monitoring purpose? have you tested it?

Leave a Reply

Your email address will not be published. Required fields are marked *

About
about armin

Armin Reiter
Blockchain/Web3, IT-Security & Azure
Vienna, Austria

Reiter ITS Logo

Cryptix Logo

Legal information