We recently configured our CDN and App Gateway for a new client using Coveo. Suddenly, Coveo stopped working. Not like “Oh man this is slow and sorta funky” but more of “Oh hey, literally nothing is working.” We were not having fun.
Looking at Dev Tools in Firefox, pretty much every request going to the Coveo rest API (/coveo/rest) was returning a 403, Forbidden. Going to the App Service directly was fine. It had always been fine. It’s how we passed QA for crying out loud! But going to the App Gateway through the CDN.. 403-a-plenty.
Obviously this wouldn’t do. After chatting with a coworker, I decided to check out the Firewall. First thing you should know about the Azure Gateway’s Firewalling. There’s a LOT of rules. You can read about every single one of them here: https://docs.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-crs-rulegroups-rules?tabs=owasp31 Ok, so yeah, there’s a lot. Which one do you turn off? Go one at a time and see when it starts working? What if it’s multiple rules? After all, your WAF adds up infractions and then if the score goes high enough, blocks the request. While fancy, this is a royal pain in the ass. So how do you go about figuring out which rule is borking your request? Turn on Diagnostics! Luckily, this is fairly straightforward. You simply go into the Gateway and click on Diagnostics. Add in a new Diagnostic Setting:
Ok, now that you’ve got your logging setup, you’re going to want to wait a few minutes (give it like 10 to be sure). Now is a great time for a cold beverage of the adult nature. Or not. Maybe tea is your deal.
Ok, now you’re logging is in place, you need to go trigger the error. Reload a page, start some autosuggest, whatever it takes to start seeing the 403s flood your beautiful site. Great. You’ve done something critical. You’ve failed. It’s a good fail though.
Now, head on over to the storage container you specified in the Diagnostic setup. You’ll see a new Container in place. Keep clicking that bugger until you get to a .json file. That file has your logs! You want this! Ok, now you’re going to want to pop that sucker open and view the JSON data. Note: each line is its own JSON object. This isn’t going to tidy nicely. So do a quick peruse over the file. You’ll see an “action” attribute in there with either a “Matched” or a “Blocked” value. Matching means it hit a criteria to accrue some points. Blocked is…you guess it: blocked. You don’t want blocked. You probably don’t even want matched. Here’s what it looks like:
Those two lines are from the same request. The Matched action (920480) gave the request enough points that it ended up getting blocked. So now that we understand the process, how do we go about tweaking things until they work? Well two things:
- I’m not your security team. Consult them or your client before you tweak a firewall. I’m not responsible for anything you do that lets the world hack your face off. Seriously ™.
- This is what worked for me. It may not work for you. Your mileage may vary.
Ok, so to turn off rules, you’ll want to go into your Firewall Profile: Click your Gateway -> Web application firewall -> Policy -> Managed Rules. Note: We are using OWASP 3.1 here. Different OWASP levels have different rules. This is what your rules screen looks like:
Clicking on any of those is going to show you the actual rules…
Check the box of the rule you want to turn off, and then scroll up and hit “Save” Now you should be able to test whether or not things got better. Run the test again, check your logs. It’s a little bit of a trial and error. To save you some time, I’ve put the list of rules that I’ve disabled below. Hopefully this helps save you some time!
|920480||Restrict charset parameter within the content-type header|
|942200||Detects MySQL comment-/space-obfuscated injections and backtick termination|
|942260||Detects basic SQL authentication bypass attempts 2/3|
|942330||Detects classic SQL injection probings 1/2|
|942340||Detects basic SQL authentication bypass attempts 3/3|
|942370||Detects classic SQL injection probings 2/2|
|942430||Restricted SQL Character Anomaly Detection (args): # of special characters exceeded (12)|
|932110||Remote Command Execution: Windows Command Injection|
|932115||Remote Command Execution: Windows Command Injection|
|933180||PHP Injection Attack: Variable Function Call Found|
|941160||NoScript XSS InjectionChecker: HTML Injection|
|941200||XSS using VML frames|
|941310||US-ASCII Malformed Encoding XSS Filter – Attack Detected.|
|941350||UTF-7 Encoding IE XSS – Attack Detected.|
|941330||IE XSS Filters – Attack Detected.|
|941340||IE XSS Filters – Attack Detected.|
|942120||SQL Injection Attack: SQL Operator Detected|
|942210||Detects chained SQL injection attempts 1/2|
So there it is. It feels a little dirty, but we’ve already sanitized all our database inputs, right? Would hate for little Bobby Tables to come along and wreck your day. Good luck and happy Sitecore and Coveo-ing!