Attack Azure Logic App for SQL Injection and countermeasures

SQL Injection is one of the most dangerous attacks and we can exploit it in many Azure assets, App Services, APIs endpoints in general, Azure Functions, Logic App and more.
We can conduct the attack using different tools, I tried some of the most used like OWASP ZAP, BurpSuite, SQLMap, I am not going into the details about the differences I found, in this specific case, SQLMap has been the most effective.

For a quick refresh about SQL Injection, you can check below

We are now going to replicate a potential SQL Injection scenario using Logic App, we will create the laboratory and we will test the attack.

This is also a good opportunity to play with some Azure features, in this case, SQL Azure and Logic App, learning the technology is also the best way to understand the weaknesses.

I am assuming the reader has at least very basic knowledge about Azure, if not then I recommend you to read some blog post about it first.

Log in to the Azure Portal at https://portal.azure.com

Create the database

Enter in Create Resource Group named “LOGICAPP-PENTEST-RG1”, If you don’t have please create a resource group with this name.

  • Create SQL database
    • name: “logicapppentest”
    • username: “Sqladmin”
    • Password: “P@ssw0rd01”
  • select the resource group “LOGICAPP-PENTEST-RG1”
  • Server name “logicapppentestsrv”
  • Compute+storage Basic

  • Select the SQL Server database “logicapppentest”
  • and click on Server name

  • Click on Firewalls and virtual networks and insert the open IP Range as below

  • Go back in the database and select query Editor and log into the database using
    • Login: “sqladmin”
    • Password: “P@ssw0rd01”

Then copy the SQL query below in the database Query 1 window and click run, when complete click the refresh button

CREATE TABLE BookingTable (
    booking_id INT,
   first_name VARCHAR (50),
   last_name VARCHAR (50),
   phone VARCHAR(20),
   hotel_id INT
);

Copy the query below and execute in the query 1 window

INSERT INTO BookingTable (booking_id,first_name, last_name, phone, hotel_id) VALUES (0,'John', 'Smith', '123456789',3);

INSERT INTO BookingTable (booking_id,first_name, last_name, phone, hotel_id) VALUES (1,'Peter', 'Red', '123456789',4);

INSERT INTO BookingTable (booking_id,first_name, last_name, phone, hotel_id) VALUES (2,'Anna', 'Green', '123456789',5);

If you want to check the data then right-click on the table name and Select top 1000 Rows

Create a LogicApp

Go in LogicApp and create a new Logicapp named LogicAppSelectData

  • Select the existing LOGICAPP-PENTEST-RG1 resource group and click create

  • Select the Logicapp designer and select the template HTTP Request-Response

SQL Injection HTTP GET version

In the first HTTP shape, create a new parameter type Method and set GET

Add new shape type Execute a SQL query, select the active connection and set the database name as “logicapppentest”

Add the query below in the query parameter

select * from bookingtable where booking_id = @{triggerOutputs()['queries']['bookingid']}

Select the HTTP response and add Query Results in the Body

Save the Logic App

SQL Injection HTTP POST version

Copy the below Json context in the Request Body

{
    "properties": {
        "bookingid": {
            "type": "string"
        }
    },
    "type": "object"
}

  • Add new shape type Execute a SQL query, select the active connection and set the database name as “logicapppentest”

  • Add the query below in the query parameter

  • Select the HTTP response and add Query Results in the Body

Install Postman

Go to: https://www.getpostman.com/downloads/ and download and install POSTMAN

Test the Logic APP with Postman

Execute Postman and then:

  • Click on New>Request

  • Set “TesstLogicapp” in Request Name
  • Save the Logic App, create a collection LogicApp and Save

  • Go back to the Logic App flow and copy the URL POST Request

  • Go in Postman and set POST method and paste the URL

  • Select Body>raw and JSON type and copy and paste the JSON below into the body section
{
   "bookingid":"1"
}
  • Click Send and you should see the payload below

Test SQL Injection in the LogicApp via Postman

Add “;Select 1” at the end of the parameter and click send, you should have a response like below.

As you can see the attack has been achieved.

Test SQL Injection in the LogicApp via GET

Simply create a GET method, with no body and use the URL string only:

It is important to add the new parameter at the end:

  • &bookingid=1%3Bselect+1

Install SQLMap

If you are using a security distribution you will have SQLMap already installed and you can skip this step.

If you are a Windows user, you need to follow the steps below.

Install Python

Go to https://www.python.org/downloads/

  • Download and install the last version

  • Select Custom installation and next and select checkbox as below

  • Click Install

Install SQLMap

Go to http://sqlmap.org

  • Download the ZIP file

  • Unzip the file in c:\SQLMap

  • Move all content:
    • from: C:\SQLMap\sqlmapproject-sqlmap-9fd4a4f
    • to: c:\SQLMap

  • Enter in Command Prompt
  • Navigate in the folder c:\SQLMap and execute sqlmap.py

Attack the Logic App

Ok now we are going to attack the Logic App and I want to show you a very important aspect.

The tools we use to attack may have some weaknesses as well, during an attack it is very important to experiment with different things like for example a different combination of the parameters and any other technique, let see a practical scenario.

Copy the URL exposed by and add &bookingid=1 ad the end

The URL should be similar to the one below:

Execute the command below:

sqlmap.py -u "https://prod-104.westeurope.logic.azure.com:443/workflows/91e8825etert3c470/triggers/request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Frequest%2Frun&sv=1.0&sig=IQ5qe_nOzzt_vRPL6YqertXip1SVqeGiwzQ&bookingid=1" --dbs

Examine the result, in this case, no SQL injection detected and no WAF/IPS detected

Move the “bookingid” parameter in order to be the first parameter and execute the command again, the command line should similar as below

sqlmap.py -u "https://prod-104.westeurope.logic.azure.com:443/workflows/91e88253erterd3c470/triggers/request/paths/invoke?&bookingid=1&api-version=2016-10-01&sp=%2Ftriggers%2Frequest%2Frun&sv=1.0&sig=IQ5qe_nOzzt_vRPLert0eXip1SVqeGiwzQ" –dbs

Examine the result now:

As you can see the tool intercepted the SQL Injection, I tried using different other SQLMap options, but nothing changed.

I learn two important things here, SQLMap is the top one tool to test SQL Injection and never trust a security tool and experiment with everything.

The countermeasure

WAF or any other type of protection is not the proper way to solve this problem.
The proper countermeasure is using a stored procedure connector as below

Read the OWASP Cheat Sheet below to understand how to develop your stored procedure in the proper way:

Related blog posts