Skip to content

v2.60.1

Choose a tag to compare

@github-actions github-actions released this 13 Jul 03:51
· 26 commits to main since this release
fea69d4

Random AI prompt + image generator for the Stable Diffusion WebUI -- a CLI and a local web UI.

Pre-release software. Provided as-is under Apache-2.0.

What's new in this release

2026-07-13 — 2.60.1 — Security: the backend could be made to run arbitrary commands

CodeQL flagged it on the release PR and it was right. /api/image/open and /api/image/reveal built a
shell string around a request-derived path:

exec(`cmd /c start "" "${fp}"`);
exec(`explorer /select,"${fp}"`);

resolveOutputFile() blocks path traversal and nothing else, so an image in the output folder named
x" & calc & ".png closes the quote and everything after it runs. The ImageMagick convert/resize calls
had the same shape. Severity: critical (js/command-line-injection).
The fix is structural, not a better escape function — escaping is a losing game played on the attacker's
board. No shell: the program and its arguments are built separately (new
targets/web/backend/osCommands.js, pure and testable) and handed to execFile, which passes argv
straight to the OS. A quote inside a filename is then just a quote inside a filename. detectMagick
lost its shell too — nothing there needed one.
Three more from the same sweep, all real:

  • Prototype pollution (js/remote-property-injection, high): mergeSidecar merged a
    request-supplied patch key-by-key into a plain object, so {"__proto__": {…}} mutated
    Object.prototype for the whole process. Those keys are now dropped.
  • World-writable temp cache (js/insecure-temporary-file, high): the remote manifest was cached at a
    fully predictable path in os.tmpdir(), where any local account could pre-create or symlink it — and
    we'd write through it and then trust what we read back. Moved into the app's own directory, mode 0600.
  • Check-then-use races (js/file-system-race, high ×3): existsSync + read/write/unlink. Replaced
    with do-it-and-handle-ENOENT/EEXIST — the check was always a lie about the future anyway.
    Regression-tested (tests/regression/commandInjection.test.js, 5), and the test was proven by
    restoring the old cmd /c start shape and watching it go red.
    "It's a local-only backend" is mitigation, not absolution: it is one --host flag from a LAN.

How to get it

Prefer not to build? Download a pre-built edition:

  • Desktop app -- Windows .msi / .exe (or a portable .zip), macOS .dmg, Linux .AppImage / .deb (attached below). Self-contained; nothing to install first.
  • random-ai-prompt-2.60.1-online.zip -- the online edition as static files; host it anywhere, or just use https://prompt.fairyfox.io.
  • random-ai-prompt-2.60.1.tar.gz -- source tarball (run with Node 24: npm install then npm start).
  • random-ai-prompt-2.60.1-docs.zip -- the generated documentation site.

What's Changed

Full Changelog: v2.60.0...v2.60.1