From bd67b8ba2a990c795569f9c79c3110bc901792bc Mon Sep 17 00:00:00 2001 From: kaitoozawa Date: Tue, 16 Dec 2025 10:51:55 +1000 Subject: [PATCH 1/5] AR snapshot/restore helpers for test isolation --- .../autorun_engine/autorun_engine_spec.rb | 2 + .../handlers/browser_details_handler_spec.rb | 3 +- .../handlers/dynamic_reconstruction_spec.rb | 2 + .../network_stack/handlers/redirector_spec.rb | 2 + spec/beef/extensions/requester_spec.rb | 2 + .../websocket_hooked_browser_spec.rb | 2 + .../modules/debug/test_beef_debugs_spec.rb | 2 + spec/spec_helper.rb | 56 +++++++++++++++++++ 8 files changed, 70 insertions(+), 1 deletion(-) diff --git a/spec/beef/core/main/autorun_engine/autorun_engine_spec.rb b/spec/beef/core/main/autorun_engine/autorun_engine_spec.rb index 02258042d..e8bf3e7e3 100644 --- a/spec/beef/core/main/autorun_engine/autorun_engine_spec.rb +++ b/spec/beef/core/main/autorun_engine/autorun_engine_spec.rb @@ -12,6 +12,7 @@ require_relative '../../../../support/beef_test' RSpec.describe 'AutoRunEngine Test', run_on_browserstack: true do before(:all) do + @__ar_config_snapshot = SpecActiveRecordConnection.snapshot @config = BeEF::Core::Configuration.instance # Grab DB file and regenerate if requested @@ -110,6 +111,7 @@ RSpec.describe 'AutoRunEngine Test', run_on_browserstack: true do after(:all) do server_teardown(@driver, @pid, @pids) disconnect_all_active_record! + SpecActiveRecordConnection.restore!(@__ar_config_snapshot) end it 'AutoRunEngine is working' do diff --git a/spec/beef/core/main/handlers/browser_details_handler_spec.rb b/spec/beef/core/main/handlers/browser_details_handler_spec.rb index c0c5fe9d7..9d7ff1080 100644 --- a/spec/beef/core/main/handlers/browser_details_handler_spec.rb +++ b/spec/beef/core/main/handlers/browser_details_handler_spec.rb @@ -12,7 +12,7 @@ require_relative '../../../../support/beef_test' RSpec.describe 'Browser Details Handler', run_on_browserstack: true do before(:all) do - + @__ar_config_snapshot = SpecActiveRecordConnection.snapshot @config = BeEF::Core::Configuration.instance db_file = @config.get('beef.database.file') print_info 'Resetting the database for BeEF.' @@ -106,6 +106,7 @@ RSpec.describe 'Browser Details Handler', run_on_browserstack: true do after(:all) do server_teardown(@driver, @pid, @pids) disconnect_all_active_record! + @__ar_config_snapshot = SpecActiveRecordConnection.snapshot end it 'can successfully hook a browser' do diff --git a/spec/beef/core/main/network_stack/handlers/dynamic_reconstruction_spec.rb b/spec/beef/core/main/network_stack/handlers/dynamic_reconstruction_spec.rb index 3cfd652fe..4a0899648 100644 --- a/spec/beef/core/main/network_stack/handlers/dynamic_reconstruction_spec.rb +++ b/spec/beef/core/main/network_stack/handlers/dynamic_reconstruction_spec.rb @@ -1,6 +1,7 @@ RSpec.describe 'BeEF Dynamic Reconsturction' do before(:all) do + @__ar_config_snapshot = SpecActiveRecordConnection.snapshot @port = 2001 config = {} config[:BindAddress] = '127.0.0.1' @@ -25,6 +26,7 @@ RSpec.describe 'BeEF Dynamic Reconsturction' do after(:all) do Process.kill("INT",@pid) + SpecActiveRecordConnection.restore!(@__ar_config_snapshot) end it 'delete' do diff --git a/spec/beef/core/main/network_stack/handlers/redirector_spec.rb b/spec/beef/core/main/network_stack/handlers/redirector_spec.rb index 415d2ff39..df78232ca 100644 --- a/spec/beef/core/main/network_stack/handlers/redirector_spec.rb +++ b/spec/beef/core/main/network_stack/handlers/redirector_spec.rb @@ -1,6 +1,7 @@ RSpec.describe 'BeEF Redirector' do before(:all) do + @__ar_config_snapshot = SpecActiveRecordConnection.snapshot @port = 2002 config = {} config[:BindAddress] = '127.0.0.1' @@ -26,6 +27,7 @@ RSpec.describe 'BeEF Redirector' do after(:all) do Process.kill("INT",@pid) + SpecActiveRecordConnection.restore!(@__ar_config_snapshot) end it 'redirects' do diff --git a/spec/beef/extensions/requester_spec.rb b/spec/beef/extensions/requester_spec.rb index 8aabfbd23..cbe5a88d6 100644 --- a/spec/beef/extensions/requester_spec.rb +++ b/spec/beef/extensions/requester_spec.rb @@ -24,6 +24,7 @@ RSpec.describe 'BeEF Extension Requester' do xit 'requester works' do begin + ar_snapshot = SpecActiveRecordConnection.snapshot # Start beef server @config = BeEF::Core::Configuration.instance @config.set('beef.credentials.user', 'beef') @@ -77,6 +78,7 @@ RSpec.describe 'BeEF Extension Requester' do BeEF::Core::Models::Http.where(hooked_browser_id: hb_session).delete_all if defined? hb_session Process.kill('KILL', @pid) if defined? @pid Process.kill('KILL', @pids) if defined? @pids + SpecActiveRecordConnection.restore!(ar_snapshot) end end end diff --git a/spec/beef/extensions/websocket_hooked_browser_spec.rb b/spec/beef/extensions/websocket_hooked_browser_spec.rb index 34156645e..4058429b4 100644 --- a/spec/beef/extensions/websocket_hooked_browser_spec.rb +++ b/spec/beef/extensions/websocket_hooked_browser_spec.rb @@ -13,6 +13,7 @@ require 'websocket-client-simple' RSpec.describe 'Browser hooking with Websockets', run_on_browserstack: true do before(:all) do + @__ar_config_snapshot = SpecActiveRecordConnection.snapshot @config = BeEF::Core::Configuration.instance # Grab DB file and regenerate if requested print_info 'Loading database' @@ -104,6 +105,7 @@ RSpec.describe 'Browser hooking with Websockets', run_on_browserstack: true do after(:all) do server_teardown(@driver, @pid, @pids) disconnect_all_active_record! + @__ar_config_snapshot = SpecActiveRecordConnection.snapshot end it 'confirms a websocket server has been started' do diff --git a/spec/beef/modules/debug/test_beef_debugs_spec.rb b/spec/beef/modules/debug/test_beef_debugs_spec.rb index 075d13490..6a178078f 100644 --- a/spec/beef/modules/debug/test_beef_debugs_spec.rb +++ b/spec/beef/modules/debug/test_beef_debugs_spec.rb @@ -12,6 +12,7 @@ require_relative '../../../support/beef_test' RSpec.describe 'BeEF Debug Command Modules:', run_on_browserstack: true do before(:all) do + @__ar_config_snapshot = SpecActiveRecordConnection.snapshot # Grab config and set creds in variables for ease of access @config = BeEF::Core::Configuration.instance @pids = [] # ensure defined for teardown consistency @@ -128,6 +129,7 @@ RSpec.describe 'BeEF Debug Command Modules:', run_on_browserstack: true do after(:all) do server_teardown(@driver, @pid, @pids) disconnect_all_active_record! + SpecActiveRecordConnection.restore!(@__ar_config_snapshot) end it 'The Test_beef.debug() command module successfully executes' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index aa23cbfbb..73aa41101 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -322,4 +322,60 @@ require 'socket' pid = nil end +end + +# ------------------------------------------------------------------- +# ActiveRecord connection snapshot/restore helpers (test isolation) +# Some specs disconnect ActiveRecord (fork safety), destroying the SQLite in-memory DB. +# These helpers restore it for later specs. +# ------------------------------------------------------------------- +module SpecActiveRecordConnection + module_function + + def snapshot + # Capture the current AR connection configuration hash if possible. + if ActiveRecord::Base.respond_to?(:connection_db_config) && ActiveRecord::Base.connection_db_config + ActiveRecord::Base.connection_db_config.configuration_hash + else + ActiveRecord::Base.connection_config + end + rescue StandardError + nil + end + + def restore!(config_hash) + # Ensure we don't leave AR disconnected for subsequent specs. + begin + handler = ActiveRecord::Base.connection_handler + if handler.respond_to?(:connection_pool_list) + handler.connection_pool_list.each { |pool| pool.disconnect! } + elsif handler.respond_to?(:connection_pools) + handler.connection_pools.each_value { |pool| pool.disconnect! } + else + ActiveRecord::Base.connection_pool.disconnect! + end + rescue StandardError + # ignore + end + + if config_hash + OTR::ActiveRecord.configure_from_hash!(config_hash) + else + # Fallback to suite default + OTR::ActiveRecord.configure_from_hash!(adapter: 'sqlite3', database: ':memory:') + end + + if Gem.loaded_specs['otr-activerecord'].version > Gem::Version.create('1.4.2') + OTR::ActiveRecord.establish_connection! + end + ActiveRecord::Schema.verbose = false + + # Run migrations if the restored DB is empty/outdated + ActiveRecord::Migration.verbose = false + ActiveRecord::Migrator.migrations_paths = [File.join('core', 'main', 'ar-migrations')] + context = ActiveRecord::MigrationContext.new(ActiveRecord::Migrator.migrations_paths) + if context.needs_migration? + ActiveRecord::Migrator.new(:up, context.migrations, context.schema_migration, context.internal_metadata).migrate + end + end end \ No newline at end of file From 7d20c1138c017e85c4ffe6916c1e6fa6a548d842 Mon Sep 17 00:00:00 2001 From: kaitoozawa Date: Fri, 12 Dec 2025 10:36:34 +1000 Subject: [PATCH 2/5] Add Kali support link to issue template --- .github/ISSUE_TEMPLATE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index c0a78b0d2..a25db2373 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -26,6 +26,7 @@ 2. Update `client_debug` to `true` 3. Retrieve browser logs from your browser's developer console (Ctrl + Shift + I or F12 depending on browser) 4. Retrieve your server-side logs from `~/.beef/beef.log` - * If using **beef-xss** logs found with `journalctl -u beef-xss` + * If you have a kali (beef-xss) problem, you can submit a bug here: + https://www.kali.org/docs/community/submitting-issues-kali-bug-tracker/ **If we request additional information and we don't hear back from you within a week, we will be closing the ticket off.** From 86909af828ac154e93b76802c7f9bbd88632f347 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 13:02:22 +0000 Subject: [PATCH 3/5] Bump irb from 1.15.3 to 1.16.0 Bumps [irb](https://github.com/ruby/irb) from 1.15.3 to 1.16.0. - [Release notes](https://github.com/ruby/irb/releases) - [Commits](https://github.com/ruby/irb/compare/v1.15.3...v1.16.0) --- updated-dependencies: - dependency-name: irb dependency-version: 1.16.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index 078f4327f..5438a08c1 100644 --- a/Gemfile +++ b/Gemfile @@ -66,7 +66,7 @@ group :test do gem 'rdoc', '~> 6.17' gem 'browserstack-local', '~> 1.4' - gem 'irb', '~> 1.15' + gem 'irb', '~> 1.16' gem 'pry-byebug', '~> 3.11' gem 'rest-client', '~> 2.1.0' diff --git a/Gemfile.lock b/Gemfile.lock index fdca7f856..b0dd0f73f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -55,14 +55,14 @@ GEM json curb (1.2.2) daemons (1.4.1) - date (3.5.0) + date (3.5.1) diff-lcs (1.6.2) domain_name (0.6.20240107) drb (2.2.3) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) - erb (6.0.0) + erb (6.0.1) erubis (2.7.0) espeak-ruby (1.1.0) event_emitter (0.2.6) @@ -80,10 +80,10 @@ GEM http_parser.rb (0.8.0) i18n (1.14.7) concurrent-ruby (~> 1.0) - io-console (0.8.1) + io-console (0.8.2) io-endpoint (0.15.2) io-like (0.4.0) - irb (1.15.3) + irb (1.16.0) pp (>= 0.6.0) rdoc (>= 4.0.0) reline (>= 0.4.2) @@ -146,7 +146,7 @@ GEM pry-byebug (3.11.0) byebug (~> 12.0) pry (>= 0.13, < 0.16) - psych (5.2.6) + psych (5.3.1) date stringio public_suffix (6.0.2) @@ -171,7 +171,7 @@ GEM psych (>= 4.0.0) tsort regexp_parser (2.11.3) - reline (0.6.2) + reline (0.6.3) io-console (~> 0.5) rest-client (2.1.0) http-accept (>= 1.7.0, < 2.0) @@ -237,7 +237,7 @@ GEM sqlite3 (2.8.1-x86_64-darwin) sqlite3 (2.8.1-x86_64-linux-gnu) sqlite3 (2.8.1-x86_64-linux-musl) - stringio (3.1.9) + stringio (3.2.0) sync (0.5.0) term-ansicolor (1.11.3) tins (~> 1) @@ -312,7 +312,7 @@ DEPENDENCIES eventmachine (~> 1.2, >= 1.2.7) execjs (~> 2.10) geckodriver-helper (~> 0.24.0) - irb (~> 1.15) + irb (~> 1.16) json maxmind-db (~> 1.4) mime-types (~> 3.7) From ee8afbbecf3eb1a379c35a46cbaa0d46482701fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 13:08:43 +0000 Subject: [PATCH 4/5] Bump rubocop from 1.81.7 to 1.82.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.81.7 to 1.82.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.81.7...v1.82.0) --- updated-dependencies: - dependency-name: rubocop dependency-version: 1.82.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 5438a08c1..8966df044 100644 --- a/Gemfile +++ b/Gemfile @@ -24,7 +24,7 @@ gem 'rake', '~> 13.3' gem 'activerecord', '~> 8.1' gem 'otr-activerecord', '~> 2.6.0' gem 'sqlite3', '~> 2.8' -gem 'rubocop', '~> 1.81.7', require: false +gem 'rubocop', '~> 1.82.0', require: false # Geolocation support group :geoip do diff --git a/Gemfile.lock b/Gemfile.lock index b0dd0f73f..ebef53a3b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -194,7 +194,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.6) - rubocop (1.81.7) + rubocop (1.82.0) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -202,10 +202,10 @@ GEM parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.47.1, < 2.0) + rubocop-ast (>= 1.48.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.47.1) + rubocop-ast (1.48.0) parser (>= 3.3.7.2) prism (~> 1.4) ruby-progressbar (1.13.0) @@ -328,7 +328,7 @@ DEPENDENCIES rdoc (~> 6.17) rest-client (~> 2.1.0) rspec (~> 3.13) - rubocop (~> 1.81.7) + rubocop (~> 1.82.0) rubyzip (~> 3.2) rushover (~> 0.3.0) selenium-webdriver (~> 4.39) From c3e162a8f5ddc4e56ceca83364b86218cafd4f10 Mon Sep 17 00:00:00 2001 From: kaitoozawa Date: Thu, 18 Dec 2025 09:39:14 +1000 Subject: [PATCH 5/5] address review comments --- spec/beef/core/main/handlers/browser_details_handler_spec.rb | 2 +- spec/beef/extensions/websocket_hooked_browser_spec.rb | 2 +- spec/spec_helper.rb | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/beef/core/main/handlers/browser_details_handler_spec.rb b/spec/beef/core/main/handlers/browser_details_handler_spec.rb index 9d7ff1080..bf6f761ee 100644 --- a/spec/beef/core/main/handlers/browser_details_handler_spec.rb +++ b/spec/beef/core/main/handlers/browser_details_handler_spec.rb @@ -106,7 +106,7 @@ RSpec.describe 'Browser Details Handler', run_on_browserstack: true do after(:all) do server_teardown(@driver, @pid, @pids) disconnect_all_active_record! - @__ar_config_snapshot = SpecActiveRecordConnection.snapshot + SpecActiveRecordConnection.restore!(@__ar_config_snapshot) end it 'can successfully hook a browser' do diff --git a/spec/beef/extensions/websocket_hooked_browser_spec.rb b/spec/beef/extensions/websocket_hooked_browser_spec.rb index 4058429b4..5d4978e05 100644 --- a/spec/beef/extensions/websocket_hooked_browser_spec.rb +++ b/spec/beef/extensions/websocket_hooked_browser_spec.rb @@ -105,7 +105,7 @@ RSpec.describe 'Browser hooking with Websockets', run_on_browserstack: true do after(:all) do server_teardown(@driver, @pid, @pids) disconnect_all_active_record! - @__ar_config_snapshot = SpecActiveRecordConnection.snapshot + SpecActiveRecordConnection.restore!(@__ar_config_snapshot) end it 'confirms a websocket server has been started' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 73aa41101..b9a260367 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -271,6 +271,8 @@ require 'socket' # Generate a token for the server to respond with BeEF::Core::Crypto::api_token + disconnect_all_active_record! + # Initiate server start-up BeEF::API::Registrar.instance.fire(BeEF::API::Server, 'pre_http_start', http_hook_server) pid = fork do