I’ve been working with WAF rules from OWASP ModSecurity recently and I’m honestly a little worried about it. It seems geared towards “securing” the worlds worst PHP app, but any reasonably good framework and infrastructure will weed out most of what these rules seem to be there to protect against, leading to silly false positives that become a whole lot less silly when it’s Big Customer whose requests are blocked. What do I know though, I’m just the guy who was told we need this. This isn’t advice against using preconfigured WAF rules, just my honest (and I’m sure naive) first impression
Yes. ModSecurity is best used as a tool for virtual patching, meaning something you can use to create a temporary defence for a problem you know you have. That buys you some time until the problem is fixed.
When you're writing a virtual patch you know exactly what data you're dealing with and you can allow through only what's known to be good. Any other approaches (e.g., generic rules) deal with text in bulk and are prone to false positives.
Oh yeah I can see the place for it, thanks for filling in that context, and only on HN would the original author of ModSecurity see my comment about it haha!
For my context, I’m coming from a place of adding it to very new deployments, where the needs are constantly changing, which is why it feels a bit square-peg-round-hole I think.
I'm in exactly the same boat, and I 100% agree. The OWASP ModSec rules are insanely naive, and generally your only option when you run into false positives will be to disable the rule altogether.
I think ideally you'd want to use the rules to create some kind of temporal risk score for a given IP / client. Eg, if a single IP hits your service several times in 5 minutes with suspicious requests, then you block the request. But this isn't possible so you basically have to ensure all your rules are only looking for the most obvious and suspicious requests, otherwise you're going to get far too many false positives.
The only argument I could make in favour of using it is a lot of attacks these days are automated and therefore are quite naive because they're simply poking around for holes.
I've seen legitimate ecommerce transactions blocked because WAF rejected the customer's address containing the word "Union" (which is also an SQL keyword.)
I know of at least one Azure Application Gateway (which is a WAF) where the company-wide policy is to enable all the Rules, even the ones Microsoft says not to enable.
This results in fun debugging sessions for issues, where random requests are blocked, also often redirects from Azure AD logins where it apparently triggers on the JWT token.
That there is still a market for "security as an afterthought" is bothersome.
All additions to a system inherently increase risk and require thoughtful alterations to existing preventative maintenance and disaster recovery planning, but the price of these products and their attendant marketing often leave no room for this to actually occur.
Personally I feel a bit insulted that security can mandate a “tool” like this to “prevent” sql injections. Just because they are clowns doesn’t mean that we are.
Sorry users, the string “a > b” is not allowed any more. But fear not, “å > b” works just fine
The attacker would also have to bypass the WAF while posting the trigger string, so perhaps it’s not trivial. Still, the whole design of these heuristic WAFs feel quite weak.
Preventing users from submitting things that look like error messages sounds like a good idea until you stop a user from using your contact form to submit an error message that they just actually encountered on your website (because your WAF is set up incorrectly).
This is just plain wrong. A WAF rule meant to prevent credit card numbers from being output would not block the server from accepting credit card numbers. Or social security numbers, or any other kind of sensitive data. That would be wild.
Blocking responses based on the content returned is pretty silly in the first place, but the whole point is to prevent the data from leaving, not from coming in. In fact the whole reason the rules exist is to prevent the case where your database starts burping up data you don't want it to. But if you were blocking the data from being accepted in the first place you wouldn't have that data in your database to begin with.
> But if you were blocking the data from being accepted in the first place you wouldn't have that data in your database to begin with.
I mean, many of these dumb mistakes that someone would want their WAF to save them from, wouldn't be for leaks of user-provided PII, but rather for leaks of ops-provided secrets (e.g. connection credentials for upstream APIs), no?
I think I'd expect it to block responses containing anything matching the syntax of any ops secret.
A bit like how Github's partner leaked-secret scanning system works (where each company concerned with credential leaks, registers with Github the syntax of the credentials they issue as a regex pattern — and then Github webhooks the relevant company whenever one of their issued credentials makes it into a commit on any public repo, so that they can invalidate that secret before some attacker scrapes it out of the repo and plugs it into their botnet.)
But rather than the credential issuers registering their secret formats with the WAF, instead it'd just be your ops team telling the WAF the general-form regexes for each type of secret your team is actually using in prod. (Which might be a bit hard to determine from an ops team's position, as they may not have too many examples of a given type of secret — but it's usually a safe bet that your secret is just a concatenation of constant string parts with fixed-length baseN-alphabet parts. So in practice it's mostly just a matter of recognizing what N is [and maybe the variant alphabet in use, in the case of e.g. base32.])
> This is just plain wrong. A WAF rule meant to prevent credit card numbers from being output would not block the server from accepting credit card numbers
Until you have any kind of JS code where the contents of an input box are round-tripped, so that the user enters a number and then either the interface brake so it starts getting blanked out against their will.
It would seem Little Bobby Tables¹ now has a cousin, Denny DeDOS.
I have worked with such filters at some point earlier in life and had completely forgotten about them. This article brought back weird memories. It seemed like a good idea at the time. I think.