What We Hardened in Self-Hosted Pro This Month

What We Hardened in Self-Hosted Pro This Month

TL;DR: Self-Hosted Pro v1.6.0 ships a batch of security, reliability, and feature improvements — fail-closed boot on decryption errors, Host-header and null-byte injection protection, audit log rate limiting, a policy-backed server-side password generator, HTTPS mailer defaults, and better SSO error handling. If you’re running Self-Hosted Pro, pull the latest image.

Why a Hardening Post

Most release notes focus on features. But for self-hosted operators — especially those running Password Pusher in regulated environments — the hardening work matters just as much. This post covers the security, reliability, and operational changes that shipped in Self-Hosted Pro v1.6.0.

New: Server-Side Password Generator

The password generator has been rebuilt as a server-side, policy-backed generator. Previously, password generation ran entirely in the browser with client-side JavaScript. The new generator enforces workspace password policies server-side, so generated passwords always meet the configured requirements. Errors are shown inline instead of silently producing non-compliant output.

Boot Security

Fail-closed on decryption errors. Self-Hosted Pro now refuses to start when the Administration Center settings cannot be decrypted. Previously, a misconfigured or rotated encryption key would let the container boot and appear healthy while silently running with unreadable configuration. Now it fails immediately with a clear error message. If the container starts, you know the configuration is intact.

Container version on startup. The application version is now printed in the boot logs and shown in the admin sidebar. Operators can confirm which build is running without checking image tags or digesting container metadata.

Rate Limiting and Audit Logs

Rack::Attack parity with hosted. Self-hosted container images were shipping a stale rack_attack.rb overlay that missed rate-limiting fixes already live on pwpush.com — including Devise login-email throttling. The container overlay is now synced with the hosted configuration.

Dedicated audit log throttles. Audit log endpoints (/p/:token/audit and /q/:token/audit) now have their own Rack::Attack rate limits, separate from global request caps. This protects against polling abuse on both authenticated and unauthenticated requests without affecting normal API traffic.

Paginated audit log responses. Web JSON audit log responses now return 30 entries per page instead of the full history. For pushes with hundreds or thousands of view events, this eliminates payload bloat and reduces response times.

Network Hardening

Host-header injection protection. Security scanners probing with forged Host headers could trigger a Rails InvalidDirectiveError by injecting arbitrary hostnames into the Content Security Policy form-action directive. The application now validates workspace hostnames and rejects malformed Host headers before they reach CSP generation.

Null-byte secret URL rejection. Scanner probes embedding null bytes in secret URL tokens no longer cause a 500 error. The application now rejects these malformed requests cleanly.

Hardened checkout redirects. Checkout redirect URLs are validated before use, preventing open-redirect scenarios from crafted return URLs.

HTTPS mailer defaults. Self-Hosted Pro mailers and background jobs now default absolute URLs to HTTPS when TLS_DOMAIN is unset — which is the common case when TLS is terminated at a reverse proxy. A HOST_PROTOCOL environment variable is available for the rare case where HTTP is intentional.

Scanner-resilient feedback endpoint. Custom-domain scanner POST requests to /feedbacks no longer trigger a NoMethodError. The endpoint now handles unauthenticated requests gracefully.

SSO and Authentication

Microsoft Entra SSO error handling. When a Microsoft Entra SSO login fails domain verification, users now see a dedicated help page with troubleshooting guidance instead of a generic “Something went wrong” redirect. This matters for initial SSO rollouts where domain configuration issues are common.

Operational Improvements

Separate max-files policy for request responses. Request response file limits are no longer reused from the push file limit. Admins can now set independent file-count policies for pushes and request responses.

Improved email delivery test messages. The SMTP test email from Admin Settings now includes more diagnostic detail, making it easier to verify that email delivery is working correctly during initial setup.

Dark mode alignment. Pro dark mode is now aligned with the OSS slate theme for visual consistency across editions.

Ruby 4.0.7 base image. Container images are now built on Ruby 4.0.7 with the latest security patches.

SQLite schema fix for fresh installs. Standard and Advanced tier fresh installs (empty database) were failing to boot due to a stale SQLite schema file. The schema is now regenerated from the current migration head.

Single logo for both themes. When only one custom application logo is uploaded, it’s now used for both light and dark overlay themes instead of falling back to the stock Password Pusher logo on the alternate theme.

Where This Might Not Apply

These changes are specific to Self-Hosted Pro container images. If you’re using the hosted service at pwpush.com, all of this is already in production. If you’re running the open source edition, some of these fixes (Rack::Attack, audit pagination) have equivalents in the OSS release — check the OSS release notes for details.

Availability

All of these changes are in Self-Hosted Pro v1.6.0, now available on registry.apnotic.com. Pull the latest image for your tier (Starter, Advanced, or Enterprise) to pick up everything listed here.

If you’re evaluating Self-Hosted Pro, the documentation and tier comparison are at docs.pwpush.com/docs/pro-self-hosted.


Peter Giacomo Lombardo Founder & Principal, Apnotic · Creators of Password Pusher