beskar 0.0.2 → 0.2.0

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.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +274 -0
  3. data/README.md +412 -204
  4. data/app/channels/concerns/beskar/channels/session_security.rb +46 -0
  5. data/app/controllers/beskar/administrative_actions_controller.rb +16 -0
  6. data/app/controllers/beskar/application_controller.rb +214 -0
  7. data/app/controllers/beskar/banned_ips_controller.rb +255 -0
  8. data/app/controllers/beskar/dashboard_controller.rb +62 -0
  9. data/app/controllers/beskar/security_events_controller.rb +164 -0
  10. data/app/controllers/concerns/beskar/controllers/audit_export.rb +54 -0
  11. data/app/controllers/concerns/beskar/controllers/security_tracking.rb +76 -48
  12. data/app/controllers/concerns/beskar/controllers/session_security.rb +29 -0
  13. data/app/jobs/beskar/notification_job.rb +33 -0
  14. data/app/mailers/beskar/security_mailer.rb +59 -0
  15. data/app/models/beskar/administrative_action.rb +41 -0
  16. data/app/models/beskar/banned_ip.rb +105 -105
  17. data/app/models/beskar/security_event.rb +51 -4
  18. data/app/models/beskar/security_state.rb +58 -0
  19. data/app/services/beskar/banned_ip_manager.rb +88 -0
  20. data/app/views/beskar/administrative_actions/index.html.erb +33 -0
  21. data/app/views/beskar/administrative_actions/show.html.erb +21 -0
  22. data/app/views/beskar/banned_ips/edit.html.erb +195 -0
  23. data/app/views/beskar/banned_ips/index.html.erb +319 -0
  24. data/app/views/beskar/banned_ips/new.html.erb +190 -0
  25. data/app/views/beskar/banned_ips/review.html.erb +24 -0
  26. data/app/views/beskar/banned_ips/show.html.erb +304 -0
  27. data/app/views/beskar/dashboard/index.html.erb +280 -0
  28. data/app/views/beskar/security_events/index.html.erb +302 -0
  29. data/app/views/beskar/security_events/show.html.erb +293 -0
  30. data/app/views/beskar/shared/_export_form.html.erb +10 -0
  31. data/app/views/layouts/beskar/_behavior.html.erb +121 -0
  32. data/app/views/layouts/beskar/application.html.erb +581 -6
  33. data/config/routes.rb +30 -0
  34. data/db/migrate/20251016000001_create_beskar_security_events.rb +3 -3
  35. data/db/migrate/20260910000001_create_beskar_security_states.rb +14 -0
  36. data/db/migrate/20260911000001_create_beskar_administrative_actions.rb +22 -0
  37. data/db/migrate/20260911000002_expand_administrative_action_targets.rb +6 -0
  38. data/docs/README.md +73 -0
  39. data/docs/archive/project-documentation.md +659 -0
  40. data/docs/audits/project-review.md +437 -0
  41. data/docs/audits/repair-status.md +216 -0
  42. data/docs/guides/audit-and-waf.md +175 -0
  43. data/docs/guides/audit-lifecycle.md +172 -0
  44. data/docs/guides/authentication.md +213 -0
  45. data/docs/guides/configuration.md +182 -0
  46. data/docs/guides/dashboard-and-search.md +251 -0
  47. data/docs/guides/notifications-and-recovery.md +157 -0
  48. data/docs/guides/risk-scoring.md +116 -0
  49. data/docs/operations/monitor-only-mode.md +85 -0
  50. data/docs/operations/security-hardening.md +167 -0
  51. data/docs/operations/state-storage.md +144 -0
  52. data/docs/research/rust-performance-assessment.md +69 -0
  53. data/lib/beskar/configuration.rb +105 -20
  54. data/lib/beskar/configuration_validator.rb +188 -0
  55. data/lib/beskar/devise_authentication.rb +24 -0
  56. data/lib/beskar/engine.rb +21 -88
  57. data/lib/beskar/logger.rb +288 -0
  58. data/lib/beskar/middleware/request_analyzer.rb +133 -99
  59. data/lib/beskar/models/security_trackable_authenticable.rb +76 -97
  60. data/lib/beskar/models/security_trackable_devise.rb +34 -25
  61. data/lib/beskar/models/security_trackable_generic.rb +171 -214
  62. data/lib/beskar/risk_level.rb +22 -0
  63. data/lib/beskar/services/account_locker.rb +90 -81
  64. data/lib/beskar/services/administrative_audit.rb +36 -0
  65. data/lib/beskar/services/administrative_bans.rb +104 -0
  66. data/lib/beskar/services/audit_data.rb +72 -0
  67. data/lib/beskar/services/authentication.rb +31 -0
  68. data/lib/beskar/services/authentication_attempt.rb +141 -0
  69. data/lib/beskar/services/ban_expiry.rb +28 -0
  70. data/lib/beskar/services/device_detector.rb +32 -41
  71. data/lib/beskar/services/event_search.rb +58 -0
  72. data/lib/beskar/services/geolocation_service.rb +83 -114
  73. data/lib/beskar/services/ip_whitelist.rb +31 -40
  74. data/lib/beskar/services/location_assessment.rb +109 -0
  75. data/lib/beskar/services/native_account_lock.rb +82 -0
  76. data/lib/beskar/services/notifications.rb +46 -0
  77. data/lib/beskar/services/rate_limiter.rb +99 -125
  78. data/lib/beskar/services/request_context.rb +64 -0
  79. data/lib/beskar/services/risk_assessment.rb +58 -0
  80. data/lib/beskar/services/session_revocation.rb +62 -0
  81. data/lib/beskar/services/waf.rb +311 -198
  82. data/lib/beskar/services/waf_request.rb +60 -0
  83. data/lib/beskar/version.rb +1 -1
  84. data/lib/beskar/warden_authentication.rb +53 -0
  85. data/lib/beskar.rb +54 -4
  86. data/lib/generators/beskar/install/install_generator.rb +158 -0
  87. data/lib/generators/beskar/install/templates/initializer.rb.tt +261 -0
  88. data/lib/tasks/beskar_tasks.rake +25 -20
  89. metadata +93 -12
  90. data/lib/beskar/templates/beskar_initializer.rb +0 -107
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c5db4a97c58f47e443a19facccd9eaf9a14894558b220a43ce52735c9ea3ed2
4
- data.tar.gz: d3c74aa51d0ce7bbce34deba20368ffeb9049b799d6cf5b08ed26aabd2605c5c
3
+ metadata.gz: d34b14d657d818c36c3c2a91210c4ad4ab04ffd6b1087eeab9bb18bf3486c56c
4
+ data.tar.gz: a42dc485e08761ff3a6260fa21e7f280f7655f59e9acf3bc20edd056c9878988
5
5
  SHA512:
6
- metadata.gz: 56fe1bdf96313ce84bd8818f6c795993eb031c38e5a5e0f29934875b45224eb250ed305c6a60ca8076ae6b4eb326228ea6625a10d4d986c4a922e6519371bda5
7
- data.tar.gz: c5875b70720fc3ac65448f430a9f0a8a4c5c505f8e1c049ae5c1177da188a00127002aeed48ab1ebc737178a6297bb838f9e5a30d6273d182cc038de37c1945c
6
+ metadata.gz: 50bf70930298ab5fc0e31d803ce8f12245155a1f8d590efb5b8f6322256dc54928dbc1991ff2733c88d69958033f037918d2af57d6eb63d681ab1279b0c4c88c
7
+ data.tar.gz: 202b467246bd2797218131c462a1b8f9fa6aa3a0712b7126abfcb0192247a459aa50eedbaa20c340f9b8d608fb85320a24bbe575fa90d796ecf91d6ccd5326e1
data/CHANGELOG.md ADDED
@@ -0,0 +1,274 @@
1
+ # Changelog
2
+
3
+ All notable changes to Beskar will be documented in this file.
4
+
5
+ The entries below include historical behavior. For the current contract and
6
+ upgrade requirements, use the [documentation index](docs/README.md) and
7
+ [repair status](docs/audits/repair-status.md).
8
+
9
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
10
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
11
+
12
+ ## Unreleased
13
+
14
+ ## 0.2.0 - 2026-09-21
15
+
16
+ Security hardening, coordinated enforcement, and auditable administration.
17
+ This release includes breaking changes for 0.1.0 installations; read the
18
+ [rollout checklist](docs/operations/security-hardening.md#rollout) before upgrading.
19
+
20
+ ### Breaking changes
21
+
22
+ - Security state is now coordinated through the database, independently of the
23
+ `Rails.cache` backend. Apply the new state and administrative-history migrations
24
+ before starting upgraded workers. Users, sessions, and security state must share
25
+ the writer connection pool; old cache counters are not imported.
26
+ - Dashboard authentication no longer grants administrative permissions by itself.
27
+ Configure `authorize_admin` separately for `:read`, `:manage_bans`, `:export`,
28
+ and `:read_audit`. Ban mutations and exports require a trusted `audit_actor`,
29
+ a reason, and successfully recorded administrative history.
30
+ - Configuration is validated and sealed at startup. Invalid or unsupported
31
+ settings stop boot; direct runtime mutation is rejected. Runtime changes through
32
+ `Beskar.configure` require separate authorization, actor/reason/request context,
33
+ and an audit record. Runtime publication remains process-local.
34
+ - Global authentication budgets and request-wide blocking for exhausted IP login
35
+ quotas now default off. Opt in with `global_attempts[:enabled]` and
36
+ `ip_attempts[:block_requests]` under `rate_limiting` if those policies are needed.
37
+ Notifications and automatic pattern analysis also default off and require
38
+ explicit host configuration when enabled.
39
+ - Monitor-only mode records observations in separate state without automatically
40
+ creating IP bans, locking accounts, or resetting passwords. Review bans created
41
+ by older monitor-mode versions before enabling enforcement; existing bans are
42
+ not automatically removed.
43
+ - Devise session and remember-cookie salts now include a durable revocation
44
+ generation, causing a one-time sign-out of existing credentials. Confirmed locks
45
+ revoke prior credentials regardless of `immediate_signout`; unlocking does not
46
+ restore them. Risk-based locking itself remains opt-in.
47
+ - Rails-native authentication must use the admission, session-creation, and
48
+ session-resumption guards. OAuth, custom tokens, API controllers, and Action Cable
49
+ require the appropriate host integration; they are not automatically protected
50
+ merely by mounting the engine.
51
+ - Deleting an account retains its security events unchanged, including their
52
+ original account identifiers. Security events and administrative history reject
53
+ ordinary model-level rewrites/deletes. This is not anonymization or protection
54
+ against privileged SQL/bulk updates; hosts still own retention policy.
55
+ - Exports are bounded to 1,000 rows per cursor page and use filtered fields and
56
+ CSV formula-injection defenses. Scripted consumers must supply an audit reason
57
+ on every page and accommodate the revised export contract.
58
+
59
+ ### Added
60
+
61
+ - Framework-neutral authentication admission, API and Action Cable session guards,
62
+ explicit session revocation, and persistent Rails-native account locks with
63
+ automatic or manual-only unlock policies.
64
+ - An append-only administrative journal and read-only history dashboard for ban
65
+ changes, export preparation, and authorized runtime configuration changes, with
66
+ actor, reason, request/operation correlation, and filtered before/after state.
67
+ - Opt-in post-commit notification delivery jobs with bounded retries, plus an
68
+ explicit host-job contract for background analysis. Password recovery remains
69
+ owned by the host application or Devise; no built-in analyzer or recovery-token
70
+ issuer is supplied.
71
+ - Organized, gem-packaged guides and operational contracts under `docs/`, including
72
+ authentication coverage, deployment requirements, and remaining limitations.
73
+ - Complete dashboard initializer examples for Rails built-in authentication and
74
+ Devise, including permission checks and audit identity. The Rails example checks
75
+ the signed session cookie and session revocation, with explicit instructions to
76
+ include `SecurityTrackableAuthenticable` in the host user model. Installation
77
+ guidance explains Devise's Warden scopes and the dashboard controller context.
78
+
79
+ ### Security and fixes
80
+
81
+ - Enforce Devise password/HTTP Basic admission before credential verification;
82
+ coordinate IP/account limits and backoff across workers without double-counting
83
+ outcomes. Required enforcement-state failures deny access while optional audit
84
+ failures do not undo authentication decisions.
85
+ - Honor monitor/whitelist policy for automatic enforcement and isolate observation
86
+ counters. Whitelisted attempts do not consume enforced global capacity.
87
+ - Fix lost updates in rate-limit/WAF state, concurrent ban extensions, and mixed
88
+ administrative/automatic changes. MySQL locking reads prevent stale transaction
89
+ snapshots from overwriting ban updates or missing sessions during revocation;
90
+ native cleanup also ignores stale loaded associations and preserves callbacks.
91
+ - Read ban decisions from the authoritative database, preserve permanent bans
92
+ during cleanup, normalize individual IP addresses, and reject invalid durations.
93
+ Administrative extensions no longer fabricate additional violations.
94
+ - Retain security events after account deletion, tolerate missing accounts in
95
+ dashboards/exports, and make bulk administrative changes and their history
96
+ transactional. Failed or aborted persistence no longer reports success.
97
+ - Bound and filter audit metadata, headers, identities, and error logging; use
98
+ Rails-resolved client IPs and consistent Rack 3 headers and retry deadlines.
99
+ - Correct timestamped geographic risk history, impossible-travel calculations,
100
+ provider/cache isolation, and shared decision/audit evidence. Mock geography
101
+ cannot supply geographic risk evidence; repeated IP use and unlocks no longer
102
+ grant implicit trust discounts.
103
+ - Narrow WAF exception scoring to relevant evidence by default, improve path
104
+ canonicalization and exclusions, and prevent duplicate charges for one request.
105
+ - Fix dashboard reporting/search/pagination, UTC and DST-sensitive ban editing,
106
+ unchanged microsecond expiry preservation, persistent validation messages, and
107
+ nonce-based scripts. Native forms retain CSRF protection and work with JavaScript
108
+ disabled or host Turbo loaded.
109
+ - Fix migration installation, MySQL JSON defaults and foreign-key types, Ruby 4
110
+ test dependencies, Chrome sandbox setup, and browser navigation synchronization.
111
+ CI covers Ruby 3.4/4.0, SQLite, PostgreSQL, MySQL, and Chromium system tests.
112
+
113
+ ### Removed
114
+
115
+ - Nonfunctional versioned API routes and their helpers. Dashboard resource exports
116
+ remain available behind their dedicated permissions.
117
+ - Claims of support for unimplemented capabilities: general SQL injection/XSS
118
+ filtering, JavaScript challenges, honeypots, and a built-in automatic pattern
119
+ analyzer. Unsupported custom lock strategies and geolocation providers are
120
+ rejected rather than silently accepted.
121
+
122
+ ### Upgrading from 0.1.0
123
+
124
+ 1. Copy and apply all engine migrations with `bin/rails beskar:install:migrations`
125
+ and `bin/rails db:migrate`, including the administrative-action target expansion.
126
+ 2. Configure administrative permissions, actor resolution, and reasons; review
127
+ [configuration](docs/guides/configuration.md) and
128
+ [audit lifecycle](docs/guides/audit-lifecycle.md) for the changed contracts.
129
+ 3. Adopt the [authentication guards](docs/guides/authentication.md), review all
130
+ credential entry points, and plan the one-time Devise sign-out. Legacy custom
131
+ tokens without a revocation generation must be rejected or reissued.
132
+ 4. Drain old workers and restart from the same reviewed configuration. Review
133
+ legacy bans and risk evidence in monitor mode before enforcing, and schedule
134
+ `bin/rails beskar:cleanup_security_state` to reclaim expired enforcement state.
135
+ This task does not purge audit events or account-lifetime revocation generations.
136
+ 5. Validate host recovery/delivery, shared-NAT behavior, and database load/failure
137
+ handling in staging. Cache independence does not remove database availability
138
+ requirements or establish production capacity guarantees.
139
+
140
+ ## 0.1.0 - 2025-11-25
141
+
142
+ Historical notes carried forward from the 0.1.0 release. In particular, the
143
+ monitor-mode ban creation described below is superseded by 0.2.0.
144
+
145
+ ### ⚠️ BREAKING CHANGES
146
+
147
+ - **Monitor-only mode refactored to top-level configuration**
148
+ - `config.waf[:monitor_only]` has been **removed**
149
+ - Use `config.monitor_only = true/false` at the configuration root level instead
150
+ - The method `Beskar.configuration.waf_monitor_only?` has been **removed**
151
+ - Use `Beskar.configuration.monitor_only?` instead
152
+ - See [Current upgrade guidance](docs/operations/security-hardening.md) for detailed migration guide
153
+
154
+ - **Dashboard authentication now required in all environments**
155
+ - Previous behavior: Dashboard allowed access in development/test without authentication
156
+ - New behavior: `config.authenticate_admin` must be explicitly configured for all environments
157
+ - **Why this change**: Prevents production security surprises by requiring explicit authentication setup
158
+ - **Migration**: Add `config.authenticate_admin` proc to your initializer (see examples in template)
159
+ - Developers who want to bypass auth in development must explicitly configure it
160
+
161
+ ### Added
162
+
163
+ - Ban records (`Beskar::BannedIp`) are now created even in monitor-only mode
164
+ - Provides full visibility into what would be blocked
165
+ - Allows querying `Beskar::BannedIp.active` to see potential blocks
166
+ - Makes verification and testing much more reliable
167
+ - Global monitor-only mode affecting all blocking features (WAF, rate limiting, IP bans)
168
+ - **Centralized logging system** (`Beskar::Logger`)
169
+ - Consistent log formatting with automatic `[Beskar]` or `[Beskar::Component]` prefixes
170
+ - Component name aliasing for cleaner output (e.g., `Beskar::Services::Waf` → `WAF`)
171
+ - Configurable log levels and output backends
172
+ - Include module support for automatic component detection in classes
173
+ - Single point of configuration for all logging
174
+ - **Security Dashboard** - Mountable web interface for monitoring and managing security
175
+ - Real-time security event monitoring with advanced filtering and pagination
176
+ - IP ban management with bulk actions, extend, and unban capabilities
177
+ - Statistics overview with risk distribution and threat analysis
178
+ - Export functionality for security events and banned IPs (CSV/JSON)
179
+ - Stripe-inspired minimalist design with embedded styles (no CSS dependencies)
180
+ - Custom pagination and filtering (no Kaminari/Pagy dependency)
181
+ - Configurable authentication via `config.authenticate_admin` proc
182
+ - Rails 7+ compatible with built-in CSRF protection
183
+ - Install generator for easy setup (`rails generate beskar:install`)
184
+ - Full documentation in [Current dashboard guide](docs/guides/dashboard-and-search.md)
185
+ - **WAF Rails Exception Detection** - Enhanced security through Rails exception analysis
186
+ - Detects `ActionController::UnknownFormat` exceptions (e.g., `/users/1.exe`) as potential scanning attempts
187
+ - Detects `ActionDispatch::RemoteIp::IpSpoofAttackError` as critical IP spoofing attacks
188
+ - Detects `ActiveRecord::RecordNotFound` as potential record enumeration scans
189
+ - Configurable exclusion patterns for `RecordNotFound` to prevent false positives
190
+ - New configuration: `config.waf[:record_not_found_exclusions]` accepts regex patterns
191
+ - Different severity levels: Critical (IP spoofing), Medium (UnknownFormat), Low (RecordNotFound)
192
+ - Exception-based violations count toward auto-blocking thresholds
193
+ - Works seamlessly alongside existing WAF vulnerability patterns
194
+ - **Enhanced Dashboard Authentication System**
195
+ - Helpful error messages with configuration examples when authentication not configured
196
+ - Clear, actionable guidance shows 4 authentication strategy examples (Devise, token-based, HTTP Basic, development bypass)
197
+ - Error response includes properly formatted code examples in initializer format
198
+ - Authentication configuration prominently documented at top of initializer template
199
+ - Support for any authentication strategy via flexible proc-based configuration
200
+
201
+ ### Changed
202
+
203
+ - **Refactored ApplicationController authentication for better maintainability**
204
+ - Simplified authentication flow from deeply nested conditionals to flat, single-responsibility methods
205
+ - Reduced method complexity: main `authenticate_admin!` is now 4 lines (was 20+ lines with 3-4 nesting levels)
206
+ - Extracted authentication logic into focused methods:
207
+ - `authenticate_admin!`: Routes to appropriate strategy (configuration check + delegation)
208
+ - `handle_custom_authentication`: Executes configured authentication with error handling
209
+ - `handle_missing_authentication_configuration`: Shows helpful error with examples
210
+ - All authentication paths now explicitly return `true` (allow) or `false` (deny)
211
+ - Consistent error handling for both HTML and JSON responses
212
+ - Improved exception handling with detailed error logging
213
+ - Added comprehensive test suite: 42 tests with 122 assertions covering all authentication scenarios
214
+
215
+ - Monitor-only mode is now a system-wide concept rather than WAF-specific
216
+ - Ban records are created but not enforced when `monitor_only = true`
217
+ - Security events include `monitor_only_mode` metadata flag
218
+ - All blocking decisions (WAF, rate limiting, authentication abuse) respect global monitor-only setting
219
+ - Improved logging with clear "MONITOR-ONLY" indicators
220
+ - Better separation of ban creation from ban enforcement
221
+ - All internal logging now uses `Beskar::Logger` instead of direct `Rails.logger` calls
222
+ - Log messages no longer require manual prefix formatting
223
+
224
+ ### Fixed
225
+
226
+ - Monitor-only mode now provides actual data for verification (ban records exist)
227
+ - Consistent behavior across all security features
228
+ - Clearer semantics for what monitor-only mode means
229
+
230
+ ### Security
231
+
232
+ - **Dashboard authentication hardening**: Removed environment-based authentication defaults
233
+ - Eliminates risk of accidentally deploying without authentication configured
234
+ - Forces explicit security decisions during initial setup
235
+ - All environments (development, test, production) now require authentication configuration
236
+ - Provides clear, immediate feedback when authentication is missing
237
+ - Reduces attack surface by failing secure (deny by default)
238
+
239
+ ### Documentation
240
+
241
+ - Updated README with new configuration structure
242
+ - Enhanced docs/operations/monitor-only-mode.md with examples of querying ban records
243
+ - Added migration guide in BREAKING_CHANGES.md
244
+ - Created docs/archive/project-documentation.md for development reference
245
+ - Updated docs/archive/project-documentation.md with comprehensive dashboard authentication section
246
+ - Documented authentication flow and architecture
247
+ - Added configuration examples and design principles
248
+ - Included test coverage details
249
+ - Updated initializer template (`lib/beskar/templates/beskar_initializer.rb`) with prominent authentication documentation
250
+ - Dashboard Authentication section moved to top (REQUIRED)
251
+ - Four complete authentication strategy examples
252
+ - Clear warnings about development-only bypass patterns
253
+
254
+
255
+ ## Versioning policy
256
+
257
+ - Before 1.0, minor releases (0.X.0) may include explicitly documented breaking changes.
258
+ - Patch releases (0.X.Y) contain backward-compatible fixes.
259
+ - From 1.0 onward, breaking changes require a major version increment.
260
+
261
+ ## Upgrade guide
262
+
263
+ When upgrading between versions with breaking changes:
264
+
265
+ 1. Read the [Current upgrade guidance](docs/operations/security-hardening.md) file
266
+ 2. Update your configuration according to the migration guide
267
+ 3. Run any new migrations: `rails db:migrate`
268
+ 4. Test in development/staging before deploying to production
269
+ 5. Start with `monitor_only = true` to verify behavior
270
+
271
+ ## Support
272
+
273
+ - [GitHub issues](https://github.com/AuditBadger-com/beskar/issues)
274
+ - [Documentation](docs/README.md)