Skip to content

Deep-review hardening: auth in all deployed envs, dependency floors, session cap#7

Merged
raghubetina merged 4 commits into
mainfrom
agent/deep-review-hardening
Jul 10, 2026
Merged

Deep-review hardening: auth in all deployed envs, dependency floors, session cap#7
raghubetina merged 4 commits into
mainfrom
agent/deep-review-hardening

Conversation

@raghubetina

Copy link
Copy Markdown
Contributor

Findings from a deep review of the gem after the 0.1.6 release, prepared as 0.1.7.

Security

  • Auth in all deployed environments. The engine force-enables web-console everywhere with all IPs allowed, but auth only engaged in production — a staging/preview deployment served an unauthenticated console (verified empirically). Development and test are now the only open environments; everything else fails safe (503 until credentials are configured, then Basic auth). Tests cover staging anonymous/valid on both the page and the evaluator.
  • web-console floor raised to >= 4.2.1. CSP nonces on injected assets arrived in 4.1.0 and Rack 3/Rails 7.1 support in 4.2.1; resolving anything older silently reintroduces the blank-console failure 0.1.6 fixed.
  • rubygems_mfa_required enabled in the gemspec.
  • Malformed Basic header hardening. Credentials are destructured instead of splatted, so a colon-less header 401s on Rack 2 (Rails 7.0) instead of raising.

Fixes / hygiene

  • Session cap. web-console's session store is never evicted, so every console page load pinned a binding until process restart. Oldest sessions are dropped beyond 50; a capped-out tab gets web-console's normal "no longer available" message. Regression test included.
  • Deleted the unused engine layout (referenced a stylesheet that doesn't ship) and the no-op CSRF skip (page is GET-only).
  • Bumped actions/checkout and actions/upload-artifact to v6, clearing Node 20 deprecation warnings and superseding dependabot PRs Bump actions/checkout from 4 to 6 #3/Bump actions/upload-artifact from 4 to 6 #4.
  • README: auth section covers all deployed environments, and notes the brute-force caveat, multi-process session behavior, and web_console config override.

The engine force-enables web-console in every environment and clears
its IP allowlist, but both the auth middleware and the controller
filters only engaged when Rails.env.production?. A deployment running
any other environment name - staging, preview, demo - therefore served
a completely unauthenticated console to the internet.

Invert the gate: development and test are the only open environments,
and anything else requires ADMIN_USERNAME/ADMIN_PASSWORD (or gets the
503 setup message until they are set), so unrecognized environments now
fail safe. The environment predicate lives on BasicAuthMiddleware and
the controller's second-layer filters share it.

Also stop splatting Rack's decoded Basic credentials into authorized?.
Rack 3 rejects credential arrays that aren't exactly two elements in
Request#basic?, but Rack 2 (still possible under Rails 7.0, which the
gemspec supports) does not, so a header whose decoded value lacks a
colon would raise ArgumentError and 500 instead of returning 401.
Destructuring pads with nil and authorized? already normalizes with
to_s, so malformed headers now fail closed.

While here, delete the engine's unused application layout: every
render uses layout false, and it referenced a stylesheet that does not
ship with the gem.
WebConsole::Session.inmemory_storage is an append-only hash: every
console page load stores a session holding a live binding, and nothing
ever removes it, so repeated loads pin memory until the process
restarts. Drop the oldest entries once 50 accumulate (Hash preserves
insertion order, so shift evicts oldest-first). A tab whose session was
evicted gets web-console's normal "session is no longer available"
message and recovers on reload.

Also remove the CSRF skip_before_action: the console page is GET-only
and Rails does not verify authenticity tokens on GET, so the skip (and
its defined? guard) did nothing.
Require web-console >= 4.2.1. The gemspec accepted >= 4.0, but CSP
nonces on injected assets only arrived in 4.1.0 (web-console #296) and
Rack 3 / Rails 7.1 support in 4.2.1 - an app resolving anything older
gets the silent blank-console-under-CSP failure that 0.1.6 fixed.

Enable rubygems_mfa_required so pushes and yanks of this gem require a
multi-factor-authenticated RubyGems session; a gem that ships a
production console is a worthwhile supply-chain target.

Bump actions/checkout and actions/upload-artifact to their current
majors (v6), clearing the Node 20 deprecation warnings on every run.
This supersedes the open dependabot PRs, which predate CI working at
all.
Changelog for the deep-review hardening pass, plus README updates: the
authentication section now describes all deployed environments rather
than just production, and notes the brute-force caveat on the password
prompt, the multi-process session limitation, and that the gem
overrides the host app's web_console settings.
@raghubetina
raghubetina merged commit 2fa3893 into main Jul 10, 2026
2 checks passed
@raghubetina
raghubetina deleted the agent/deep-review-hardening branch July 10, 2026 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant