Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ versioned entry and uses it as the GitHub release notes.

- Prevent unauthenticated remote code execution on `/tikz/svg` via `\special{ps:...}`: `dvisvgm` hands PostScript specials embedded in the DVI off to Ghostscript, which `dvisvgm` starts with `-dDELAYSAFER` instead of `-dSAFER`, leaving the `%pipe%` device available and allowing arbitrary command execution regardless of `KROKI_SAFE_MODE` — including `SECURE`, since that setting only restricts kpathsea (LaTeX) file access and has no effect on Ghostscript. Fixed by passing `--no-specials=ps` to `dvisvgm` so PostScript specials are never processed
- Prevent BPMN diagram source from executing arbitrary HTML/JavaScript in the companion's headless Chromium page: the diagram source was assigned to the rendering container via `innerHTML` before being handed to bpmn-js, so a crafted request to `/bpmn/svg` could inject an element (e.g. `<img onerror=...>`) that ran script in that page; combined with the browser's `--disable-web-security` flag (same-origin policy disabled), that script could issue cross-origin requests and read the responses. Fixed by clearing the container instead of parsing the diagram source as HTML, and by dropping `--disable-web-security` — the only reason it was set, local file access, is already covered by the shared `--allow-file-access-from-files` flag ([#2089](https://github.com/yuzutech/kroki/pull/2089))
- Stop the headless Chromium instance shared by the Mermaid, BPMN, Excalidraw and diagrams.net companions from phoning home to Google (`update.googleapis.com`, `clients2.google.com`, `android.clients.google.com`, `accounts.google.com`, `www.google.com`) as soon as it launches: several independent Chromium subsystems (GCM device checkin, network-time sync, the component updater, ...) each reach out to their own Google endpoint, so disabling them one flag at a time (`--disable-component-update`, `--disable-domain-reliability`, `--no-pings`) still left some contacting Google — confirmed by packet capture. Fixed by blocking DNS resolution for those exact hosts at the browser level via `--host-resolver-rules` — not a `*.google.com`/`*.googleapis.com` wildcard, so it doesn't also block legitimate diagram-triggered subresources under the same domains (e.g. `fonts.googleapis.com`), which remain governed by the existing `KROKI_*_SAFE_MODE`/`*_ALLOWED_ORIGINS` request policy

### Changed

Expand Down
30 changes: 30 additions & 0 deletions lib/browser-instance/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,36 @@ const BASE_ARGS = [
'--disable-dev-shm-usage',
// Disable the setuid sandbox (Linux only)
'--disable-setuid-sandbox',
// Puppeteer's own default args (see ChromeLauncher.defaultArgs) already cover
// most background chatter (--disable-background-networking, --disable-sync,
// safe browsing, etc.), but several independent Chromium subsystems still
// phone home to Google on browser launch regardless: GCM device checkin
// (android.clients.google.com), network-time/CUP sync (clients2.google.com,
// www.google.com), account status (accounts.google.com), and the component
// updater (update.googleapis.com) — confirmed by packet capture even with
// --disable-component-update/--disable-domain-reliability/--no-pings set.
// Disabling each subsystem individually is whack-a-mole across Chromium
// versions, so instead block DNS resolution for the exact hosts confirmed
// by packet capture. Listed individually rather than as a *.google.com /
// *.googleapis.com wildcard so this doesn't also swallow legitimate
// diagram-triggered subresources under the same domains (e.g.
// fonts.googleapis.com) — those are already gated by applyNetworkPolicy
// below (KROKI_*_SAFE_MODE / *_ALLOWED_ORIGINS), which is the right layer
// to opt into them. Extend this list if packet capture turns up another
// Google host doing this.
'--disable-component-update',
'--disable-domain-reliability',
'--no-pings',
'--host-resolver-rules=' +
[
'update.googleapis.com',
'clients2.google.com',
'android.clients.google.com',
'accounts.google.com',
'www.google.com'
]
.map(host => `MAP ${host} 127.0.0.1`)
.join(','),
// Run in headless mode, i.e., without a UI or display server dependencies
'--headless',
// Prevents creating scrollbars for web content. Useful for taking consistent screenshots.
Expand Down
Loading