Upgrading sidekiq 6 to 7
Breaking6.5.12 → 7.3.10Breaking1Security3Deprecated2New15Changed13Fixed22Other2
Fetching 34 releases from GitHub…16 / 34
SecurityWeb UI no longer allows extensions to use script tags and CSP disallows inline scripts, making Sidekiq immune to XSS.#6270 ↗
BreakingUpgrade verdict
1 breaking change and 3 security fixes.
In plain terms
- Sidekiq no longer silently fixes incorrect Redis command calls, so code that passed arguments in a non-native way may now raise errors.
- Web UI add-ons can no longer inject inline scripts, which closes off a cross-site scripting attack path.
- A security flaw in the metrics filtering feature could let attackers inject malicious scripts. It was introduced in version 7.2.0 and is now fixed.
- The web dashboard no longer allows inline JavaScript to run, closing a security hole.
Must act Top 5 of 6 that need code or config changes
Ruby requirement changed in 7.0.0.beta1: >= 2.5.0 → >= 2.7.0.
What you must change
Breaking1
Adjusts the redis-client adapter to avoid
method_missing, which can break app code relying on the adapter to correct invalid redis-client API usage.Sidekiq.redisSecurity3
Web UI no longer allows extensions to use script tags and CSP disallows inline scripts, making Sidekiq immune to XSS.
Fixes an XSS vulnerability in metrics filtering introduced in 7.2.0, tracked as CVE-2024-32887.
Moderate · CVSS 5.5Forbids inline JavaScript execution in the Web UI.
Deprecations to plan for
Deprecated2
Deprecates passing Redis :password as a String to avoid log disclosure; use a Proc instead.
config.redispasswordDeprecates direct access to attributes within the hash block parameter; use Sidekiq::Work accessor methods instead.
Sidekiq::WorkAPI changes
Generated by DepDelta from published Ruby source. Not mixed with prose notes.
- removed:
const Sidekiq.DEFAULTS - removed:
const Sidekiq.DEFAULT_ERROR_HANDLER - removed:
const Sidekiq.FAKE_INFO - removed:
const Sidekiq.Job - removed:
static method Sidekiq.[](_) - removed:
static method Sidekiq.[]=(_, _) - removed:
static method Sidekiq.client_middleware() - removed:
static method Sidekiq.death_handlers() - removed:
static method Sidekiq.default_error_handler(_, _) - removed:
static method Sidekiq.default_server_middleware() - removed:
static method Sidekiq.default_worker_options() - removed:
static method Sidekiq.error_handlers() - removed:
static method Sidekiq.fetch(*) - removed:
static method Sidekiq.handle_exception(_, _ = …) - removed:
static method Sidekiq.log_formatter() - removed:
static method Sidekiq.merge!(_) - removed:
static method Sidekiq.on(_) - removed:
static method Sidekiq.options() - removed:
static method Sidekiq.redis_info() - removed:
static method Sidekiq.server_middleware() - removed:
static set Sidekiq.average_scheduled_poll_interval(_) - removed:
static set Sidekiq.concurrency(_) - removed:
static set Sidekiq.default_worker_options(_) - removed:
static set Sidekiq.log_formatter(_) - removed:
static set Sidekiq.logger(_) - removed:
static set Sidekiq.options(_) - removed:
static set Sidekiq.queues(_) - removed:
static set Sidekiq.redis(_) - added:
const Sidekiq.MAJOR - added:
const Sidekiq.Worker - added:
module ActiveJob - added:
static method Sidekiq.configure_embed() - added:
static method Sidekiq.default_configuration() - added:
static method Sidekiq.freeze!() - added:
static method Sidekiq.gem_version()
- added:
module QueueAdapters
- added:
class SidekiqAdapter - added:
method SidekiqAdapter.enqueue(_) - added:
method SidekiqAdapter.enqueue_after_transaction_commit?() - added:
method SidekiqAdapter.enqueue_all(_) - added:
method SidekiqAdapter.enqueue_at(_, _)
- added:
class JobWrapper < Sidekiq::ActiveJob::Wrapper
- removed:
const Extensions.SIZE_LIMIT - removed:
const Metrics.Counter - removed:
const WebApplication.CSP_HEADER - removed:
constructor Logger(*, **) - removed:
method DeadSet.retry_all() - removed:
method LoggingUtils.add(_, _ = …, _ = …) - removed:
method RetrySet.kill_all() - removed:
method RetrySet.retry_all() - removed:
method TestingClient.raw_push(_) - removed:
method WebHelpers.namespace() - removed:
method WebHelpers.redis_connection() - removed:
method WebHelpers.redis_connection_and_namespace() - removed:
method Worker.logger() - removed:
module Extensions - removed:
module Worker - removed:
property Launcher.fetcher: accessor - removed:
property Launcher.manager: accessor - removed:
property Worker.jid: accessor - removed:
set Web.sessions(_) - removed:
static method DeadSet.max_jobs() - removed:
static method DeadSet.timeout() - removed:
static method Extensions.enable_delay!() - removed:
static method Testing.constantize(_) - removed:
static property RedisConnection.adapter: reader - removed:
static property Testing.__test_mode: accessor - removed:
static set RedisConnection.adapter(_) - removed:
static set Web.session_secret(_) - removed:
static set Web.sessions(_) - changed:
constructor Client(_ = …) → constructor Client(*, **) - changed:
constructor JobLogger(_ = …) → constructor JobLogger(_) - changed:
constructor Launcher(_) → constructor Launcher(_, embedded: …) - changed:
constructor Manager(_ = …) → constructor Manager(_) - changed:
constructor TransactionAwareClient(_) → constructor TransactionAwareClient(pool: …, config: …) - changed:
method BasicFetch.bulk_requeue(_, _) → method BasicFetch.bulk_requeue(_) - changed:
method CLI.run(boot_app: …) → method CLI.run(boot_app: …, warmup: …) - changed:
method Launcher.run() → method Launcher.run(async_beat: …) - changed:
method WebAction.route_params() → method WebAction.route_params(_ = …) - changed:
method WebHelpers.filtering(*) → method WebHelpers.filtering(_) - changed:
method WebHelpers.number_with_delimiter(_) → method WebHelpers.number_with_delimiter(_, _ = …) - changed:
method WebRouter.route(_, _) → method WebRouter.route(*, _) - changed:
static method Client.push_bulk(_) → static method Client.push_bulk(...) - changed:
static method CurrentAttributes.persist(_) → static method CurrentAttributes.persist(_, _ = …) - changed:
static method Web.register(_) → static method Web.register(_, name: …, tab: …, index: …, root_dir: …, cache_for: …, asset_paths: …) - added:
class Capsule - added:
class Config - added:
class Deploy - added:
class Embedded - added:
class Work - added:
const CLI.HOLIDAY_COLORS - added:
const Config.DEFAULTS - added:
const Config.ERROR_HANDLER - added:
const Deploy.LABEL_MAKER - added:
const Deploy.MARK_TTL - added:
const JobRecord.ACTIVE_JOB_PREFIX - added:
const JobRecord.GLOBALID_KEY - added:
const Paginator.TYPE_CACHE - added:
const RedisClientAdapter.DEPRECATED_COMMANDS - added:
const Web.CONTENT_LANGUAGE - added:
const Web.CONTENT_SECURITY_POLICY - added:
const Web.LOCATION - added:
const Web.X_CASCADE - added:
const Web.X_CONTENT_TYPE_OPTIONS - added:
const WebApplication.CSP_HEADER_TEMPLATE - added:
const WebApplication.METRICS_PERIODS - added:
constructor Capsule(_, _) - added:
constructor Config(_ = …) - added:
constructor Deploy(_ = …) - added:
constructor Embedded(_) - added:
constructor Work(_, _, _) - added:
method Capsule.client_middleware() - added:
method Capsule.fetcher() - added:
method Capsule.local_redis_pool() - added:
method Capsule.logger() - added:
method Capsule.lookup(_) - added:
method Capsule.redis() - added:
method Capsule.redis_pool() - added:
method Capsule.server_middleware() - added:
method Capsule.stop() - added:
method Client.cancel!(_) - added:
method Component.inspect() - added:
method Config.capsule(_) - added:
method Config.client_middleware() - added:
method Config.concurrency() - added:
method Config.death_handlers() - added:
method Config.default_capsule() - added:
method Config.error_handlers() - added:
method Config.freeze!() - added:
method Config.handle_exception(_, _ = …) - added:
method Config.inspect() - added:
method Config.logger() - added:
method Config.lookup(_, _ = …) - added:
method Config.new_redis_pool(_, _ = …) - added:
method Config.on(_) - added:
method Config.queues() - added:
method Config.redis() - added:
method Config.redis_info() - added:
method Config.redis_pool() - added:
method Config.register(_, _) - added:
method Config.server_middleware() - added:
method Config.to_json(*) - added:
method Config.total_concurrency() - added:
method DeadSet.trim() - added:
method Deploy.fetch(_ = …) - added:
method Deploy.mark!(at: …, label: …) - added:
method Embedded.quiet() - added:
method Embedded.run() - added:
method Embedded.stop() - added:
method Job.interrupted?() - added:
method Job.logger() - added:
method JobRecord.bid() - added:
method JobSet.kill_all(notify_failure: …, ex: …) - added:
method JobSet.pop_each() - added:
method JobSet.retry_all() - added:
method Launcher.heartbeat() - added:
method Process.embedded?() - added:
method Process.version() - added:
method Process.weights() - added:
method Processor.stopping?() - added:
method TestingClient.atomic_push(_, _) - added:
method TransactionAwareClient.batching?() - added:
method WebAction.reload_page() - added:
method WebAction.url_params(_) - added:
method WebApplication.process_csp(_, _) - added:
method WebHelpers.busy_weights(_) - added:
method WebHelpers.csp_nonce() - added:
method WebHelpers.filter_link(_, _ = …) - added:
method WebHelpers.pollable?() - added:
method WebHelpers.redis_url() - added:
method WebHelpers.script_tag(_, **) - added:
method WebHelpers.search(_, _) - added:
method WebHelpers.style_tag(_, **) - added:
method WebHelpers.to_json(_) - added:
method Work.[](_) - added:
method Work.job() - added:
method Work.payload() - added:
method Work.queue() - added:
method Work.raw(_) - added:
method Work.run_at() - added:
method WorkSet.find_work_by_jid(_) - added:
module ActiveJob - added:
module IterableJob - added:
property Capsule.concurrency: accessor - added:
property Capsule.mode: reader - added:
property Capsule.name: reader - added:
property Capsule.queues: reader - added:
property Capsule.weights: reader - added:
property Config.capsules: reader - added:
property Job._context: accessor - added:
property Job.jid: accessor - added:
property Launcher.managers: accessor - added:
property Manager.capsule: reader - added:
property Processor.capsule: reader - added:
property Work.process_id: reader - added:
property Work.thread_id: reader - added:
set Capsule.queues(_) - added:
set Config.average_scheduled_poll_interval(_) - added:
set Config.concurrency(_) - added:
set Config.logger(_) - added:
set Config.queues(_) - added:
set Config.redis(_) - added:
static method CLI.day() - added:
static method Deploy.mark!(_ = …) - added:
static method ProcessSet.[](_) - added:
static method Testing.__local_test_mode() - added:
static method Testing.__test_mode() - added:
static method Web.configure() - added:
static method Web.custom_job_info_rows() - added:
static property Testing.__global_test_mode: accessor - added:
static set Testing.__local_test_mode(_)
- added:
class Wrapper - added:
method Wrapper.perform(_)
- removed:
class DelayedClass - removed:
class DelayedMailer - removed:
class DelayedModel - removed:
class Proxy < BasicObject - removed:
constructor Proxy(_, _, _ = …) - removed:
method ActionMailer.delay(_ = …) - removed:
method ActionMailer.delay_for(_, _ = …) - removed:
method ActionMailer.delay_until(_, _ = …) - removed:
method ActionMailer.sidekiq_delay(_ = …) - removed:
method ActionMailer.sidekiq_delay_for(_, _ = …) - removed:
method ActionMailer.sidekiq_delay_until(_, _ = …) - removed:
method ActiveRecord.delay(_ = …) - removed:
method ActiveRecord.delay_for(_, _ = …) - removed:
method ActiveRecord.delay_until(_, _ = …) - removed:
method ActiveRecord.sidekiq_delay(_ = …) - removed:
method ActiveRecord.sidekiq_delay_for(_, _ = …) - removed:
method ActiveRecord.sidekiq_delay_until(_, _ = …) - removed:
method DelayedClass.perform(_) - removed:
method DelayedMailer.perform(_) - removed:
method DelayedModel.perform(_) - removed:
method Klass.delay(_ = …) - removed:
method Klass.delay_for(_, _ = …) - removed:
method Klass.delay_until(_, _ = …) - removed:
method Klass.sidekiq_delay(_ = …) - removed:
method Klass.sidekiq_delay_for(_, _ = …) - removed:
method Klass.sidekiq_delay_until(_, _ = …) - removed:
method PsychAutoload.resolve_class(_) - removed:
module ActionMailer - removed:
module ActiveRecord - removed:
module Klass - removed:
module PsychAutoload
- added:
class InterruptHandler - added:
class Interrupted < ::RuntimeError - added:
class Setter - added:
const Iterable.CANCELLATION_PERIOD - added:
const Iterable.STATE_FLUSH_INTERVAL - added:
const Iterable.STATE_TTL - added:
constructor Iterable() - added:
constructor Setter(_, _) - added:
method ClassMethods.build_client() - added:
method ClassMethods.client_push(_) - added:
method ClassMethods.delay(*) - added:
method ClassMethods.delay_for(*) - added:
method ClassMethods.delay_until(*) - added:
method ClassMethods.perform_async(*) - added:
method ClassMethods.perform_at(_, *) - added:
method ClassMethods.perform_bulk(*, **) - added:
method ClassMethods.perform_in(_, *) - added:
method ClassMethods.perform_inline(*) - added:
method ClassMethods.perform_sync(*) - added:
method ClassMethods.queue_as(_) - added:
method ClassMethods.set(_) - added:
method ClassMethods.sidekiq_options(_ = …) - added:
method InterruptHandler.call(_, _, _) - added:
method Iterable.arguments() - added:
method Iterable.around_iteration() - added:
method Iterable.build_enumerator(*) - added:
method Iterable.cancel!() - added:
method Iterable.cancelled?() - added:
method Iterable.each_iteration(*) - added:
method Iterable.iteration_key() - added:
method Iterable.on_complete() - added:
method Iterable.on_resume() - added:
method Iterable.on_start() - added:
method Iterable.on_stop() - added:
method Iterable.perform(*) - added:
method Setter.perform_async(*) - added:
method Setter.perform_at(_, *) - added:
method Setter.perform_bulk(_, batch_size: …) - added:
method Setter.perform_in(_, *) - added:
method Setter.perform_inline(*) - added:
method Setter.perform_sync(*) - added:
method Setter.set(_) - added:
module Iterable - added:
module Options
- added:
class ActiveRecordEnumerator - added:
class CsvEnumerator - added:
constructor ActiveRecordEnumerator(_, cursor: …, **) - added:
constructor CsvEnumerator(_) - added:
method ActiveRecordEnumerator.batches() - added:
method ActiveRecordEnumerator.records() - added:
method ActiveRecordEnumerator.relations() - added:
method CsvEnumerator.batches(cursor:, batch_size: …) - added:
method CsvEnumerator.rows(cursor:) - added:
method Enumerators.active_record_batches_enumerator(_, cursor:, **) - added:
method Enumerators.active_record_records_enumerator(_, cursor:, **) - added:
method Enumerators.active_record_relations_enumerator(_, cursor:, **) - added:
method Enumerators.array_enumerator(_, cursor:) - added:
method Enumerators.csv_batches_enumerator(_, cursor:, **) - added:
method Enumerators.csv_enumerator(_, cursor:) - added:
module ClassMethods - added:
module Enumerators
- added:
method ClassMethods.get_sidekiq_options() - added:
method ClassMethods.sidekiq_class_attribute(*) - added:
method ClassMethods.sidekiq_options(_ = …) - added:
method ClassMethods.sidekiq_retries_exhausted() - added:
method ClassMethods.sidekiq_retry_in() - added:
module ClassMethods
- added:
class ACCESSOR_MUTEX < Mutex.new
- removed:
class Deploy - removed:
const Deploy.MARK_TTL - removed:
const ExecutionTracker.LONG_TERM - removed:
const ExecutionTracker.MID_TERM - removed:
constructor Deploy(_ = …) - removed:
method Deploy.fetch(_ = …) - removed:
method Deploy.mark(at: …, label: …) - changed:
method Query.top_jobs(minutes: …) → method Query.top_jobs(class_filter: …, minutes: …) - added:
class Counter - added:
const Histogram.HISTOGRAM_TTL - added:
constructor Counter() - added:
method Counter.increment() - added:
method Counter.value()
- added:
method Chain.copy_for(_) - added:
method Chain.include?(_)
- added:
method Reloader.to_hash()
- removed:
method CompatClient._client() - removed:
method CompatClient.connection() - removed:
method CompatClient.disconnect!() - removed:
method CompatClient.message() - removed:
method CompatClient.redis() - removed:
method CompatClient.subscribe(_) - removed:
method CompatMethods.brpop(*) - removed:
method CompatMethods.brpoplpush(*) - removed:
method CompatMethods.exists?(_) - removed:
method CompatMethods.set(*) - removed:
method CompatMethods.sismember(*) - added:
const CompatMethods.USED_COMMANDS - added:
method CompatClient.config()
- removed:
class RedisAdapter - removed:
const RedisAdapter.BaseError - removed:
const RedisAdapter.CommandError - removed:
constructor RedisAdapter(_) - removed:
method RedisAdapter.new_client()
- changed:
constructor Enq() → constructor Enq(_)
- removed:
class Queues - removed:
method Queues.lengths() - changed:
constructor History(_, _ = …) → constructor History(_, _ = …, pool: …)
- added:
class TestModeAlreadySetError < RuntimeError
- removed:
class Setter - removed:
constructor Setter(_, _) - removed:
method ClassMethods.build_client() - removed:
method ClassMethods.client_push(_) - removed:
method ClassMethods.delay(*) - removed:
method ClassMethods.delay_for(*) - removed:
method ClassMethods.delay_until(*) - removed:
method ClassMethods.perform_async(*) - removed:
method ClassMethods.perform_at(_, *) - removed:
method ClassMethods.perform_bulk(*, **) - removed:
method ClassMethods.perform_in(_, *) - removed:
method ClassMethods.perform_inline(*) - removed:
method ClassMethods.perform_sync(*) - removed:
method ClassMethods.queue_as(_) - removed:
method ClassMethods.set(_) - removed:
method ClassMethods.sidekiq_options(_ = …) - removed:
method Setter.perform_async(*) - removed:
method Setter.perform_at(_, *) - removed:
method Setter.perform_bulk(_, batch_size: …) - removed:
method Setter.perform_in(_, *) - removed:
method Setter.perform_inline(*) - removed:
method Setter.perform_sync(*) - removed:
method Setter.set(_) - removed:
module ClassMethods - removed:
module Options
- removed:
method ClassMethods.get_sidekiq_options() - removed:
method ClassMethods.sidekiq_class_attribute(*) - removed:
method ClassMethods.sidekiq_options(_ = …) - removed:
method ClassMethods.sidekiq_retries_exhausted() - removed:
method ClassMethods.sidekiq_retry_in() - removed:
module ClassMethods
- removed:
class ACCESSOR_MUTEX < Mutex.new