Protocol attacks: exhausting connection state
Protocol attacks consume the memory that devices use to track connections, not the bandwidth that carries them. Every connection in progress occupies an entry in a table, and those tables are finite. Fill them and legitimate clients are refused, while the traffic graph shows nothing unusual.
Quick facts
- Layer
- Transport (4), sometimes network (3)
- Vector
- Connection attempts that are never completed
- Goal
- Fill connection tracking tables
- In your logs
- Connections in a half-open state; few or no requests
- Does a WAF stop it?
- No. No connection completes, so no request exists
The reason for that last row is the same one described on attack layers: request inspection needs a request, and here the attack succeeds precisely by never producing one.
How a connection consumes state
Opening a connection is a three-step exchange. The client asks, the server answers and waits, the client confirms. Between the second and third steps the server holds a half-open connection: memory allocated, an entry in a queue, a timer running.
That waiting state is the resource. It exists to tolerate slow networks, which means it must persist for a while before being discarded. An attacker who starts connections and never confirms them fills the queue with entries that will time out eventually and are useless in the meantime. New clients arrive, find no room, and are refused.
Two consequences follow, and both explain why this family is often misdiagnosed.
Bandwidth stays unremarkable. The packets involved are small. A connection attempt costs almost nothing to send and costs the recipient memory and a timer, which is an asymmetry the attacker is exploiting.
Everything in the path is a target. The server is not the only device tracking connections. Firewalls and load balancers maintain their own tables, and whichever has the smallest one fails first, sometimes taking down services that were not the intended target.
The vectors in this category
| Vector | Mechanism | Distinguishing property |
|---|---|---|
| SYN flood | Connection requests never completed | Half-open entries accumulate in the queue |
| ACK flood | Packets claiming to belong to sessions that do not exist | Forces a table lookup for every packet |
| RST flood | Reset packets against non-existent sessions | Same lookup cost, plus a risk to live sessions |
The second and third share a mechanism that is less intuitive than the first. A stateful device receiving a packet that claims to be part of an existing conversation must search its table to find that conversation. The search happens whether or not the session exists, so packets referring to nothing still cost processing. Here the resource being exhausted is lookup capacity rather than table space.
Recognising it
Three observations separate this family from the others.
The server is reachable but refuses connections. Processor usage is low, memory is fine, and yet new clients cannot connect. Nothing is overloaded in the ordinary sense: a table is full.
Connection counts are high while request counts are low. Application logs stay quiet because the requests that would have been logged never happened. Compare this with an application-layer flood, where logs fill.
Half-open connections dominate. Standard tooling on the server shows connections stuck in the intermediate state of the handshake, in numbers that do not correspond to any plausible user population.
Whose table filled first
Establish this first: the answer decides where any fix belongs.
If services unrelated to the one under attack also stop working, the device in front of them ran out of state first. A shared firewall or load balancer failing takes everything behind it, and the symptom of an attack on one site becomes an outage across several.
If only the targeted service is affected and the machine hosting it shows free memory and idle processors, the limit reached was the connection queue of that service rather than anything shared.
The distinction matters because tuning the wrong device changes nothing. Enlarging a queue on a server whose firewall is the bottleneck produces no improvement and hides the real constraint, which is the sort of change that gets made under pressure and never revisited.
Mitigation by layer
Four defences, in the order they usually apply.
Hold no state until the connection proves itself. Operating systems can answer a connection request without allocating memory, encoding what they need into the reply and reconstructing it when the client confirms. Legitimate clients complete the exchange and get their connection; attackers who never reply cost nothing. This mechanism is the direct answer to the largest vector in the category and is available on current systems.
Tune the queue and its timers. A larger queue and a shorter wait both reduce the window an attacker exploits, within limits: too short a timeout starts refusing genuinely slow clients, which is a real trade-off on mobile networks.
Filter upstream, statelessly. Devices that inspect packets without tracking sessions can drop malformed or clearly forged traffic without accumulating state themselves. Anything that tracks state to filter this attack is vulnerable to the attack it is filtering.
Terminate connections somewhere with capacity. Where connections are established at a provider's edge rather than at your server, their tables absorb the attempts and your origin sees only completed sessions.
What does not help is anything that reads requests: rules, challenges, and request rate limits operate on a stage this attack never reaches.
The trade-off nobody mentions
Defences here are tuning, and tuning has a cost paid by real users.
Shortening the time a server waits for a client to confirm reduces exposure and also drops clients on slow or lossy connections, which is not an even distribution: it falls on mobile users and on networks far from your servers. Raising the queue size consumes memory that the application would otherwise use.
That is why the mechanism that holds no state until the connection proves itself matters more than the numbers around it. It removes the trade-off rather than adjusting where it lands, and it is the change to make before touching any timer.
Where the platform sits
Bridge WAF operates on requests, which places it after the stage this family attacks, and saying otherwise would be inaccurate. What applies instead is termination: when connections are established at the platform's edge, the connection tables under attack are the platform's rather than your origin's, and your server sees sessions that already completed. Which component covers which layer is a fair question to ask any provider. See what the platform offers at Bridge CDN.
Questions
What is a protocol DDoS attack?
An attack that fills the tables network devices use to track connections. New clients are refused while bandwidth readings stay unremarkable, which is why it is often misdiagnosed: the resource being exhausted is memory rather than capacity, and memory does not appear on a traffic graph.
Does a WAF stop protocol attacks?
No. The connections never complete, so no request is ever formed for a firewall to inspect. Worse, a firewall that tracks connection state can itself be the device whose table fills, which makes it part of the problem rather than the defence.
Why is bandwidth normal during one?
Because a connection attempt is a very small packet, and the cost of it falls on the recipient rather than the sender. Each one occupies an entry in a table that is finite, so a stream too small to register on a graph can still exhaust the resource that matters.
What is the main defence?
Answering connection requests without reserving memory until the client proves it is really there, which moves the cost back onto the sender. This behaviour is standard on current operating systems and generally engages automatically once the pending queue comes under pressure.
Can my firewall stop it?
Only if it does not need to track connection state to make the decision. A device that tracks connections has a table of its own, and the same traffic exhausts it just as readily as it exhausts the server, so the protection fails before the thing it protects.
How do I confirm it?
Look for the combination rather than any single reading: many connections in a half-open state, processor usage that is low rather than high, and an application log showing few requests. Together those three rule out both a volumetric flood and an ordinary traffic surge.
After the stage this family attacks. What applies is termination: whose connection tables absorb the attempts.
off
No request is inspected. This family never reaches the request stage either way.
monitor
Matches are recorded — on connections that completed, which these do not.
block
Refusal happens on requests, after a session exists to carry them.
The firewall layer is included with Bridge CDN. Start in monitor: nothing is refused until you decide it should be.
Get started