Skip to main content
Version: 9.x

Print user-supplied HTML safely

You let your users write HTML, such as an invoice or a letter template, and print it with Gotenberg. You want their HTML to reach nothing but what it should, and no request to take the container down.

Deployment​

compose.yaml
services:
gotenberg:
image: gotenberg/gotenberg:9
environment:
CHROMIUM_DENY_PRIVATE_IPS: "true"
CHROMIUM_DISABLE_JAVASCRIPT: "true"
API_DISABLE_DOWNLOAD_FROM: "true"
WEBHOOK_DENY_PRIVATE_IPS: "true"
PDF_DENY_PRIVATE_IPS: "true"
API_BODY_LIMIT: 20MB
API_TIMEOUT: 30s
CHROMIUM_MAX_QUEUE_SIZE: "20"

Request​

Your backend sends the user's HTML as usual:

curl \
--request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@index.html \
--form files=@style.css \
-o invoice.pdf

Result​

The PDF prints as before. An image or a style sheet the HTML points at an internal address is left out, and Gotenberg logs which.

How it works​

  • CHROMIUM_DENY_PRIVATE_IPS keeps the HTML's images, style sheets, fonts and iframes off your private network, and a cloud's metadata service: see Restrict outbound requests.
  • CHROMIUM_DISABLE_JAVASCRIPT stops the user's scripts, which could call any URL or loop forever.
  • API_DISABLE_DOWNLOAD_FROM, WEBHOOK_DENY_PRIVATE_IPS and PDF_DENY_PRIVATE_IPS close the other ways a request reaches a URL: a download, a webhook, and the timestamp authority of a sign or timestamp stage.
  • The size limit, the timeout and the queue cap keep one request, or a burst, from exhausting the container: see Limit resources.

Variations​

  • The templates need your own assets: upload them with the page, or allow your asset host with CHROMIUM_ALLOW_LIST, together with ^file:///tmp/ for the files uploaded with the page.
  • The templates need scripts: keep JavaScript on, and keep the timeout short.
  • Users send URLs, not HTML: the same settings apply to /forms/chromium/convert/url.