Skip to content

Render RFD PDFs in Asciidoctor more safely - #613

Merged
notpeter merged 3 commits into
mainfrom
claude/claude-security-fix-find_011cgtdtpxvwsesmugbtmj9h-9r3prr
Nov 12, 2026
Merged

notpeter merged 3 commits into
mainfrom
claude/claude-security-fix-find_011cgtdtpxvwsesmugbtmj9h-9r3prr

Conversation

@notpeter

Copy link
Copy Markdown
Collaborator

Harden the handling of PDF generation with Ascii doctor on the server.

  • RFDs with malicious payloads could read arbitrary files from the server at PDF generation time so run asciidcotor-pdf in "safe mode" and filter environment variables.
  • download_supporting_documents could escape from within the rfd-specific working directory (e.g. via .. in paths) so sanitize those paths first.
🤖 Robot Voice:

The asciidoctor-pdf command line defaults to the unsafe safe mode, so RFD content could include:: arbitrary files (absolute or parent-relative paths) or point pdf-theme at a YAML file elsewhere on disk and have its contents embedded in the published PDF. The renderer also inherited the processor's full environment, including any configuration supplied through it.

Run asciidoctor-pdf with -S safe and the render directory as the base dir so includes and relative images are jailed to it, lock the pdf-theme, pdf-themesdir and pdf-fontsdir attributes (asciidoctor-pdf does not jail them) so documents cannot override them, and pass the child only the environment variables needed to locate Ruby, Node and Chromium.

download_supporting_documents built local paths by deleting every rfd/NNNN from the repository path, so an RFD committer could pick directory names that collapse into .. and write files outside the render directory. The new supporting_document_path helper strips only the leading RFD directory. It skips any path that is empty or contains anything other than ordinary file and directory names, so every write stays under /rfd-render//. Unit tests cover the crafted path and the rejected cases.

Claude links (internal-only):

claude and others added 3 commits November 11, 2026 20:21
The asciidoctor-pdf command line defaults to the unsafe safe mode, so RFD
content could include:: arbitrary files (absolute or parent-relative paths)
or point pdf-theme at a YAML file elsewhere on disk and have its contents
embedded in the published PDF. The renderer also inherited the processor's
full environment, including any configuration supplied through it.

Run asciidoctor-pdf with `-S safe` and the render directory as the base dir
so includes and relative images are jailed to it, lock the pdf-theme,
pdf-themesdir and pdf-fontsdir attributes (asciidoctor-pdf does not jail
them) so documents cannot override them, and pass the child only the
environment variables needed to locate Ruby, Node and Chromium.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5Ej2cHBc7wgaksc9BPkai
download_supporting_documents built each local path by removing every
occurrence of `rfd/NNNN` from the repository path with str::replace.
Neighbouring components could collapse into `..` (for example
`rfd/0123/.rfd/0123./evil` became `../evil`), letting an RFD committer
write arbitrary files outside the per-render temp directory when the
UpdatePdfs action ran.

Strip only the leading RFD directory, component by component, and skip
any document whose remaining path is empty or contains anything other
than normal components, so the joined path always stays under the
render directory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5Ej2cHBc7wgaksc9BPkai
@notpeter
notpeter requested a review from augustuswm November 11, 2026 21:11
@notpeter
notpeter merged commit b4bda4e into main Nov 12, 2026
12 checks passed
@notpeter
notpeter deleted the claude/claude-security-fix-find_011cgtdtpxvwsesmugbtmj9h-9r3prr branch November 12, 2026 11:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants