slash_console 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -1
- data/README.md +8 -4
- data/app/controllers/slash_console/console_controller.rb +14 -3
- data/lib/slash_console/basic_auth_middleware.rb +22 -4
- data/lib/slash_console/version.rb +1 -1
- metadata +4 -4
- data/app/views/layouts/slash_console/application.html.erb +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fe6fc75ab8103bf062f9a10eefdcc0385749f4c1889b04fb1c6ba0f1a99a939d
|
|
4
|
+
data.tar.gz: 6186eb67c87e30ebb7c0e09dca9cd4d38212d5186fd32571a0ee89aedaaea780
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 611af64c4b066ec322875c66d9eac0a50ff0cc0102344240b24f1dd501ec60cd2241f3d19cd3f45fd593c0c63205685483bcdf79df23b18081e91e141618432d
|
|
7
|
+
data.tar.gz: 9f7f467142f12e16668899c9cb150e7b7165be1f2df1b099d93d2809bc2d5fb0ffb36f32d2befdd752be3c83cb2850331ad91bae944510704b76379c8400d6d1
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.7] - 2026-07-10
|
|
11
|
+
|
|
12
|
+
### Security
|
|
13
|
+
- Authentication is now required in every environment except `development`
|
|
14
|
+
and `test`, instead of only `production`. The engine force-enables
|
|
15
|
+
web-console and allows all IPs everywhere, so a `staging`/`preview`
|
|
16
|
+
deployment previously served an unauthenticated console.
|
|
17
|
+
- Require web-console >= 4.2.1: versions before 4.1.0 do not put CSP
|
|
18
|
+
nonces on injected assets (silently breaking under a strict CSP), and
|
|
19
|
+
versions before 4.2.1 lack Rack 3 / Rails 7.1 support.
|
|
20
|
+
- Enabled `rubygems_mfa_required`, so future gem pushes and yanks require
|
|
21
|
+
a multi-factor-authenticated RubyGems session.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- A malformed Basic Authorization header (credentials without a colon)
|
|
25
|
+
now gets a 401 on Rack 2 instead of raising.
|
|
26
|
+
- Stored console sessions are capped at 50 per process. web-console's
|
|
27
|
+
session store is never evicted otherwise, so each console page load
|
|
28
|
+
pinned a binding in memory until process restart.
|
|
29
|
+
|
|
30
|
+
### Removed
|
|
31
|
+
- Deleted the engine's unused application layout, which referenced a
|
|
32
|
+
stylesheet that does not ship with the gem, and a no-op CSRF skip in
|
|
33
|
+
the console controller (the console page is GET-only).
|
|
34
|
+
|
|
10
35
|
## [0.1.6] - 2026-07-10
|
|
11
36
|
|
|
12
37
|
### Security
|
|
@@ -78,6 +103,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
78
103
|
- Development mode with no authentication required
|
|
79
104
|
- Standard Ruby style guide compliance
|
|
80
105
|
|
|
81
|
-
[Unreleased]: https://github.com/firstdraft/slash_console/compare/v0.1.
|
|
106
|
+
[Unreleased]: https://github.com/firstdraft/slash_console/compare/v0.1.7...HEAD
|
|
107
|
+
[0.1.7]: https://github.com/firstdraft/slash_console/compare/v0.1.6...v0.1.7
|
|
82
108
|
[0.1.6]: https://github.com/firstdraft/slash_console/compare/v0.1.0...v0.1.6
|
|
83
109
|
[0.1.0]: https://github.com/firstdraft/slash_console/releases/tag/v0.1.0
|
data/README.md
CHANGED
|
@@ -6,7 +6,7 @@ A Rails engine that provides a web-based console interface at `/rails/console`,
|
|
|
6
6
|
|
|
7
7
|
- Only use this gem in applications where the security trade-offs are acceptable. Basically, only for toy apps/proofs-of-concept/portfolio projects that contain only sample data. Never use this gem when real user data is at risk.
|
|
8
8
|
- For serious apps, SSH into the server and run `rails console` at the command-line. This may require upgrading your hosting from free to paid, but you should be doing that anyway if you have real users.
|
|
9
|
-
- Make up a strong, unique `ADMIN_PASSWORD` for each app.
|
|
9
|
+
- Make up a strong, unique `ADMIN_PASSWORD` for each app. There is no rate limiting on the password prompt, so a short or guessable password can be brute-forced.
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
@@ -30,9 +30,9 @@ That's it! Navigate to `/rails/console` in your browser.
|
|
|
30
30
|
|
|
31
31
|
In development, no authentication is required. Simply visit `/rails/console`.
|
|
32
32
|
|
|
33
|
-
###
|
|
33
|
+
### Deployed environments
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
In every environment other than `development` and `test` — production, staging, previews, anything — authentication is required. Set these environment variables:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
ADMIN_USERNAME="choose_your_own_username"
|
|
@@ -41,15 +41,19 @@ ADMIN_PASSWORD="choose_your_own_strong_password"
|
|
|
41
41
|
|
|
42
42
|
Without these environment variables, you'll see an error message explaining what needs to be configured.
|
|
43
43
|
|
|
44
|
+
If your server runs multiple processes (e.g. Puma workers), console sessions live in the memory of whichever process rendered the page, so evaluating code may intermittently report that your session is no longer available. Run a single process (e.g. `WEB_CONCURRENCY=1`) for a reliable console.
|
|
45
|
+
|
|
44
46
|
## How It Works
|
|
45
47
|
|
|
46
48
|
SlashConsole is a lightweight wrapper around [the excellent `web-console` gem](https://github.com/rails/web-console). It:
|
|
47
49
|
|
|
48
50
|
1. Provides a dedicated route for console access (instead of only on error pages).
|
|
49
51
|
2. Renders a full-page console interface, including in apps that enforce a strict nonce-based Content Security Policy.
|
|
50
|
-
3. In
|
|
52
|
+
3. In every environment except development and test, requires basic authentication via a Rack middleware that protects both the console page and web-console's code-evaluation endpoints (`/__web_console/repl_sessions/:id`).
|
|
51
53
|
4. Evaluates console input at the top level, so constants resolve the same way as in `bin/rails console`.
|
|
52
54
|
|
|
55
|
+
Note that SlashConsole configures web-console itself: it activates it in all environments and clears its IP allowlist (authentication replaces it). Any `config.web_console` settings in your app will be overridden.
|
|
56
|
+
|
|
53
57
|
## Development
|
|
54
58
|
|
|
55
59
|
After checking out the repo, run `bundle install` to install dependencies.
|
|
@@ -2,17 +2,23 @@ module SlashConsole
|
|
|
2
2
|
class ConsoleController < ApplicationController
|
|
3
3
|
layout false
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# web-console stores every console session (and the binding it holds)
|
|
6
|
+
# in an in-memory hash that is never evicted, so each page load would
|
|
7
|
+
# otherwise pin memory until the process restarts. Old sessions are
|
|
8
|
+
# dropped once this many accumulate; an evicted session's tab shows
|
|
9
|
+
# web-console's normal "session is no longer available" message.
|
|
10
|
+
MAX_STORED_SESSIONS = 50
|
|
6
11
|
|
|
7
12
|
# BasicAuthMiddleware is the primary guard: it protects both this page
|
|
8
13
|
# and web-console's evaluator endpoints, but only at the engine's
|
|
9
14
|
# standard /rails mount point. These filters remain as a second layer
|
|
10
15
|
# so the page stays protected if an application mounts the engine at a
|
|
11
16
|
# custom path.
|
|
12
|
-
before_action :ensure_credentials_configured, if: -> {
|
|
13
|
-
before_action :authenticate_user, if: -> {
|
|
17
|
+
before_action :ensure_credentials_configured, if: -> { BasicAuthMiddleware.authentication_required? }
|
|
18
|
+
before_action :authenticate_user, if: -> { BasicAuthMiddleware.authentication_required? }
|
|
14
19
|
|
|
15
20
|
def index
|
|
21
|
+
prune_console_sessions
|
|
16
22
|
console(SlashConsole.console_binding)
|
|
17
23
|
render :index
|
|
18
24
|
end
|
|
@@ -30,5 +36,10 @@ module SlashConsole
|
|
|
30
36
|
BasicAuthMiddleware.authorized?(username, password)
|
|
31
37
|
end
|
|
32
38
|
end
|
|
39
|
+
|
|
40
|
+
def prune_console_sessions
|
|
41
|
+
storage = WebConsole::Session.inmemory_storage
|
|
42
|
+
storage.shift while storage.size >= MAX_STORED_SESSIONS
|
|
43
|
+
end
|
|
33
44
|
end
|
|
34
45
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module SlashConsole
|
|
2
|
-
# Basic authentication for the console in
|
|
2
|
+
# Basic authentication for the console in deployed environments.
|
|
3
3
|
#
|
|
4
4
|
# Authentication must happen in the middleware stack, not in
|
|
5
5
|
# ConsoleController: web-console's evaluator endpoints (PUT/POST
|
|
@@ -20,6 +20,14 @@ module SlashConsole
|
|
|
20
20
|
CONSOLE_PATHS = %r{\A/rails(?:/(?:console)?(?:\.[^/]*)?/?)?\z}
|
|
21
21
|
|
|
22
22
|
class << self
|
|
23
|
+
# Development and test are the only environments that get an open
|
|
24
|
+
# console. Any deployed environment -- production, staging, preview,
|
|
25
|
+
# or anything else -- must present credentials, because the engine
|
|
26
|
+
# force-enables web-console everywhere and allows all IPs.
|
|
27
|
+
def authentication_required?
|
|
28
|
+
!(Rails.env.development? || Rails.env.test?)
|
|
29
|
+
end
|
|
30
|
+
|
|
23
31
|
def credentials_configured?
|
|
24
32
|
ENV["ADMIN_USERNAME"].present? && ENV["ADMIN_PASSWORD"].present?
|
|
25
33
|
end
|
|
@@ -35,14 +43,13 @@ module SlashConsole
|
|
|
35
43
|
end
|
|
36
44
|
|
|
37
45
|
def call(env)
|
|
38
|
-
return @app.call(env) unless
|
|
46
|
+
return @app.call(env) unless self.class.authentication_required? && protects?(env[Rack::PATH_INFO].to_s)
|
|
39
47
|
|
|
40
48
|
unless self.class.credentials_configured?
|
|
41
49
|
return [503, {"content-type" => "text/plain"}, [CREDENTIALS_MESSAGE]]
|
|
42
50
|
end
|
|
43
51
|
|
|
44
|
-
|
|
45
|
-
if auth.provided? && auth.basic? && self.class.authorized?(*auth.credentials)
|
|
52
|
+
if valid_credentials?(env)
|
|
46
53
|
@app.call(env)
|
|
47
54
|
else
|
|
48
55
|
unauthorized
|
|
@@ -51,6 +58,17 @@ module SlashConsole
|
|
|
51
58
|
|
|
52
59
|
private
|
|
53
60
|
|
|
61
|
+
# Destructures rather than splatting: Rack 2 (Rails 7.0 apps) does not
|
|
62
|
+
# validate credential arity in Request#basic?, so a header whose
|
|
63
|
+
# decoded value lacks a colon would otherwise raise instead of 401ing.
|
|
64
|
+
def valid_credentials?(env)
|
|
65
|
+
auth = Rack::Auth::Basic::Request.new(env)
|
|
66
|
+
return false unless auth.provided? && auth.basic?
|
|
67
|
+
|
|
68
|
+
username, password = auth.credentials
|
|
69
|
+
self.class.authorized?(username, password)
|
|
70
|
+
end
|
|
71
|
+
|
|
54
72
|
def protects?(path)
|
|
55
73
|
CONSOLE_PATHS.match?(path) || evaluator_path?(path)
|
|
56
74
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: slash_console
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Raghu Betina
|
|
@@ -29,14 +29,14 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version:
|
|
32
|
+
version: 4.2.1
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version:
|
|
39
|
+
version: 4.2.1
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: standard
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -66,7 +66,6 @@ files:
|
|
|
66
66
|
- app/assets/stylesheets/slash_console/application.css
|
|
67
67
|
- app/controllers/slash_console/application_controller.rb
|
|
68
68
|
- app/controllers/slash_console/console_controller.rb
|
|
69
|
-
- app/views/layouts/slash_console/application.html.erb
|
|
70
69
|
- app/views/slash_console/console/index.html.erb
|
|
71
70
|
- config/routes.rb
|
|
72
71
|
- lib/slash_console.rb
|
|
@@ -78,6 +77,7 @@ homepage: https://github.com/firstdraft/slash_console
|
|
|
78
77
|
licenses:
|
|
79
78
|
- MIT
|
|
80
79
|
metadata:
|
|
80
|
+
rubygems_mfa_required: 'true'
|
|
81
81
|
homepage_uri: https://github.com/firstdraft/slash_console
|
|
82
82
|
source_code_uri: https://github.com/firstdraft/slash_console
|
|
83
83
|
changelog_uri: https://github.com/firstdraft/slash_console/blob/main/CHANGELOG.md
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>Slash console</title>
|
|
5
|
-
<%= csrf_meta_tags %>
|
|
6
|
-
<%= csp_meta_tag %>
|
|
7
|
-
|
|
8
|
-
<%= yield :head %>
|
|
9
|
-
|
|
10
|
-
<%= stylesheet_link_tag "slash_console/application", media: "all" %>
|
|
11
|
-
</head>
|
|
12
|
-
<body>
|
|
13
|
-
|
|
14
|
-
<%= yield %>
|
|
15
|
-
|
|
16
|
-
</body>
|
|
17
|
-
</html>
|