Lion Cipher Lab

Build a hash table, and measure how hash flooding turns it quadratic

Why it matters

Almost every program you will ever defend stores data in hash tables: Python dicts, JSON objects, HTTP headers, form fields, caches, session stores. They are fast because of an average-case promise. Spread the keys out, and finding one takes about the same time no matter how many there are. That promise breaks if an attacker can choose keys that all land in the same place. Then every insert has to walk past every earlier key, and the work grows with the SQUARE of the input. In 2003 Crosby and Wallach showed this against Perl, the Squid proxy and the Bro intrusion detection system. In December…

What you'll learn

Steps in this lab

  1. What you are building, and why a data structure can be a denial-of-service bug
  2. Set up: a terminal, Python, and a lab folder
  3. Build the table and two hash functions: hashtable.py
  4. Construct 65,536 keys with one hash: collide.py
  5. Measure BEFORE: random keys vs colliding keys in the unkeyed table
  6. Why storing the hash did not save you, and why a bigger table would not either
  7. The fix: SipHash with a secret random key, measured AFTER
  8. Watch Python do the same thing: sys.hash_info and PYTHONHASHSEED
  9. Honest negative 1: a key the attacker knows or can learn is no key, and Python only salts str and bytes
  10. Honest negative 2: no collisions at all, and a huge request still costs you
  11. Honest negative 3: the keyed hash costs real speed
  12. Do it better: the judgment, in one page

Open the full interactive lab →