Back to Feed
article 2m read

Three locks on the schedule page all use one key

A token, a self-repairing digest and a server deny rule on my staff schedule page all hang off one seed file, and reading the code, a missing seed lets an empty token straight through.

Article DepthPractice

Flow

Where each guard gets its secret

  1. 1Seed file

    Short, and committed to the repo.

  2. 2Token

    A hash of the seed, shown to every visitor.

  3. 3Digest

    Keyed with the same seed, and rewritten on any mismatch.

  4. 4Server rule

    Hides the seed, but only on servers that read per-directory config.

One small file is what all three locks I put on my staff schedule page in one afternoon depend on. From reading the code, if that file goes missing, the locks stop doing their job.

Three guards, one seed

The page keeps names, shifts and breaks in a plain CSV file. I put it behind two endpoints, one to read and one to save a cell. Then I added a token, a digest of the data file, and a server rule to block direct downloads of the private files.

The token and the digest both come from one seed file. The token is a hash of the seed, and the page shows it to every visitor. The seed is short, so it may be guessable from that token. Get the seed and you can fake both checks. It also went into the repo.

An empty secret makes an empty password

If the seed file is missing, the expected token becomes an empty string. The check turns away a missing token but not an empty one, so an empty token should pass. The page would show the same empty token, and the app would keep working. I got this from the code, not from a live test.

return sent is not None and same(want, sent)   # "" == "" passes

A digest that agrees with everything

If the digest doesn't match the data, the code writes a new digest from whatever is on disk and carries on. So a tampered file just becomes the new normal. With no seed, the digest step is skipped and the data is served anyway.

The deny rule depends on the server

The rule only works on servers that read per-directory config. On other servers, the seed is a plain download. Files kept outside the web folder don't have that problem.

The save path got looser

A save now adds blank rows up to whatever row number the client sends, with no limit. A column past the end is saved once and lost on the next load, while the caller is told it worked.

None of this is fixed in that day's work. Of all of it, the empty-token check is the one I'd write first, since it's about two lines.

Keep reading

Pick up a connected idea or branch into a nearby one.

5 paths forward