Details
I have an application running behind an Azure Web Application Firewall (WAF) on an Azure Application Gateway (AppGW) that was previously on an on-premises server. Since moving it to Azure, users and testers are now getting 403 Forbidden when attempting to send data to the service. I believe these are seen by the WAF as XSS or SQL Injection attacks, but I don't have a way to prove it.
So the question is, why are these requests being blocked by a WAF?
Note: These curl commands were generated by Postman. I took the JSON document and put it into a function.
Example callers:
#!/usr/bin/env bash
function json_document() {
cat <<EOF
{
"data": [
{
"code": "xxyyzz",
"codeType": "aaabbbccc",
"description": "some random string with >48 stuff, here"
}
],
"attributes": [
{
"vendorName": "a company",
"url": "https://my.company.com/app/SSO/",
"isDefault": true
}
]
}
EOF
}
/usr/bin/curl \
--location \
--request POST \
--url 'https://my.company.com/v1/csharp/app/resource' \
--header "Authorization: Bearer ${AUTH_PAT}" \
--header 'Content-Type: application/json' \
--data-raw "$(json_document)"
The above curl command works if I remove the >
and replace it with >
. Then the second example:
#!/usr/bin/env bash
function json_document() {
cat <<EOF
{
"name": "Item One (3 TIMES A DAY) (deferiprone) - Prior Authorization",
"attributes": [
{
"vendorName": "Vendor Name",
"url": "Vendor URL",
"isDefault": true
}
]
}
EOF
}
/usr/bin/curl \
--location \
--request POST \
--url 'https://my.company.com/v1/csharp/app/resource' \
--header "Authorization: Bearer ${AUTH_PAT}" \
--header 'Content-Type: application/json' \
--data-raw "$(json_document)"
The above works when we remove the DAY) (
portion or put it in a different spot in the string, which breaks some formatting rules later on.
Both of these get the following result:
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>Microsoft-Azure-Application-Gateway/v2</center>
</body>
</html>
Question
Why are these being blocked for seemingly innocent strings?
--data-raw
is not the right option, you should just the simple--data
. With that, your first request is passed. But the second one triggers an error:[id "933210"] [msg "PHP Injection Attack: Variable Function Call Found"] [data "Matched Data: (3 TIMES A DAY) (deferiprone) found within ARGS:name: Item One (3 TIMES A DAY) (deferiprone) - Prior Authorization"]