v1.1.1 — security hardening, an MIT license, and one-tag releases.
Four CodeQL alerts closed, the project relicensed under MIT, and a
GitHub Actions pipeline that turns a v* tag into a draft
release with macOS and Windows artifacts attached. No behaviour
changes for end users — same v1.1 app, sturdier underneath.
Path-traversal defense
CodeQL flagged two "Uncontrolled data used in path expression" alerts in the server's filename handling. Both are now closed.
resolveOutputPath() and the
/api/download/:filename handler now apply a defensive
path.basename() and verify the resolved path stays
inside the configured output directory. Filenames containing
traversal sequences — .., absolute paths, OS-specific
separator tricks — either land safely inside the output folder or
are rejected outright.
The server still binds to 127.0.0.1, so this was never
reachable from the public internet. The fix raises the bar for the
one realistic threat: a malicious local webpage that has discovered
the loopback port.
Rate limiting on the loopback API
express-rate-limit now guards two endpoints:
100 requests/minute on conversion and
300 requests/minute on download. Standard
RateLimit response headers are emitted so anything
legitimate sees its budget.
Same threat model as above — the server is loopback-only. The cap is generous enough that real batch conversions never bump into it while still bounding what a hostile local page can do. Closes the two CodeQL "Missing rate limiting" alerts.
MIT license
LocalPix is now formally MIT-licensed. A LICENSE file
ships in the repo root, with matching license and
author fields in package.json. Nothing
changes for end users; the move just makes the existing intent
(use it, fork it, do what you like) legally legible to anyone who
asks.
GitHub Actions release pipeline
A new .github/workflows/release.yml takes over what
used to be a two-machine manual ritual. Pushing a tag matching
v* triggers parallel macOS and Windows builds, then
drafts a GitHub Release with both artifacts attached and the
release body auto-extracted from CHANGELOG.md.
The practical effect: the gap between "I tagged a version" and "users can download it" is now measured in CI-runner minutes rather than whichever laptop I happen to be near.
scripts/build-icns.sh
A small reusable shell script that turns any 1024×1024 PNG into a
macOS .icns bundle. Used to build both the light and
dark icon variants — committed mostly so the next icon refresh
doesn't require re-deriving the iconutil incantation
from memory.
Notes
Three CodeQL "DOM text reinterpreted as HTML" alerts in
public/index.html remain open as won't-fix for
this release. All interpolated values flow through
escHtml() before reaching the DOM, so none of them
are reachable XSS. The honest fix is a full DOM-API refactor —
replacing the string-built HTML with createElement
and textContent — which is on the docket for v1.2.
How to upgrade
Download the v1.1.1 .dmg or .exe from the downloads page and replace your existing install. WebP output remains byte-identical to every prior LocalPix and LocalConvert release; hashed pipelines don't need to change anything.