A fair fight costs both sides about the same. Amplification attacks are not fair: a few bytes in, a mountain of work out. CWE-405 is the class for a product that does not control situations where an adversary can cause it to consume or produce excessive resources without investing equivalent work or proving authorization. MITRE's word for it is asymmetric.
It applies broadly: client server systems, parsers, network services and libraries. The result is often poor performance from amplification, typically in a non-linear way, and it is worse when users can consume more than their access level should allow.
How it happens
The record lists four cases that show different flavors:
- CVE-1999-0513: the classic Smurf attack, using spoofed ICMP packets sent to broadcast addresses, so one packet becomes many replies aimed at a victim.
- CVE-2003-1564: a parsing library that allows an XML bomb, a small document that expands into an enormous one.
- CVE-2004-2458: a tool creates directories before authenticating the user, so unauthenticated requests cost real work.
- CVE-2020-10735: Python has a quadratic complexity issue when converting a string to an int with many digits in unexpected bases.
The last one is worth a closer look. Quadratic complexity means that doubling the input roughly quadruples the work. A string a few tens of kilobytes long can tie up a CPU for a long time, and any service that converts user supplied text to integers is a target.
A generic vulnerable pattern is work done before authentication:
@app.post("/export")
def export():
rows = db.query_all(request.json["filter"]) # heavy query, no auth yet
return render_report(rows) # huge response
What an attacker gains
MITRE lists availability: DoS through amplification, and CPU, memory or other resource consumption. The impact is rated high. Amplification attacks are efficient, so a small attacker can take down a large service, and they are sometimes a component of flood attacks.
How to find it
The record lists no detection methods. Practical approaches:
- Review what a request can cost. For each endpoint, ask how the work scales with input size, and whether it runs before authentication.
- Test with hostile inputs: deeply nested or self expanding documents, very long strings, many small requests, requests for huge result sets.
- Profile with inputs of doubling size. A cost that grows faster than linearly is a flag.
- Check libraries for known complexity and expansion issues. The free scan at gold.safeguard.sh/scan runs in your browser with no login and keeps the file on your machine, up to 100 dependencies.
How to fix it
MITRE's mitigations:
- Make resources available to a client in line with that client's access level.
- Keep track of allocated resources at all times and meter their use appropriately.
- Consider disabling resource-intensive algorithms on the server side, such as Diffie-Hellman key exchange. MITRE rates this as highly effective, with the note that business requirements may prevent it.
In practice, add concrete limits:
MAX_BODY = 1_000_000
if len(text) > 4300: # bound before converting
abort(400)
n = int(text)
parser = etree.XMLParser(resolve_entities=False, huge_tree=False)
Authenticate before doing expensive work, cap result sizes, set per client quotas, and limit expansion ratios and nesting depth in anything you decompress or parse.
Try it yourself
Click through it at your own pace, or open it full screen.
Quick check
What makes a resource attack asymmetric?
The attacker spends little, such as one small packet or document, while the target spends a lot. The cost ratio favors the attacker.
Why does doing work before authentication matter?
Anyone can trigger that work, so the access level of the requester does not limit what they can consume. The directory creation case in the record is an example.