-
Notifications
You must be signed in to change notification settings - Fork 8
Release Notes v2.141 v2.142
NeySlim edited this page May 2, 2026
·
1 revision
Consolidated release notes for stable releases v2.141 (2026-04-29) and v2.142 (2026-05-02).
For older versions see Release Notes v2.128 → v2.140 and the full CHANGELOG.
Major security hardening sweep (16 fix(security): commits) plus a large modular refactor of backend services and frontend pages. No breaking API changes. Two operator-visible behaviour changes:
- HSM dependency installer now returns
403unlessUCM_ALLOW_RUNTIME_PIP=1is set in the environment. - Filesystem session directory is enforced at
0o700at boot — a loose-permissions directory makes the application refuse to start.
-
EST
/cacerts,/simpleenroll,/simplereenroll,/serverkeygen,/csrattrsnow enforceest_enabledon every request and short-circuit with503 EST disabledinstead of falling through to the SPA. The/serverkeygenbody is also size-capped and stricter about content negotiation. See EST Protocol. -
EST and SCEP mTLS client certificates are only honoured when the request comes from a trusted reverse proxy (
security.trusted_proxies). Direct hits without TLS termination by UCM no longer accept proxy-injected client cert headers. See EST Protocol, SCEP Server. - mTLS login route gated behind the same trusted-proxy check. Header-based mTLS is rejected unless the request originates from a trusted proxy. See mTLS Authentication.
-
SCEP CSRs no longer copy arbitrary KU/EKU bits — only a whitelist (
digitalSignature,keyEncipherment,serverAuth,clientAuth) is honoured. - SCEP RFC 8894 P0/P1/P2 hardening — stricter PKCS#7 parsing, transaction-ID validation, signed/encrypted response envelope checks; iOS/macOS enrollment fixes (#102).
- 2FA backup codes are now hashed at rest (Argon2id) and consumed atomically; plaintext codes are returned only at generation time and never stored. See WebAuthn Support.
- Approval quorum is race-safe and idempotent. Concurrent approvals on the same request can no longer over-approve; double-submits are deduplicated. See Approval Workflows.
- ACME account private keys encrypted at rest with the application key. See ACME Support.
-
Password change endpoint ignores client-supplied
force_change(only operators can clear that flag). - CSRF token entropy increased; password hash algorithm tightened; database migration identifiers validated against an allow-list.
-
Outbound webhooks revalidate the resolved IP at delivery time (DNS-rebinding window closed) and reject cloud-metadata IPs (
169.254.169.254, GCP / Azure / Alibaba equivalents) and loopback. RFC1918 /.lan/.localtargets remain allowed by design (UCM is on-prem). See Notifications. -
SSO / IdP, ACME proxy and webhook URL fields all share the same SSRF helper (
validate_url_not_cloud_metadata) — cloud metadata is blocked everywhere. -
ProxyFixis opt-in viasecurity.trusted_proxies— prevents unauthenticatedX-Forwarded-Forspoofing on direct deployments. - EST audit lines use the trusted-proxy-aware client IP instead of the raw socket address. See Audit Logs.
-
On-demand CRL generation is serialised per-CA with a per-CA lock and
503 Retry-After: 5under contention — closes a CPU/IO DoS vector when many clients hit/cdp/<ca>.crlsimultaneously. See CRL CDP. -
CSV bulk user-import capped at 5 MB / 10 000 rows with
413 Payload Too Largeon overflow. See User Management. -
Filesystem session directory created/enforced at mode
0o700and the application refuses to boot if it has group/world-readable bits. See Installation Guide.
-
Runtime HSM
pip installdisabled by default —POST /api/v2/hsm/install-dependenciesreturns403with a hint to setUCM_ALLOW_RUNTIME_PIP=1or install the dependency via the system package manager (apt install python3-pkcs11,dnf install python3-PyKCS11, etc.). See HSM Support.
-
utils/trusted_proxy.py— sharedis_request_from_trusted_proxy()/client_ip()/reject_untrusted_proxy_headers()helpers used by EST, SCEP, mTLS login and audit logging. -
utils/ssrf_protection.py— single source of truth forvalidate_url_not_cloud_metadataandvalidate_host_not_cloud_metadata, used by webhooks, SSO, ACME proxy, OPNsense import. -
utils/safe_commit.py,utils/require_json_body,utils/parse_request_pagination,utils/safe_call,utils/audit_event— small composable helpers applied acrossapi/v2/*to remove boilerplate and silence intermittent rollback bugs. -
useCRUDPagefrontend hook covering 4 list / create / edit pages.
-
Massive backend modularisation.
system.py(1556 l),certificates.py(2220 l),cas.py(1245 l),ssh_cas.py(1607 l),database_admin(817 l),discovery_service,pdf_generator,scep_service(981 l),acme_service(1456 l → 7 mixins ≤ 350 l),trust_store(1487 l),ca_service(788 l),restore_mixin,notification_service,audit_service,crl_service,ssh_cert_service,msca_service,account.py,acme.py,tools.py,acme_client.py,users.py,settings.py,opnsense_importandmodels/__init__.pywere split into focused submodules. Behaviour is unchanged; module size, test isolation and review surface improve. -
Frontend modularisation.
CAsPage,CertificatesPage,DiscoveryPage,ACMEPage,SettingsPageandSsoProviderFormsplit into per-section sub-components underpages/<feature>/. - All
api/v2/*db.session.commit()calls now go throughsafe_commit()— consistent rollback + error logging on every write path.
-
PKCS12 / PFX export now honours the
include_chainflag (#100). Previously the CA chain was always included, regardless of the request. - Dashboard chart cards no longer overflow the grid and System Health gained an internal scrollbar (#99).
- iOS / macOS SCEP enrollment regressions (#102).
- ~20 test files de-duplicated against
conftest.py; pre-commit gate runs i18n sync + 461 frontend + 1613 backend tests on every commit. - RC validated end-to-end on Debian (DEB), Fedora (RPM) and Docker: smoke API 8/8 and Playwright use-cases 10/10 on all three targets.
- Admin lockout prevented on database backend switch (#96). Switching the database backend (SQLite ↔ PostgreSQL) no longer locks the admin out. Boolean and JSON columns are now coerced correctly when migrating rows from SQLite to PostgreSQL, the migration runs per-table in its own transaction so a single bad row no longer aborts the whole switch, and the active admin session survives the cutover. See Database Backend.
-
PostgreSQL backups via
pg_dump. The Docker image now shipspostgresql-client, so PostgreSQL-backed instances can produce nativepg_dumpbackups during backend migrations and scheduled backups. See Backup & Restore.
- In-app help covers v2.128 → v2.140 features in English plus all 8 translated languages (fr, de, es, it, ja, pt, uk, zh).
- README features and roadmap refreshed for v2.128 → v2.140.
- CI: backend test collection no longer fails on missing
SECRET_KEY/JWT_SECRET_KEY— workflow now exports test-mode env vars before pytest runs.
-
Docker —
docker pull neyslim/ultimate-ca-manager:2.142(or:latest). -
DEB —
wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.142/ucm_2.142_all.deb && sudo dpkg -i ucm_2.142_all.deb. -
RPM —
wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.142/ucm-2.142-1.fc43.noarch.rpm && sudo dnf install ./ucm-2.142-1.fc43.noarch.rpm.
-
HSM dependency installer — if you were relying on the in-app Install dependencies button on the HSM settings page, set
UCM_ALLOW_RUNTIME_PIP=1in the service environment or install the package via your system package manager. Recommended path on production: install via APT/DNF and leave the env var unset. -
Session directory perms — UCM refuses to start if its session directory (typically
/var/lib/ucm/sessions/or/opt/ucm/data/sessions/for source installs) has group/world-readable bits. The package post-install scripts already set this correctly. Manual installs should runchmod 0700 <session-dir>. -
mTLS / EST / SCEP behind reverse proxy — if you terminate TLS on a reverse proxy and rely on
X-SSL-Client-*(or equivalent) headers, declare the proxy CIDR(s) undersecurity.trusted_proxiesin System Config. Direct deployments (UCM terminates TLS itself) need no change. -
PKCS12 export
include_chain— automation that always received the chain regardless of the flag may now receive a leaf-only PKCS12 if it explicitly sendsinclude_chain=false.
No database migration is required beyond the standard auto-migration on first boot.