DoS isn't just downtime. It's a skeleton key for fail-open

The server was up. It answered pings, monitoring was green, load was normal. Except its EDR agent had been dead for six months, because MySQL binlogs had quietly filled the system partition to zero. From the dashboard's point of view, everything was fine. The server was “alive” - only its single eye had been gouged out.
This is not a story about downtime. The outage didn't “take anything down” in the sense we usually mean by DoS. It flipped a security control into a state where the attacker could do whatever they wanted, without a single alert.
And that is the point. A Denial of Service vulnerability is rarely the goal in itself. More often it is the tool you use to force a system into an unprotected state - fail-open. If you exclude DoS from testing, you are not just skipping “availability”. You are leaving one question untested: what does your infrastructure do the moment one block falls over?
Why everyone excludes DoS (and why that's understandable)
Let me be blunt: we exclude DoS from scope by default too. In production, nobody wants a security audit to knock over the order system on a Friday afternoon. That's sensible caution. The client sleeps well, the environment stays up, everyone's happy.
The problem is what we exclude along with it. We don't check how the application behaves during a failure. On top of that comes a second, convenient belief: “the attacker wants data anyway, not a bogged-down server.” Sounds smart. It's wrong. A modern attacker doesn't need to craft an elegant exploit if they can simply crash a component that, at the moment of failure, passes traffic through by default instead of blocking it.
Case 1: the CMS that “forgot” it was installed after the database failed
We once ran into a popular CMS in a configuration that, with no database connection, decided the installation had never happened. Sounds harmless, until you pair it with the file-upload mechanism.
We flooded the server with requests until the database stopped answering. At that point the application politely showed us the installation wizard. It was downhill from there. The wizard displayed the credentials from the config file, let us attach our own external database, and finish the “installation” on a live server. The result: an administrator account. From there, uploading a plugin with a PHP file, and we have remote code execution on the machine.
An example attack flow (conceptually):
GET /index.php HTTP/1.1 Host: target-cms.com # System próbuje łączyć się z DB -> Timeout/DoS -> is_blog_installed() returns FALSE # Serwer zwraca stronę instalacyjną zamiast błędu 500
Publicly, the same mechanism shows up in WordPress (CVE-2020-28037, versions before 5.5.2). On error, is_blog_installed() could return “no, I'm not installed,” which opened the wizard and the road to RCE. MITRE classifies this as CWE-754, improper handling of an exceptional condition. A pretty name for “we didn't check what happens when the database goes down.”
Case 2: the EDR that a full disk killed
This one isn't a pentest, it's incident response. Attackers rarely try to punch through a modern EDR head-on. It's far more convenient to make it quietly stop working, so the administrator never sees a single alert.
We already covered the outage itself at the top. Let me add a detail I skipped: the agent didn't just die. It hung during a routine attempt to refresh its connection to the central console, because the full partition had no room left for temporary files and logs. The server was blind for six months. Worse, once space was freed, the process didn't come back on its own. You buy an expensive EDR, you deploy a SIEM, you paint your dashboard green... and a single unmonitored partition disarms you.
This isn't exotic. It's a classic integration failure.
Unit tests lie, integration tests tell the truth
All these cases share one thing. Each block works correctly on its own. Only their interaction during a failure creates the hole.
A unit test checks whether connect_to_db() returns an error when the database is silent. It does. Green. An integration test asks what the whole system does when that function returns an error right as someone loads the home page. And it turns out the system opens the installer.
There's a well-known meme about kitchen drawers. Each one slides out perfectly on its own. Except they block each other, and you can't open any of them. Unit tests passed, integration test failed. In security it looks exactly the same, only instead of a stuck drawer you get an open door.
Fail-open is everywhere, not just in CMSes
The “if it fails, let it through” pattern sits in many layers of defense. That's what makes DoS such a convenient tool.
In January 2026 it came to light that for a while Cloudflare's WAF could be bypassed via the /.well-known/acme-challenge/ path. The ACME certificate logic disabled WAF inspection for requests matching that path, so it wouldn't block certificate renewals. You could pack a malicious payload into such a request and hit the origin directly, skipping the entire perimeter. Textbook fail-open. Cloudflare fixed the flaw back in October 2025, but the example stands.
The same logic applies to MFA. Many companies roll out FIDO keys while leaving a weaker fallback “just in case”: an SMS code or an app. In an adversary-in-the-middle attack, the attacker can convince the victim's browser that the FIDO server is unavailable. The browser, in the name of user convenience, downgrades to the weaker method on its own. The most secure standard drops to the level of SMS phishing, because someone designed the fallback to kick in without asking.
A few cases and well-known patterns where the failure of one element lets the attacker in:
What to do about it (advice for CISOs and CTOs)
This whole problem has a name in the CWE catalog. It's CWE-636, “Not Failing Securely.” The principle isn't new, you just have to stick to it.
- Design security components so that on failure they reject traffic. The default state after an error should read “deny,” not “allow.”
- Extend the pentest with a controlled DoS on staging. This isn't about knocking over production, it's about triggering a failure on purpose (cut off the database, fill the disk) and checking whether an install wizard or a dead agent shows up.
- Treat a disk-full alert on a machine running EDR or SIEM as critical. No space there switches off your visibility across the network, not just your log writes.
- If you use FIDO, require extra identity verification before downgrading to a weaker method. The fallback must not turn itself on at the first communication error.
- Ask your developers point-blank: what does authorization do if this specific microservice stops responding for 30 seconds? If the answer is “I don't know,” you've got a topic for the next sprint.
The most interesting things in security happen not when everything works, but when something breaks. If you think about those states before an attacker does it for you, you're in the minority that sleeps well for a reason, not in spite of everything.
So a closing question: when did someone last check, not whether your system goes down, but what the rest of your defenses do the moment one of them falls over?
We call it a controlled DoS on staging. Book a free consultation: we'll show you how to trigger a failure safely and check whether your controls block traffic by default instead of letting it through.