fix(security+audit): strip latent RCE grants, opener allowlist, GDI leaks, CI hardening
From the deep-audit wave (reviewer-verified: capability identifiers valid, no removed-crate references, GDI free ordering correct): - Removed 8 never-registered plugins (clipboard-manager, fs, shell, http, process, os, dialog, global-shortcut) from Cargo.toml AND their capability grants (shell:allow-execute, unscoped fs writes, http:default, …) — verified the web never invokes any of them. A latent RCE-class surface is gone. - on_new_window: only http/https/mailto reach the OS opener (file:///custom schemes previously bypassed the opener capability scope entirely). - set_badge_count: freed hdc + hdc_screen on all three GDI error paths (leaked per badge update in a long-running tray app). - 8s reveal failsafe gated by an AtomicBool: no longer re-shows a window the user closed to tray; page-load reveal now fires once only (logout reloads don't re-surface a tray-hidden window); recovery for a missed page-load event preserved. - toast.rs: store pruned on Activated too + capped at 20 (was unbounded). - Startup no longer panics when the bundled icon is missing (tray skipped gracefully); msSmartScreenProtection no longer disabled (throttling disables kept); rust-version corrected to 1.77.2. - release.yml update-manifest: fails on empty signatures (was: could publish a manifest that traps Windows users in a failed-update loop); partial- failure window documented. Deleted the stale upstream tauri.yml workflow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,14 @@ jobs:
|
||||
id: release
|
||||
env:
|
||||
TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
# NOTE (partial-failure window): this renames the `latest` release's
|
||||
# name/body to the new version up front, before the platform builds run.
|
||||
# If a build later fails, the release keeps the OLD binary assets but the
|
||||
# NEW name. That's cosmetic: the auto-updater reads release.json, which is
|
||||
# only regenerated by the update-manifest job — and that job `needs:` BOTH
|
||||
# build-windows and build-linux, so a failed/skipped build prevents any
|
||||
# manifest (and therefore updater) change. Clients keep the last good
|
||||
# release.json until a fully successful run replaces it.
|
||||
run: |
|
||||
VERSION="4.12.${{ github.run_number }}"
|
||||
EXISTING=$(curl -sf "$GITEA_URL/api/v1/repos/$REPO/releases/tags/latest" \
|
||||
@@ -277,6 +285,13 @@ jobs:
|
||||
|
||||
WIN_SIG=$(curl -sf "$BASE/LotusChat-x86_64-setup.nsis.zip.sig")
|
||||
LIN_SIG=$(curl -sf "$BASE/LotusChat-x86_64.AppImage.tar.gz.sig")
|
||||
|
||||
# Never publish a manifest with a missing/empty signature: the updater
|
||||
# would reject (or worse, accept an unsigned) artifact. Fail the job so
|
||||
# the previous good release.json stays in place.
|
||||
[ -n "$WIN_SIG" ] || { echo "ERROR: empty Windows signature" >&2; exit 1; }
|
||||
[ -n "$LIN_SIG" ] || { echo "ERROR: empty Linux signature" >&2; exit 1; }
|
||||
|
||||
DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
|
||||
python3 -c "import json,sys; v,d,wu,ws,lu,ls=sys.argv[1:]; print(json.dumps({'version':v,'notes':'Latest Lotus Chat release','pub_date':d,'platforms':{'windows-x86_64':{'url':wu,'signature':ws},'linux-x86_64':{'url':lu,'signature':ls}}},indent=2))" \
|
||||
|
||||
Reference in New Issue
Block a user