Console1984

repository·master·Indexed 21 days ago

https://github.com/basecamp/console1984

A Rails extension for protecting sensitive data access in production consoles. It enforces audit trails, restricts access to encrypted data and external systems (like Redis or Elasticsearch) in protected mode, and requires a justification to enter unprotected mode. It includes session logging, automatic session incineration, and mechanisms to prevent unauthorized actions via Console1984::Shield and Console1984::CommandValidator.

Tokens
7.6K
Snippets
28
Records
42
Agent score
73%

What's inside console1984

  1. Test against multiple Rails versions using Appraisal

    master

    This project uses the Appraisal gem to manage testing across multiple Rails versions. The version matrix is defined in the Appraisals file, and specific gemfiles are generated in the gemfiles/ directory.

    Use bundle exec appraisal [version] [command] to run tests against a specific version, or run bundle exec appraisal [command] to run the command against all defined versions in the matrix.

    # Run against a specific Rails version
    bundle exec appraisal rails-8-0 bin/rails test
    
    # Run against all Rails versions
    bundle exec appraisal bin/rails test
    
    # Regenerate gemfiles after changing the Appraisals file
    bundle exec appraisal install
  2. Set up CONSOLE_USER via SSH

    master

    To automatically identify users in the console, you can pass the CONSOLE_USER environment variable through SSH.

    1. On the Server: Edit /etc/ssh/sshd_config to allow the variable:

      AcceptEnv LANG LC_* CONSOLE_USER

      Then restart the SSH service: service sshd restart.

    2. On the Client: Add the variable to your SSH config (~/.ssh/config):

      Host *
        SetEnv CONSOLE_USER=your_name
    # Server: /etc/ssh/sshd_config
    AcceptEnv LANG LC_* CONSOLE_USER
    
    # Client: ~/.ssh/config
    Host *
      SetEnv CONSOLE_USER=david
  3. Install Console1984

    master

    Console1984 is a Rails console extension for protecting sensitive data access and providing audit trails.

    Prerequisites:

    • Rails 7+ (requires Active Record encryption).
    • You must configure Active Record Encryption in your project, as the library uses it to store tracked console commands encrypted.

    Steps:

    1. Add the gem to your Gemfile:
      gem 'console1984'
    2. Run the installation generator and migrate your database to create the necessary activity tracking tables:
      rails console1984:install:migrations
      rails db:migrate
    gem 'console1984'
  4. How to access encrypted data in the Rails console

    master

    By default, Console1984 operates in protected mode, where data encrypted with Active Record encryption is shown as ciphertext.

    To access the decrypted values:

    1. Run the decrypt! command in the console.
    2. Provide a justification (e.g., a URL for user consent) when prompted.
    3. Once in unprotected mode, you can view decrypted data.

    Warning: While in unprotected mode, avoid saving objects that were loaded. This can result in accidentally saving ciphertext into unencrypted columns.

    To return to protected mode, run the encrypt! command.

    irb(main)> Topic.last.name
    => "{\"p\":\"iu6+LfnNlurC6sL++JyOIDvedjNSz/AvnZQ=\"...}"
    
    irb(main)> decrypt!
    # [Prompt for justification]
    
    irb(main)> Topic.last.name
    => "Thanks for the inspiration"
    
    irb(main)> encrypt!
  5. Run the test suite against different databases

    master

    The test suite uses SQLite by default. To run tests against other databases like MySQL or PostgreSQL, you must first set up the necessary Docker containers and databases using bin/setup. Once setup is complete, you can specify the target database using the TARGET_DB environment variable.

    bin/setup
    bin/rails test # against SQLite (default)
    bin/rails test TARGET_DB=mysql
    bin/rails test TARGET_DB=postgres
    bin/rails test TARGET_DB=sqlite
  6. What is Console1984

    master

    Console1984 is an IRB-based Rails console extension designed to enhance security and auditing during interactive sessions. It provides three core capabilities:

    1. Session Logging: Records console sessions, including the user, the reason for access, and the commands entered. By default, it uses Console1984::SessionsLogger::Database to persist these logs.
    2. Data Protection: Protects encrypted data by displaying ciphertexts instead of decrypted values when the console is in protected mode.
    3. External System Protection: Restricts access to sensitive external systems (like Redis or Elasticsearch) when in protected mode.

    It also includes internal tampering prevention mechanisms via Console1984::Shield and Console1984::CommandValidator to prevent users from performing unauthorized actions, such as deleting audit trails.

  7. Understand Protected vs Unprotected modes

    master

    Console1984 operates in two distinct modes that dictate how commands are executed and how data is presented:

    • Protected Mode: The console will not show decrypted information (it shows ciphertexts instead) and will block connections to protected URLs/external systems.
    • Unprotected Mode: The console allows access to decrypted information and protected URLs. Commands executed in this mode are flagged as sensitive in the audit logs.

    Command execution and protection enforcement are managed by Console1984::CommandExecutor.

  8. How the Shield provides protection

    master

    The Console1984::Shield operates at two distinct levels of security:

    1. External Protection

    Prevents users from accessing encrypted data or protected external systems while the console is in a protected mode. This is achieved by extending socket classes (like TCPSocket and SSLSocket) and ActiveRecord adapters to intercept and audit network and database access.

    2. Internal Protection

    Prevents users from tampering with the Console1984 system itself. This is achieved by:

    • Freezing core Ruby classes and modules via refrigerator.freeze_all.
    • Using MethodInvocationShell to prevent the execution of forbidden methods.
    • Prepending extensions to core classes to enforce security constraints.
  9. How Console 1984 modes work

    master

    Console 1984 operates in two distinct security modes that control access to sensitive data and external connections:

    • Protected Mode: The default state. In this mode, the system will not reveal encrypted information and will prevent attempts to connect to protected URLs.
    • Unprotected Mode: A high-privilege state. In this mode, the system reveals encrypted information and allows all network connections to proceed.

    Note that certain security features, such as the prevention of tampering with audit trails, remain active in both modes.

  10. Prevent writing to protected network connections

    master

    The Console1984::Ext::Socket::TcpSocket module extends TCP socket methods to enforce security boundaries. When a socket connection is made to a URL defined in Console1984::Shield::Modes::PROTECTED_MODE.currently_protected_urls, any attempt to call write or write_nonblock will result in a Console1984::Errors::ProtectedConnection error.

    This mechanism ensures that sensitive data cannot be transmitted over network connections that have been flagged as protected by the system's shield modes.

    # This is a conceptual example of the error raised when attempting to write to a protected address
    begin
      socket.write("sensitive data")
    rescue Console1984::Errors::ProtectedConnection => e
      puts "Connection blocked: #{e.message}"
    end
  11. How Console1984::Freezeable works

    master

    The Console1984::Freezeable module is a security mechanism designed to prevent the manipulation of sensitive Console1984 classes during a session. It prevents adding new methods, changing class state, or accessing/overriding instance variables via reflection.

    Key Behaviors

    • Deferred Freezing: Including the module does not freeze the class immediately. Instead, the class is added to a registry (Console1984::Freezeable.to_freeze). Freezing only occurs when Console1984::Freezeable.freeze_all is explicitly called. This allows for controlled setup before the environment becomes immutable.
    • Instance Data Protection: It can prevent the use of sensitive methods like instance_variable_get and instance_variable_set to stop users from bypassing state protections via reflection.
    • Limitations: It does not prevent every possible state-modification command. For custom logic, you may need to override +#freeze+ or manually invoke freezing on specific instances.

    Implementation Pattern

    To make a class freezeable, include the module. The class will then be included in the global freeze list.

  12. Configure session incineration settings

    master

    Console1984 automatically deletes (incinerates) session logs after a certain period.

    • To change the duration: Set config.console1984.incinerate_after (defaults to 30.days).
    • To disable incineration: Set config.console1984.incinerate = false.

    Example configuration:

    config.console1984.incinerate_after = 1.year