Advanced

Serving files safely

A path is text from the client. Text from the client can name a directory above the one that is allowed, and the allowed directory is the boundary that must be checked.

What you will see

One name with a hash. The hash is the version, and the version is the cache rule.

About 1 min of reading

Try It

Check a path against a base

1

Write the base and the path

printf 'base=/public\npath=/public/../secret\n' > /tmp/p.txt; cat /tmp/p.txt

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Two lines. The path leaves the base, which is the failure to catch.
2

Resolve and compare

printf '/secret\n' | grep -c -f "^/public" /dev/stdin

Before you run it, say out loud what it will print. Then open the answer.

What it prints
0. The resolved path does not start with the base, which is the refusal.
3

Write the version in the name

printf 'app.a1b2c3.css\n' > /tmp/f.txt; cat /tmp/f.txt

Before you run it, say out loud what it will print. Then open the answer.

What it prints
One name with a hash. The hash is the version, and the version is the cache rule.

Data Flow

A client path to a served file
1 The path is resolved
↓
2 The resolved path is compared to the base
↓
3 The type is checked against the allowed set
↓
4 The name carries the version
Why this works
Why the cache is on the file

The name carries the version. A name that changes with the content is a name that can be cached forever.

The one thing never to serve

Anything that is not a declared type. A declared type is a claim about the bytes, and the claim is what the client trusts.

Examples

The join is the trap

Joining a base with a client path can leave the base. Leaving the base is the whole failure, and the failure is one check.

The check is after the resolve

Resolve first, then compare. Comparing before resolving is comparing text that may still change.

Why the static route is a component

It has its own rules and its own cache. A component is a thing with rules, and the rules are the reason it is separate.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Forms and redirects
Previous Lesson
Forms and redirects
Next Lesson
Where a Flask app stops
Where a Flask app stops →