fix: bound document nesting and escape generated urls

This commit is contained in:
randogoth 2026-10-04 22:30:44 +03:00
parent c29364d8e0
commit 49a63503d0
10 changed files with 276 additions and 19 deletions

View file

@ -219,6 +219,10 @@ Links should be root-relative and extensionless (`[about](/about)`, not `about.m
Nothing outside the content root is reachable. A request target is percent-decoded before it is normalised, so an encoded `..` becomes a real one and gets clamped at the root rather than quietly matching nothing; any path component beginning with a dot is refused outright; and whatever survives is canonicalised and required to still be inside the root, which is what defeats a symlink pointing out of it. There are no generated directory listings — only `index.md`.
URLs the server generates are percent-encoded. A file name can contain a space, a `?`, a `#` or even a CR LF, and these URLs are emitted as redirect targets, so an unencoded one would truncate the path or end the response header and let a crafted file name inject a header of its own into every protocol.
A document is also refused if it nests blocks more than 100 levels deep, or if it is larger than the 8 MiB an expansion may produce. Both are about the stack and the heap rather than about the content: every pass over a parsed document recurses, and a stack overflow aborts the process instead of unwinding, so one pathological file would take every virtual host down with it. Includes are separately capped at 16 levels and 200 000 lines, with the byte cap catching the diamond fan-out that a per-stack cycle check cannot see.
## Development
```bash