Source default removed, governed upload and restore have receipts, and the predecessor share is invalidated by owner attestation (no probe, by design). Fixed, embargo lifted, publication handover pending. Age-key taint referred to railiance-platform as a possible separate finding. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 6903@bnt-lap001 Assistant-Session: 8319e8a8-ffa6-4eb3-b8bf-b29945628f89
150 lines
7.5 KiB
Markdown
150 lines
7.5 KiB
Markdown
---
|
||
id: RISK-F-0010
|
||
type: finding
|
||
title: "Forgejo backup source embeds a WebDAV credential default"
|
||
status: fixed
|
||
owner: risk-nexus
|
||
reported_by: railiance-platform
|
||
reported_via: railiance-platform
|
||
routed_by: risk-nexus
|
||
date_reported: "2026-08-23"
|
||
date_filed: "2026-08-23"
|
||
system: railiance-platform
|
||
environment: production
|
||
fix_owner: railiance-platform
|
||
fix_tracking: RPF-WP-0029-T02 (done 2026-09-15)
|
||
closure_condition: "provider invalidation plus governed ciphertext upload and restore receipts; source fallback removal alone does not lift the embargo"
|
||
verification: RISK-V-0003
|
||
# Graded by risk-nexus 2026-09-01 — docs/rulings/2026-09-01-inbox-sweep.md
|
||
severity: low
|
||
severity_at_production: low
|
||
impact: I2
|
||
likelihood: L2
|
||
fidelity_modifier: false
|
||
production_rescore: false
|
||
disclosure: public
|
||
publication: pending-handover
|
||
publication_id: risk-f-0010-embedded-backup-webdav-credential
|
||
publication_path: "findings/embedded-backup-webdav-credential/v1/index.html"
|
||
publication_subtitle: "A backup script carried a literal file-drop credential default; the default is gone, the share is invalidated, and governed upload and restore are proven."
|
||
revision: "fixed-1"
|
||
embargo_was_condition: "the provider credential is revoked or invalidated and the literal source default is removed"
|
||
embargo_lifted: "2026-09-22 — literal default removed (observed) and predecessor share invalidated (owner attestation, no probe by design)"
|
||
embargo_was_since: "2026-09-01"
|
||
date_fixed: "2026-09-15"
|
||
escalation: none
|
||
last_checked: "2026-09-22T06:01:01Z"
|
||
next_check: "2026-09-22T07:01:01Z"
|
||
cadence: 1h
|
||
clean_streak: 1
|
||
graded_by: risk-nexus
|
||
ruling: RISK-RULING-2026-09-22-A
|
||
checked_by: "worsch"
|
||
---
|
||
|
||
# RISK-F-0010 — Forgejo backup source embeds a WebDAV credential default
|
||
|
||
## What is true, as reported
|
||
|
||
`railiance-platform/tools/cmd/forgejo-backup` line 13 assigns a literal default
|
||
to `RAILIANCE_BACKUP_NC_TOKEN`. The credential value is deliberately omitted
|
||
from this finding, along with any fingerprint, length, or copy.
|
||
|
||
The literal is in repository history and can be recovered by anyone with access
|
||
to affected clones or history. It was also surfaced in captured agent command
|
||
output during an attended review on 2026-08-23, which expands the set of places
|
||
that must be treated as potentially exposed.
|
||
|
||
The value was not used in that operation and its current validity was not
|
||
tested. The configured Nextcloud endpoint was independently observed to be a
|
||
write-only file drop: metadata listing and reads were denied while the approved
|
||
OpenBao-sourced credential could upload ciphertext. Therefore, the established
|
||
risk is an embedded credential and possible unauthorized write or storage
|
||
injection if it remains live; read access to existing backups is not
|
||
established. The age recovery private key is separate and was not found in the
|
||
script.
|
||
|
||
## How it was found
|
||
|
||
Found by source inspection while selecting the approved encrypted off-host
|
||
snapshot lane for preparation-only scenario
|
||
`WARDEN-WP-0027-T02-DRILL-20260822-01`. No attempt was made to authenticate
|
||
with or probe the embedded value.
|
||
|
||
## Suggested direction
|
||
|
||
Suggestion, owned by `railiance-platform`:
|
||
|
||
1. Revoke and regenerate the Nextcloud file-drop credential at the provider.
|
||
2. Write the replacement only to the governed OpenBao lane
|
||
`platform/workloads/railiance/backup/offsite-lane` through a mode-0600 input
|
||
file, then securely remove the input.
|
||
3. Remove the source-code default so backup execution fails closed unless the
|
||
value arrives through OpenBao or an explicit sanctioned environment.
|
||
4. Review reachable Git history, CI and agent logs, and clones under the
|
||
applicable retention policy; do not reproduce the credential while doing so.
|
||
5. Verify a ciphertext upload and restore after rotation, then clear any
|
||
exposure taint only with evidence.
|
||
|
||
Risk Nexus owns severity, disclosure, escalation, and review cadence. This
|
||
report intentionally does not assign them.
|
||
|
||
## Register ruling — 2026-09-01
|
||
|
||
`low` (`I2` × `L2`), embargoed, no escalation.
|
||
|
||
**`I2`: limited to one backup lane on the facts established.** If the embedded
|
||
value remains valid, it can authorize an ungoverned write or storage injection
|
||
at the Nextcloud file-drop endpoint. Metadata listing and reads were denied,
|
||
backup content is ciphertext, and the age recovery private key is separate.
|
||
Nothing here establishes disclosure of an existing backup or estate-wide
|
||
credential reach.
|
||
|
||
**`L2`: recoverable through access the estate does grant.** The value is in Git
|
||
history and appeared in captured agent output, so a repository clone or retained
|
||
log is a sufficient foothold. Current validity is unknown and is not tested by
|
||
this register; unknown is not treated as either live or revoked.
|
||
|
||
**Embargoed.** While the source default remains and validity is unresolved,
|
||
publishing that a recoverable provider credential exists materially shortens the
|
||
path beyond reading the private repository. The hold lifts only when revocation
|
||
or invalidation and removal of the literal are both observable. The credential
|
||
value, fingerprint, and shape remain excluded from every record and message.
|
||
|
||
**No escalation.** There is no evidence of a read, loss, real-person data
|
||
exposure, legal notification duty, new spend, ownership dispute, or a stalled
|
||
remediation yet. Railiance Platform owns both the source and provider action.
|
||
Silence defaults on 2026-09-15 to the existing grade and a recorded stall; it
|
||
does not soften the assessment.
|
||
|
||
Reasoning: `docs/rulings/2026-09-01-inbox-sweep.md`.
|
||
|
||
## Source remediation reconciled — 2026-09-05
|
||
|
||
RPF-WP-0029-T01 records source fallback removal and fail-closed input checks.
|
||
This register confirmed the named fallback is absent in the current script
|
||
without displaying or testing any credential. RPF-WP-0029-T02 remains `wait`
|
||
for provider invalidation and governed encrypted upload/restore receipts.
|
||
|
||
[RISK-V-0003](../docs/verifications/2026-09-05-open-findings-source-review.md)
|
||
records the boundary: source removal does not establish invalidation of the
|
||
predecessor. Open, low, embargoed and no escalation remain appropriate on the
|
||
available evidence. The 2026-09-15 review/default is unchanged. The historical
|
||
source-default statements above describe the earlier assessments.
|
||
|
||
## Closure ruling — 2026-09-22
|
||
|
||
Fixed; embargo lifted; no escalation. All four closure legs are evidenced: the
|
||
source default is removed, governed ciphertext upload and restore have receipts
|
||
(2026-09-06), and the predecessor share was invalidated on 2026-09-15. The
|
||
invalidation rests on owner attestation because probing it would mean
|
||
reconstructing the credential. Age-key taint is outside this finding and has
|
||
been referred to railiance-platform. Reasoning:
|
||
`docs/rulings/2026-09-22-f0010-closure.md`.
|
||
|
||
## Reviews
|
||
|
||
- **2026-09-01** — graded from the filed report and a redacted current-source check. The literal default remains; no fix record was found. Cadence starts at instant.
|
||
- **2026-09-02** — clean check: literal source default remains; no fix tracking; embargo and 2026-09-15 wait unchanged. Cadence instant → 1h (1 clean in a row); next check 2026-09-02 09:11Z.
|
||
- **2026-09-05** — not clean: Confirmed source fallback removal and RPF-WP-0029 tracking; provider invalidation and encrypted upload/restore receipts remain pending. Low grade and embargo retained; see RISK-V-0003. Cadence 1h → instant; checked again immediately.
|
||
- **2026-09-22** — clean check: Closed under RISK-RULING-2026-09-22-A: source default absent, upload/restore receipts, predecessor share invalidated by owner attestation; embargo lifted. Cadence instant → 1h (1 clean in a row); next check 2026-09-22 07:01Z.
|