Basecamp released a new gem recently, which is intended to be an extension to the Rails console to protect sensitive accesses and make them auditable. When they first mentioned it more than a year ago, I was sceptical about how would they make this work, and it looks like I was right, they even mention on their Readme the following:
console1984 uses Ruby to add several protection mechanisms. However, because Ruby is highly dynamic, it’s technically possible to circumvent most of these controls if you know what you are doing. We have made an effort to prevent such attempts, but if your organization needs bullet-proof protection against malicious actors using the console, you should consider additional security measures.
I thought I will give a try to come up a way to bypass the auditing and it only took a few minutes of looking at the source code and fooling around in a console.
After I figured out how are they storing the audit records, I figured I will just delete the records from the database with Console1984::Session.last.commands.destroy_all, but that raised an exception: Console1984::Errors::ForbiddenCommand.
I checked the sourcecode and noticed that they defined a list of auditable table names, so I just overrode that in the console:
After this, Console1984::Session.last.commands.destroy_all runs with no error, but I noticed that my session is still flagged as sensitive, so I fixed that with Console1984::Session.last.sensitive_accesses.destroy_all
I am sure there are a lot of other ways to circumvent the protection, and I would strongly advise against using this gem in any project, because it gives a false sense of security and doesn’t prevent any developer to access whatever they want in case they have access to a production console.
29 August 2021 Update
v0.1.5 fixed the above issue, but I still found and reported another way to bypass the protection. You can get a low level database connection and wipe your session if want to:
# if you need to get the database connection config: ActiveRecord::Base.send(:resolve_config_for_connection, :development)
conn = PG::Connection.open(:dbname => 'rails_edge_development')
conn.exec "delete from console1984_sessions"