In my previous post I wanted to show by example how you can use the WAF rules with Frontdoor to protect your API from some potential exploits. In this follow up post I wanted to talk about the new preview Frontdoor SKU for Frontdoor Premium and show how it can use the more advanced Microsoft_DefaultRuleSet_2.0 or DSR2.0 preview rules which support richer inspection of request bodies. In the previous post one of the outcomes was that there were lots of things we could check but there were constraints to checking the request body. In the Premium Frontdoor SKU we can use WAF to check json message bodies now and I wanted to show how to do this.
If we remember to the previous post the architecture for our test looks like below and this time I am going to run all of the tests through a premium frontdoor and use a WAF with the Microsoft_DefaultRuleSet_2.0 configured.
To keep the post shorter I will not go through the tests which worked exactly the same as they did in the first post. I will instead focus on the tests which behave differently.
Tests
SQL Injection in plain text body should fail with 1=1 – Fail
In this test we will send a plain text message body with a sql injection attempt
Desired Behaviour | WAF will block the request |
Actual Behaviour | HTTP 200 returned and the request is not blocked |
Request:
PUT /echo/resource HTTP/1.1
Host: {mikeshost}
Ocp-Apim-Subscription-Key: {mikeskey}
Content-Type: text/plain
Content-Length: 46
SELECT * FROM Users WHERE UserId = 105 OR 1=1;
SQL Injection in Json body should fail with 1=1 – Pass
In this case we will use a json request and we will include a SQL injection attempt in the request body
Expected Behaviour | WAF will block the request |
Actual Behaviour | We get an HTTP 403 and the request is blocked |
Request:
PUT /echo/resource HTTP/1.1
Host: {mikeshost}
Ocp-Apim-Subscription-Key: {mikeskey}
Content-Type: application/json
Content-Length: 143
{
"vehicleType": "train",
"maxSpeed": 125,
"avgSpeed": 90,
"speedUnit": "SELECT * FROM Users WHERE UserId = 105 OR 1=1;"
}
XSS in Json body should fail – Pass
In this request we will add an XSS attempt to a json request and hope that WAF will block it.
Expected Behaviour | Blocked by WAF |
Actual Behaviour | We get an HTTP 403 and the request is blocked |
Request:
PUT /echo/resource HTTP/1.1
Host: {mikeshost}
Ocp-Apim-Subscription-Key: {mikeskey}
Content-Type: application/json
Content-Length: 149
{
"vehicleType": "train",
"maxSpeed": 125,
"avgSpeed": 90,
"speedUnit": "<script>alert(“This is a XSS Exploit Test”)</script>"
}
XSS in Json body should fail with big message 1
In this request we will use a bigger message in the request but also include an XSS attempt in it. We will add another parameter and it will have a long string in it. The overall request size will be bigger but less than 128kb.
Desired Behaviour | The request is blocked by WAF |
Actual Behaviour | We get an HTTP 403 and the request is blocked |
Request:
PUT /echo/resource HTTP/1.1
Host: {mikeshost}
Ocp-Apim-Subscription-Key: {mikeskey}
Content-Type: application/json
Content-Length: 754642
{
"vehicleType": "train",
"maxSpeed": 125,
"avgSpeed": 90,
"speedUnit": "<script>alert(“This is a XSS Exploit Test”)</script>",
"longString": "This is a very long string under 128kb"
}
XSS in Json body should fail with big message 2 – Pass
In request we have added a property to the json request which would have a very big string in it so the message is bigger. (Note ive truncated this down in the code snippet). We will send the request and hope that it is blocked.
Desired Behaviour | The request is blocked by WAF |
Actual Behaviour | We get an HTTP 403 and the request is blocked |
Request:
PUT /echo/resource HTTP/1.1
Host: {mikeshost}
Ocp-Apim-Subscription-Key: {mikeskey}
Content-Type: application/json
Content-Length: 754642
{
"vehicleType": "train",
"maxSpeed": 125,
"avgSpeed": 90,
"speedUnit": "<script>alert(“This is a XSS Exploit Test”)</script>",
"longString": "This is a very long string over 128kb"
}
XSS in Json body should fail with big message 3 – Fail
In this request we swap around the speedUnit and longString properties so that in the same message we now have the xss attempt further down the message. The Frontdoor & WAF rule will only check the first 128kb of the message body according to the documentation. In this test we are looking to see if the request is blocked or allowed through.
Desired Behaviour | The request is blocked by WAF |
Actual Behaviour | HTTP 200 and the request is not blocked and we get the request echo’d back |
Request:
PUT /echo/resource HTTP/1.1
Host: {mikeshost}
Ocp-Apim-Subscription-Key: {mikeskey}
Content-Type: application/json
Content-Length: 754642
{
"vehicleType": "train",
"maxSpeed": 125,
"avgSpeed": 90,
"longString": "This is a very long string well over 128kb",
"speedUnit": "<script>alert(“This is a XSS Exploit Test”)</script>"
}
Summary
When we review the outcome from these examples we can see that the Premium Frontdoor has added support for message body inspection for other request types. You can do application/json and application/xml which will be useful for API implementations. You could see above the text/plain test still allowed the request through but the others were now blocked where as previously they were not.
The other key learning here is that Frontdoor and WAF will only inspect a certain size of request body. I think the documentation said it was 128kb. This means bigger requests may not be blocked and you could see how I changed the order of the properties on the later tests which allowed one to not get blocked by WAF.
I hope this helps make it easier for people to get up and running checking your WAF rules are setup and working for you and helps to understand some of the constraints of what you can and cant do with the WAF rules. Remember defense in depth is important and while the WAF can allow you to off load some of the vulnerability checking it is the first line of defense and can reduce load on your code by checking stuff before it gets to your code but this should be an addition to writing secure code not as an alternative to it.
Postman
The postman collection I used with the premium frontdoor is below.