Skip to content

Commit d1b83a5

Browse files
committed
chore(release): bump to Beta 0.9.13.2
Rolls up the security-audit hardening (API-token object-level scoping, object-level authz gaps in restore/console/migration/snapshot, tenant isolation + role hierarchy in user/role admin, per-action perms on schedules).
1 parent c1e7eec commit d1b83a5

5 files changed

Lines changed: 8 additions & 8 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
</p>
2222

2323
<p align="center">
24-
<img src="https://img.shields.io/badge/version-0.9.13.1--beta-blue" alt="Version"/>
24+
<img src="https://img.shields.io/badge/version-0.9.13.2--beta-blue" alt="Version"/>
2525
<img src="https://img.shields.io/badge/python-3.8+-green" alt="Python"/>
2626
<img src="https://img.shields.io/badge/license-AGPL--3.0--License-orange" alt="License"/>
2727
</p>

pegaprox/constants.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
from pathlib import Path
99

1010
# Version
11-
PEGAPROX_VERSION = "Beta 0.9.13.1"
12-
PEGAPROX_BUILD = "2026.06.18"
11+
PEGAPROX_VERSION = "Beta 0.9.13.2"
12+
PEGAPROX_BUILD = "2026.06.24"
1313

1414
# File Paths & Directories
1515
CONFIG_DIR = 'config'

version.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"version": "0.9.13.1",
3-
"build": "2026.06.18",
4-
"release_date": "2026-06-18",
2+
"version": "0.9.13.2",
3+
"build": "2026.06.24",
4+
"release_date": "2026-06-24",
55
"changelog": [
66
"release: v0.9.13 — Headlines: a new Cloud (Preview) layout — an opt-in card-grid interface with full per-cluster parity (VMs, containers, datastores, pools, networks, clusters, hosts, HA, Backups, Firewall, Replication, Ceph, SDN, Storage, PBS, Site Recovery, Monitoring) plus inline actions (run/enable/delete backup jobs, toggle/delete firewall rules, run replication). RBAC overhaul: admin-only endpoints are now permission-driven instead of hardcoded to the admin role, so custom roles finally work across alerts, users, settings, clusters, console/shell and API tokens (+4 perms: security.lockout.view/manage, security.settings.manage, update.manage; admin still holds every permission, so it stays backward-compatible). Console: the Client-Portal VNC console opens again (#537 abyss1), the terminal WebSocket uses the main port behind a reverse proxy (#539 markushergeth), a 500 on the VNC fallback route is fixed, and the SSH-WS helper writes to a writable dir on read-only installs (#528). ESXi->Proxmox migration: the dd progress parser reads the final byte count so a fully-copied disk is no longer mistaken for incomplete and deleted (#538 oetti77), the selected NIC model is honoured on every interface (#536 narukeh), real datastore-upload and qm errors are surfaced instead of '[object Object]' / success notices (#524 ccesario, #438 crcro), RBD target volumes are activated before write, and the SSHFS/live-mirror fallback probing is more robust with real stderr in the logs (#535 narukeh). Docker images rebuild from scratch each release so apt always pulls the current Debian security patches (openssl CVEs). Sponsor logos self-heal from the update mirror/GitHub when missing locally and survive a read-only images dir. Backfilled 146 missing UI translation keys that were rendering raw keys. The in-app and script updaters always re-download the newest tree now (never skip on a version match) with full-tree fallback and post-copy verification. Plus corporate-layout polish and an SSRF guard on the PBS storage-preflight.",
77
"security: v0.9.12.2 — authorized penetration test + remediation. All CRITICAL and HIGH findings fixed and each E2E-verified against a live lab. CRITICAL: (C-1) the VNC/termproxy console no longer hands the cluster-wide PVE session ticket (PVEAuthCookie = effectively root on pve:8006) to the browser — the standalone WS proxy now fetches it server-side via cluster-creds / ws-token-validate, the browser only ever sees the per-console scoped termproxy ticket; (C-2/M-2) V2P migration's esxi_datastore / esxi_vm_dir are validated against a strict single-name allowlist at the API boundary AND re-validated at the v2p chokepoint, plus shlex.quote on the sshfs mount paths — closes a root command-injection on the PVE node reachable by a default migrate-permission user. HIGH: (H-1/H-2) every console path (VNC route, in-process + standalone WS proxies, termproxy ticket) now enforces cluster access AND per-VM user_can_access_vm('vm.console') — previously only the vm.console permission was checked, so a console user could reach any VM on any cluster/tenant; (H-3) API-token perms are evaluated against the token's floored role, not the owner's — an admin-owned viewer/user token no longer inherits admin on perms-guarded routes; (H-4) web-push send re-validates the endpoint host server-side + refuses redirects; (H-5) the plain→SQLCipher migration's plaintext DB backup (every cluster password in clear) is now securely shredded on startup past a 1h window (PEGAPROX_PLAIN_BACKUP_RETENTION_S) instead of retained indefinitely next to the keystore; (H-6) request bodies are capped per-request so a chunked Transfer-Encoding body can no longer bypass the size limit and OOM the process. MEDIUM: (M-3) cluster-group endpoints read the correct tenant key (was user.get('tenant'), always None → cross-tenant group/metrics leak) and the manual cross-cluster balance + lb-history now enforce group ownership (was a BOLA that could trigger live VM migrations on another tenant's group); (M-7) alert webhook channels (Slack/Discord/Teams/ntfy/generic) now pass the SSRF guard before sending + refuse redirects, and the channel-test endpoint no longer leaks the upstream HTTP status (port-scan oracle) — internal targets opt-in via alert_webhook_allow_private; (M-8/M-9) ACME re-validates every directory-supplied follow-on URL and ACME/SIEM/site-recovery outbound calls no longer follow redirects to internal hosts. OIDC was deliberately left untouched. UI: Corporate Layout polish within its flat Clarity aesthetic — theme-aware metric/threshold colors (light mode now correct), keyboard focus ring on toolbar buttons, fade-in on action dropdowns, symmetric property-grid padding, flat (non-gradient) light-mode modal header. CI: Docker image builds only on a released version tag (not every main push); release-image apt-poll retries raised 120→150; the LXC template now also ships as pegaprox-latest-lxc-amd64.tar.xz so releases/latest/download/ always resolves to the newest build. Scaling/stability hardening from the 30-cluster/100-node audit carried over from the Testing line (off-hub metrics reads/writes, broadcast throttling, watched-cluster gating, bounded caches, syslog receiver DoS fix + UI toggle).",

web/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3467,7 +3467,7 @@
34673467
const API_URL=window.location.origin+'/api';// const API_URL = 'http://localhost:5000/api'; // local dev
34683468
// const API_URL = 'https://pegaprox.internal/api' // old staging
34693469
// NS: Central version constant - keep in sync with backend PEGAPROX_VERSION
3470-
const PEGAPROX_VERSION="Beta 0.9.13.1";const DEBUG=false;// set true for verbose logging
3470+
const PEGAPROX_VERSION="Beta 0.9.13.2";const DEBUG=false;// set true for verbose logging
34713471
// NS: global time formatting — reads user pref from localStorage
34723472
function fmtDate(d,opts={}){if(!d)return'';const dt=d instanceof Date?d:new Date(typeof d==='number'&&d<1e12?d*1000:d);if(isNaN(dt))return'';const h12=localStorage.getItem('pegaprox-time-format')==='12h';const defaults={year:'numeric',month:'2-digit',day:'2-digit',hour:'2-digit',minute:'2-digit',second:'2-digit',hour12:h12};return dt.toLocaleString(undefined,{...defaults,...opts});}function fmtTime(d){if(!d)return'';const dt=d instanceof Date?d:new Date(typeof d==='number'&&d<1e12?d*1000:d);if(isNaN(dt))return'';const h12=localStorage.getItem('pegaprox-time-format')==='12h';return dt.toLocaleTimeString(undefined,{hour:'2-digit',minute:'2-digit',second:'2-digit',hour12:h12});}// NS: timezone list for node time config (matches backend get_timezones)
34733473
const TIMEZONES=['UTC','Europe/Berlin','Europe/Vienna','Europe/Zurich','Europe/London','Europe/Paris','Europe/Amsterdam','Europe/Brussels','Europe/Rome','Europe/Madrid','Europe/Warsaw','Europe/Prague','Europe/Budapest','Europe/Stockholm','Europe/Helsinki','Europe/Athens','Europe/Moscow','America/New_York','America/Chicago','America/Denver','America/Los_Angeles','America/Toronto','America/Vancouver','America/Sao_Paulo','America/Mexico_City','Asia/Tokyo','Asia/Shanghai','Asia/Hong_Kong','Asia/Singapore','Asia/Seoul','Asia/Dubai','Asia/Kolkata','Asia/Bangkok','Asia/Jakarta','Australia/Sydney','Australia/Melbourne','Australia/Perth','Pacific/Auckland','Pacific/Fiji','Africa/Cairo','Africa/Johannesburg','Africa/Lagos'];// =====================================================

web/src/constants.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// const API_URL = 'https://pegaprox.internal/api' // old staging
1313

1414
// NS: Central version constant - keep in sync with backend PEGAPROX_VERSION
15-
const PEGAPROX_VERSION = "Beta 0.9.13.1";
15+
const PEGAPROX_VERSION = "Beta 0.9.13.2";
1616
const DEBUG = false; // set true for verbose logging
1717

1818
// NS: global time formatting — reads user pref from localStorage

0 commit comments

Comments
 (0)