Skip to content

Flowlight 0.8.2 - #6

Merged
blessdyb merged 2 commits into
mainfrom
release/0.8.2
Sep 27, 2026
Merged

blessdyb merged 2 commits into
mainfrom
release/0.8.2

Conversation

@blessdyb

Copy link
Copy Markdown
Contributor

Security fixes from a review of the update path, the Ask endpoint and header redaction. First release with the feature work on the branch rather than already on main, so this MR is the release's whole diff.

The updater answered "yes" where it meant "I don't know"

Checksums failed open. The comparison was expected == nil || expected == actual. A release with no SHA256SUMS.txt, a checksums file with no line for the disk image, or one that didn't parse all produced a nil expectation — and nil passed. Every way of failing to learn the checksum was treated as having learned it was right. It now requires the file, a 200 for it, and an entry for this image.

Nothing checked who signed the update. The installer compared the downloaded app's version and bundle identifier, which are strings inside the disk image that nothing signs, and then ran xattr -dr com.apple.quarantine — removing the one attribute that would have made macOS check the signature on first launch. So the check that mattered was never made, and the check macOS would have made was deleted.

CodeSignatureCheck validates the staged bundle against Apple's anchor with nested code and strict validation, and against the Team ID of the running app rather than a constant: an update must be signed by whoever signed the copy asking for it. Nothing to go stale, and an ad-hoc local build (no team) refuses rather than pretending it verified something. FLSkipUpdateSignatureCheck covers local testing and is read from the running app's defaults, so nothing inside a downloaded image can set it.

Two more from the same review

  • A compatible hosted endpoint accepted http:// while sending an API key and a question about this Mac's traffic. HTTPS is required now, except loopback and private ranges — that is how someone points it at a model on their own machine or LAN.
  • Redaction matched a fixed list of header names, so X-Access-Key, X-Client-Credential or any vendor's spelling went to disk under a privacy promise that says API keys are never stored. It matches on the word now, with a short exception list so X-Request-Id and friends stay readable.

Checks

470 tests including five new ones for the update path, plutil clean, ten catalogs unchanged at 1176/1176, and the release build signed, notarized and Gatekeeper-verified before this merges.

🤖 Generated with Claude Code

blessdyb and others added 2 commits September 27, 2026 00:35
Two checks in the update path answered "yes" when they meant "I don't know".

The checksum was compared as `expected == nil || expected == actual`. A release with no `SHA256SUMS.txt`, a
checksums file with no line for the disk image, or one that didn't parse all produced a nil expectation, and a
nil expectation passed — so every way of failing to learn the checksum was treated as having learned it was
right. It now requires the file, a 200 for it, and a line for this image, and refuses the download otherwise.
Every release the workflow publishes carries one; a release that doesn't is one to refuse.

The installer checked the downloaded app's version and bundle identifier. Both are strings inside the disk
image, and nothing signs them. It then removed the quarantine attribute — the one thing that would have made
macOS check the signature when the app was first launched. So the check that mattered was never made, and the
check macOS would have made was deleted.

`CodeSignatureCheck` now validates the staged bundle against Apple's anchor with nested code and strict
validation, and against the Team ID of the running app rather than one written down here: an update has to be
signed by whoever signed the copy asking for it. That needs no constant that can go stale, and on an ad-hoc
local build — no team to compare against — it refuses instead of pretending it verified something.
`FLSkipUpdateSignatureCheck` lets those local builds exercise the path; it is read from the running app's own
defaults, so nothing inside a downloaded image can set it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Version, notes and rebuilt site, on the release branch until the tag has published.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@blessdyb
blessdyb merged commit f91e989 into main Sep 27, 2026
5 of 7 checks passed
@blessdyb
blessdyb deleted the release/0.8.2 branch September 27, 2026 07:50

This branch was successfully deployed

1 active deployment
release — e2faa4fe Deployed Sep 27, 2026 by blessdyb via release #54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant