fix(forgejo): upgrade to 16.0.2 for the org-mode arbitrary file read #450
Inga granskare
Etiketter
Inga etiketter
area/backups
area/ci
area/control-panel
area/identity
area/infra
area/observability
area/payments
area/security
area/storage
area/web
blocked
needs-info
needs-triage
ready-for-implementation
type
bug
type
chore
type
docs
type
epic
type
feature
type
task
wontfix
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Inget förfallodatum satt.
Beroenden
Inga beroenden satta
Referens
bitborg/bitborg-infra!450
Läser in…
Hänvisa till i nytt ärende
Ingen beskrivning angiven.
Ta bort grenen "fix/forgejo-16.0.2-security"
Borttagning av en gren är permanent. Även om den borttagna grenen kan fortsätta existera en kort tid innan den faktiskt tas bort, kan det INTE ångras i de flesta fall. Vill du fortsätta?
Closes #447. Security upgrade — worth merging ahead of ordinary review queue.
Why now
16.0.2 shipped 2026-07-30. Production has been behind it for 20 days, held first by #430
(
timestamp-requiredkept it out of a branch for seventeen days) and then by the weekly schedule(#446). Neither logged an error.
The fix that matters is
fix: prevent arbitrary file reads from org-mode rendering(upstream PR13682). The chain is complete on this deployment:
web_signups_open: "true").orgfileapp.iniSECRET_KEY,INTERNAL_TOKEN, DB, mailer, OIDC client secretThat last row is why this is escalation rather than an information leak: those first two forge
sessions and decrypt stored values.
Also in 16.0.2: CGNAT (
100.64.0.0/10) added to theprivatehostmatcher, which backs the webhookand migration allowlists; a stored XSS in Actions pre-execution messages (entitlement-gated, so least
reachable); and eight upstream dependency bumps marked
[SECURITY].ADR 0038 gate, cleared properly
Both tags move in this one change, as the gate's own instruction requires:
Verified in the
local/preview, not on prod.local/Makefilepins the floating16-rootless, sothe preview runs 16.0.2 today (confirmed:
forgejo version 16.0.2+gitea-1.22.0).bitborg.cssdisabledlabel:has(input[name="full_name"]).right.floated.content:has(input[name="_method"][value="PRIMARY"])The toggle is the point. "Nothing visible" is also exactly what a selector matching nothing
produces, so each was confirmed by disabling our stylesheet and watching the control appear. The
PRIMARY row additionally needed a second email address added first: with one address there is no
primary to choose, the selector matched zero elements, and it would have passed vacuously.
Also verified: the signed-out navbar still carries "Create account" →
www.bitborg.se/en/signup.What is NOT verified, stated rather than glossed
EXTERNAL_USER_DISABLE_FEATURES = deletion,manage_passwordapplies only to external OIDC users, sothe preview's break-glass local admin cannot exercise it. If 16.0.2 renamed the key or changed its
accepted values, external users silently regain password management and self-delete.
That needs one real OIDC account checked after the apply. It is not covered by anything above, and it
is not CSS, so the concealment gate does not cover it either.
This also means the earlier appearance of a "Change password" section in the preview is expected,
not a regression — the config comment says outright that a break-glass local admin keeps its
password page.
Dry-run against bitborg-prod
ok=293 changed=6 unreachable=0 failed=0, and the concealment gate passes.forgejo : Install Forgejo custom CSSforgejo : Pull the pinned Forgejo imageforgejo : Install Forgejo container Quadlet unitforgejo : Apply Quadlet changes before starting the servicemeta: flush_handlersbackup-drill : Install the drill orchestratorbackup_drill_forgejo_imagetemplates the tagregistry-mirror : Install the wrapper scriptThe last two are the tag propagating through templated consumers rather than duplicated literals,
which is the intended design and worth noting explicitly: the mirror will carry 16.0.2 with no second
edit, and Saturday's restore drill will run
forgejo doctoron 16.0.2 rather than the old image. Thatis not true of kanidm, whose mirror pin is a hardcoded literal (#441).
Handlers:
forgejo : Restart Forgejo, plusrunner-controller : Reload gitborg user systemd. Thesecond is forgejo's own notify. That handler name is defined in three roles and Ansible de-duplicates
to runner-controller's copy, which four separate handler comments in this repo already document.
Service impact
Forgejo restarts. Git and web are unavailable for the restart, and the image is pulled first, so the
gap is the container start rather than the download. Nothing else restarts.
Provenance comment
The CSS block claimed its selectors were "matched against Forgejo 16.0.1 markup". That is the record
the next upgrader reads, so it now says 16.0.2 and records how it was re-verified. The other 16.0.1
mentions in the tree are historical "verified against" claims about behaviours I have not
re-verified, so they are deliberately left alone rather than sweepingly bumped.
After the apply
Confirm the RUNNING image is 16.0.2 rather than assuming the tag bump took effect. #63 records that an
image-tag bump can no-op without a pull and restart; the dry-run shows both, but the running container
is the evidence.