Skip to content

v2.74.0

Latest

Choose a tag to compare

@marcpope marcpope released this 10 Aug 00:08
· 2 commits to main since this release

Security

This release fixes a cross-tenant authorization flaw. If your installation has more than one user account, please update.

A user holding manage_plans on one client could repoint that client's backup plan at a different client's repository by supplying its id. The plan itself was permission-checked, but the repository id taken from the request was not — so the check was object-level only, and the reference could cross tenants.

Auditing the same pattern turned up four more places where an id from the request or URL was used without confirming it belonged to the client in question:

  • Deleting a repository could remove objects from a bucket using another tenant's S3 credentials
  • Restoring from S3 could resolve another tenant's S3 credentials and pull their repository into a repository of your own
  • Removing S3 sync echoed another tenant's configuration name back in the confirmation message
  • Plugin configurations could be overwritten, deleted, or connection-tested across tenants, with the S3 test revealing the other tenant's bucket name

Single-admin installations are not exposed by these — every path requires a second, non-admin account. Multi-user installations should update at the earliest opportunity.

Reported privately and responsibly by @Doniyor2510 (GHSA-vm4w-wwpg-v3rc). Thank you.

Behavior change: profile timezone

Changing your profile timezone no longer rewrites your schedules.

Previously it rewrote the timezone on every schedule still set to your old zone and recalculated the next run, which silently moved backups to a different absolute time — a 02:00 schedule became 02:00 in the new zone. Anyone checking their backups while travelling could shift the whole server's schedule just by opening a page.

The profile timezone is now purely a display preference. A schedule keeps its own declared timezone and its own next run; a 02:00 New York schedule still runs at 02:00 New York and simply displays as 15:00 to someone viewing from Tokyo. No existing schedule is modified by this release — only the behavior of future timezone changes.

Fixed: stalled scheduler on large catalogs

The S3 sync manifest embedded the entire file catalog, generated inline on the once-a-minute scheduler tick while holding the scheduler lock. On a repository with tens of millions of catalogued files this ran for over an hour, writing a multi-gigabyte file, so every tick in that window was skipped and server-side jobs (prune, compact, catalog) sat queued behind it.

The catalog is now capped at 250,000 rows. Past that the manifest records archives only, and a restore from S3 queues a catalog sync to rebuild the file list. Larger manifests could never be read back anyway — the importer parses the document in memory.

New API endpoints

Continuing the API surface for mobile clients. All are token-authenticated and scoped to the caller's own clients.

Schedules

  • GET /api/v1/schedules/day — a day of concrete backup occurrences for the whole server, filterable by client, with day-picker counts for the surrounding week. Every field the UI positions or prints by is pre-resolved into the caller's timezone. Occurrences are placed on the day the viewer actually sees them, including when a schedule declared in another timezone crosses midnight.

My Profile

The My Profile page had no API surface at all; every action was a session-authenticated form post. These are the same actions in JSON:

  • GET / PATCH /api/v1/profile — account details in one round trip, partial update
  • GET /api/v1/profile/timezones — the timezone list with each zone's current offset, for clients that have no timezone database of their own
  • POST /api/v1/profile/password — changing your password now also signs out your other mobile sessions and reports how many
  • PUT /api/v1/profile/storage-alerts — low-storage alert threshold
  • POST /api/v1/profile/2fa/{setup,enable,disable,recovery-codes} — full two-factor enrolment. Returns the otpauth URI rather than a rendered QR image so clients can draw their own. The pending enrolment secret is held server-side, and regenerating recovery codes requires the account password
  • GET/PUT /api/v1/profile/reports, GET /api/v1/reports/{id}, POST /api/v1/reports/generate, POST /api/v1/reports/{id}/email — report preferences and retrieval. Report data is filtered to the clients the caller can access, with the summary recomputed over that scope

Queue and jobs (also in this release)

  • GET /api/v1/jobs/{id} gains the activity log, queue position and slot usage, current file during a running backup, prune statistics, and client status — enough to explain why a job is stuck rather than just saying "waiting"
  • GET /api/v1/queue gains recent finished jobs across all visible clients, server-wide slot usage, and 24-hour statistics

Other fixes

  • Plugin configuration edit form: conditional fields no longer stay visible when the selected options make them irrelevant. A duplicate class attribute meant show_when fields — the InterWorx partial-backup options among them — were always shown
  • InterWorx backups: failure messages now carry the actual error. The tool logs progress first and the error last, and reports a failed sub-backup mid-stream before continuing, so both truncating to the start and keeping only the tail hid the part that mattered

Agent

Agent version is 2.74.0 in this release. Agents will update themselves on their next check-in.