Developers Guide to Web Application Firewalls

Michael Buckbee

16 Nov 2023

Why a Developers Guide?

Most organizations only hire a dedicated security role once they're at dozens, if not hundreds, of engineers.

By default, this leaves the security of web applications in the hands of the development team.

  • A positive of this is that developers make the best security decisions as they're the ones who know the application inside and out.
  • A negative is that developers need tools and support to back them up and often don't know what to advocate for.

This article gives developers a mental framework for improving their web application securifty. It focuses on how to consider Web Application Firewalls as they are far and away the number one category of security tool used to defend web apps from attack.

What's a Web Application Firewall (WAF)?

Frustratingly, the spectrum of what people call a WAF goes from "paste these dozen commands into your .htaccess" file to massive global networks of interconnected data centers that proxy all of your traffic.

This makes answering questions like "Should we use a WAF?" or even "Don't we already have a WAF?" difficult to answer, as it's incredibly easy to either make assumptions or talk past each other.

Why add a WAF to your application stack?

If you're reading this and thinking: "Well, we've survived this far without a WAF, why should we add one now?" There are three main reasons most developers add a WAF to their application stack:

  1. You're under attack (DDos or credential stuffing)
  2. You need the WAF for compliance reasons (SOC II, PCI, HIPAA, GDPR, etc.)
  3. You looked in your logs and were horrified by the volume, variety, and sheer weirdness of the requests they contained.

This last category is the most common as it's a catch-all for hundreds of different, more niche reasons like absurd levels of bot traffic, unending vulnerability scanners, or just a general sense of unease at the state of the internet.

firewall.webp

Our industry is in a weird state where if we described the process to an outsider, they'd be horrified.

Consider if the following question came from your CFO, an investor, or a customer:

Question: "So you looked in our webserver's logs, saw that every day there were thousands of probes and exploitation attempts against the server and you didn't do anything about it?"

Answer: "Well, most of the requests were looking for Wordpress paths, and we don't use Wordpress, so we figured it was fine."

Which is the standard way of handling things today. Most developers figure that they're not going to make a mistake that will allow an attacker to compromise their application, so they don't worry about it.

How does a WAF help this situation?

aka "What does a WAF actually do?"

The core feature of all WAFs is that they make it easier to block web requests.

In the prior sentence, "easier" is doing a lot of work, as you could theoretically handle much of what a WAF does in your web server or application framework.

The volume and ease of implementing the blocking rules are where theory smashes into reality. You might consider it reasonable to block a few dozen IP addresses in your web server, but it's functionally unworkable to tweak your web server config to block more advanced rules/requests like:

  • Threat blocking of things like SQLi, XSS, etc. (the type of things identified by the OWASP CRS)
  • GeoBlocking (hey, maybe we shouldn't do business with North Korea)
  • Reputational Blocking (hey, maybe this IP address from a known Eastern European malware host isn't innocently buying Steam Gift cards off our site)
  • RateLimiting/Throttling (hey, maybe we should limit requests to our free API by token)
  • Custom blocking rules based on request properties (IP, CIDR, User Agent, Paths, etc.)
  • Behavioral changes/anomalies (hey, is it weird that one IP is making 1000x the number of requests than average)
  • Virtual Patching (hey, this Log4j thing seems bad; can we block all attempts to submit text to the site that contains the string 'jndi' until we can patch our systems?)
  • Bot Management (hey, maybe we should block all requests that don't have a valid browser fingerprint)

Bottomline: WAFs aren't magic; they are just tools that make implementing some or all of these rules into your web application easier.

Threat Evaluation and Blocking Feedback Loop

Blocking is the easy part of a WAF. The hard part is figuring out what to block.

There's a feedback loop between:

  1. Your Web Application Firewall (WAF)
  2. Your Web Framework (e.g., Django, Rails, Express, Laravel etc.)
  3. Your Logging and Monitoring System (e.g., Papertrail, Coralogix, Splunk)

In traditional systems, even if you're lucky enough to have all the above in place, you still have to identify patterns in your logging system manually, turn around and export/copy those into your WAF, monitor for changes, and then rinse and repeat that process ad infinitum.

undefined

Wafris is designed to make this process easier by holding a sliding window (by default, the last 24 hours) of request data that you can interactively filter and review from which it becomes apparent what to block.

What exactly is protected?

A common critique of WAFs is that "we already do that" - an excellent example is SQL Injection (SQLi) protection.

The argument goes that a WAF is redundant since "we already use prepared statements" or "we already use an ORM," so a WAF is redundant.

These types of arguments only cover half the story. A better framework for considering this is splitting the security jobs (responsibilities) into Application and Operational categories.

Application Security

Web application security covers the code correctness side of the equation.

This includes SQL injection prevention, cross-site attacks, securely storing passwords, etc. Put another way, it's the "we already do that" side of the equation.

Generally speaking, if you can quickly test for it in your development environment, it's an application security issue.

Having multiple systems working to prevent SQLi (and other application attacks) is a good thing, as it means that if one system fails, you have another method that can catch the attack.

Developers are also (shockingly) human, and humans make mistakes. They sometimes check in extra files in their git commits, publicly store files they didn't realize were sensitive, or forget to do things under pressure.

A WAF provides a safety net for these easily made mistakes.

This layered architecture is formally called "Defense in Depth" and is a core concept of modern secure applications.

Further, it's important to note that application security is a moving target. New vulnerabilities are discovered daily, and having a WAF lets you react more quickly than the upgrade, test, and deploy cycle typically would.

undefined

Operational Security

Operational security covers the "how do we run this thing" side. This includes things like:

  • How do we know if we're under attack?
  • How do we block attacks?
  • How do we know if we're leaking data?
  • How do we rate limit signups?
  • How do we block bad bots?

Put another way, it's the "we don't already do that" side of the equation, which is why it's often overlooked.

An application vs. operational example

An excellent example of the difference between application and operational security is the recent 23andMe data breach:

  • Attackers used usernames and passwords stolen from other sites to log into 23andMe accounts
  • They then used the data export features of the site to exfiltrate individual account data
  • They recombined this data into a single large data set
  • They then sold this data set on the dark web

No vulnerabilities in the 23andMe application stack were exploited. Still, the attackers could exploit operational loopholes like the lack of behavioral detection, rate limiting, and bot detection to perform the attack.

undefined

To be 100% clear, this is not a criticism of 23andMe; many, if not most, significant services are vulnerable to these operational exploits. Their honest and open communications about the incident are a model for handling these types of attacks.

And bad news for the humans reading this: humans make mistakes.

So, yes, you may have a framework that does SQLi protection, but what if you have a legacy app that doesn't? Or what if you have a framework that does SQLi protection but includes a library that doesn't?

You need multiple layers of protection, and a WAF is one of those layers.

The three kinds of WAFs

WAFs fall into three categories: Ruleset, DNS Based, and In-App.

1. Ruleset WAFs

Rulesets WAFs have a very specific scope of functionality. They operate by applying a set of predefined rules (regexes) to HTTP requests. These rules identify and mitigate common web application vulnerabilities such as SQL injection, cross-site scripting (XSS), and remote file inclusion (RFI).

This is a big step up from not having any protection, but they squarely cover existing application framework security features and by design don't provide any operational security functionality. For example, they don't provide any way to block an IP address or rate limit requests.

Further, it can be tricky to handle both false positives (legitimate requests that are blocked by the WAF) and false negatives (new threats that have emerged since the ruleset was created).

Examples

The other forms of WAF are supersets of the functionality that ruleset WAFs provide.

2. DNS Based WAFs

DNS-based WAFs operate at the DNS level as a secure gateway for all incoming traffic to your web application. They work by routing incoming traffic through their network of servers and filtering out malicious requests based on various factors such as IP reputation, geolocation, and behavioral analysis. DNS-based WAFs are particularly effective at mitigating DDoS attacks, as they can absorb and distribute the traffic across their network.

They incorporate rulesets and some traffic analysis but are generally configured for all web applications and don't provide the same level of customization as in-app WAFs.

Examples:

The major downside to DNS-based WAFs is (predictably) DNS. Depending on the provider, they may require you to change your DNS provider, which can be a non-starter for many organizations.

undefined

It is also the case that all of your traffic will be routed through the WAF; while it's primarily transient this can still be a security issue for some organizations as it complicates compliance and auditing.

Expedited WAF (linked above) doesn't require you to give them full DNS control, only a single DNS record change.

3. In-App WAFs

In-app WAFs are integrated directly into your web framework or ingress application. Since they're local to your web application servers, they're typically much faster and provide higher customization and control than other types of WAFs. They can be tailored to your application's specific needs and characteristics, allowing for more precise and effective protection.

They offer modular rulesets that you can enable or disable as needed, and they can be configured to block requests based on various factors such as IP reputation, geolocation, and behavioral analysis.

undefined

Wafris is an in-app WAF that provides a simple, easy-to-use interface for creating and managing WAF rules and policies backed by Redis.

How to get started?

We are biased in thinking that every web app needs a WAF. This viewpoint stems from spending several years working with developers to protect sites actively under attack and seeing the difference a WAF can make.

Our frustrations with the existing WAFs on the market led us to build Wafris, the WAF of our dreams: a WAF made from the ground up to help developers protect their web applications.

Ready to secure your site?

Create a free Web Application Firewall today

Start blocking traffic in 4 minutes or less