Snyk has a proof-of-concept or detailed explanation of how to exploit this vulnerability.
The probability is the direct output of the EPSS model, and conveys an overall sense of the threat of exploitation in the wild. The percentile measures the EPSS probability relative to all known EPSS scores. Note: This data is updated daily, relying on the latest available EPSS model version. Check out the EPSS documentation for more details.
In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.
Test your applicationsUpgrade activeadmin
to version 2.12.0 or higher.
Affected versions of this package are vulnerable to Information Exposure due to a concurrency issue that results in a shared variable not being properly synchronized. An attacker with access to the same ActiveAdmin application can obtain private data intended for another user by timing their request to coincide with the victim's CSV export action or by frequently requesting CSV exports in the hope of a concurrent request occurring.
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
# Use local changes or ActiveAdmin master.
if ENV["ACTIVE_ADMIN_PATH"]
gem "activeadmin", path: ENV["ACTIVE_ADMIN_PATH"], require: false
else
gem "activeadmin", github: "activeadmin/activeadmin", require: false
end
# Change Rails version if necessary.
gem "rails", "6.1.4"
gem "sprockets", "3.7.2"
gem "sassc-rails", "2.1.2"
gem "sqlite3", "1.4.2", platform: :mri
gem "activerecord-jdbcsqlite3-adapter", "61.0", platform: :jruby
end
require "active_record"
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :active_admin_comments, force: true do |_t|
end
create_table :users, force: true do |t|
t.string :full_name
end
end
require "action_controller/railtie"
require "action_view/railtie"
require "active_admin"
class TestApp < Rails::Application
config.root = __dir__
config.session_store :cookie_store, key: "cookie_store_key"
secrets.secret_token = "secret_token"
secrets.secret_key_base = "secret_key_base"
config.eager_load = false
config.logger = Logger.new($stdout)
config.hosts = "www.example.com"
end
class ApplicationController < ActionController::Base
include Rails.application.routes.url_helpers
end
class User < ActiveRecord::Base
end
class TestSpy
attr_reader :count
def initialize
@count = 0
end
def increment
@count += 1
end
def reset
@count = 0
end
end
TEST_SPY = TestSpy.new
ActiveAdmin.setup do |config|
# Authentication disabled by default. Override if necessary.
config.authentication_method = false
config.current_user_method = false
end
Rails.application.initialize!
ActiveAdmin.register_page "Dashboard" do
menu priority: 1, label: proc { I18n.t("active_admin.dashboard") }
content do
"Test Me"
end
end
ActiveAdmin.register User do
actions :index
controller do
def find_collection(*)
TEST_SPY.increment
# Rails.logger.debug { ">> FETCHING COLLECTION\n#{caller.join("\n")}" }
super
end
end
end
Rails.application.routes.draw do
ActiveAdmin.routes(self)
end
require "minitest/autorun"
require "rack/test"
require "rails/test_help"
# Replace this with the code necessary to make your test fail.
class BugTest < ActionDispatch::IntegrationTest
def test_csv_fetches_collection_once
user = User.create! full_name: 'John Doe'
TEST_SPY.reset
get admin_users_url(format: :csv)
csv_response_body = response.body.delete('')
assert_equal "Id,Full name\n#{user.id},John Doe\n", csv_response_body
assert_response :success
assert_equal 1, TEST_SPY.count
end
def test_html_fetches_collection_once
User.create! full_name: 'John Doe'
TEST_SPY.reset
get admin_users_url
assert_match /John Doe/, response.body
assert_response :success
assert_equal 1, TEST_SPY.count
end
private
def app
Rails.application
end
end