Skip to content

Instantly share code, notes, and snippets.

@david-pm
Created August 9, 2019 02:47
Show Gist options
  • Save david-pm/748846ba853d2b48834f0cca6fce2b6e to your computer and use it in GitHub Desktop.
Save david-pm/748846ba853d2b48834f0cca6fce2b6e to your computer and use it in GitHub Desktop.
disable flushdb and flushall from ruby's redis client
# inspired by this article: https://www.honeybadger.io/leveling-up/safeguarding-redis/
# and adapted from this gist: https://gist.github.com/joshuap/c1ff2657c150df6fb1257398b1d2716b
#
# * needed a way to disable flushall and flushdb in Production only
# * wanted to add a way to add some basic tests for sanity and explicit documentation
#
############### config/initializers/redis.rb #########################
require 'redis'
require 'redis_dangerous_commands'
class Redis
prepend DangerousCommands
end
############### lib/redis_dangerous_commands.rb #########################
module DangerousCommands
class ProhibitedCommandError < StandardError; end
def self.prepended(base)
return unless Rails.env.production?
base.send(:define_method, :flushdb) do
raise ProhibitedCommandError, error_message('EMPTY THE ENTIRE DATABASE')
end
base.send(:define_method, :flushall) do
raise ProhibitedCommandError, error_message('FLUSH ALL DATABASES')
end
end
def error_message(inner_message)
"DANGEROUS destructive operation. If you really want to #{inner_message} do it from `redis-cli`."
end
end
############### spec/lib/redis_dangerous_commands_spec.rb #########################
describe 'DangerousCommands' do
context 'Production' do
let(:dumb) { Dummy.new }
before do
allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('production'))
class Dummy
prepend DangerousCommands
end
end
it 'raises ProhibitedCommandError' do
expect{ dumb.flushdb }.to raise_error DangerousCommands::ProhibitedCommandError
end
it 'raises ProhibitedCommandError' do
expect{ dumb.flushall }.to raise_error DangerousCommands::ProhibitedCommandError
end
end
context 'Non-production' do
let(:dumb) { DifferentDummy.new }
before do
class DifferentDummy
prepend DangerousCommands
end
end
it 'does not respond to flushdb' do
expect(dumb).not_to respond_to(:flushdb)
end
it 'does not respond to flushall' do
expect(dumb).not_to respond_to(:flushall)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment