Container Escape in Hanami with Dynamodb
Container Escape in Hanami with Dynamodb — how this specific combination creates or exposes the vulnerability
A container escape in a Hanami application that uses DynamoDB typically arises when the runtime environment of the container is improperly isolated from the host or from other containers, and the application logic interacts with DynamoDB in a way that reflects underlying system or configuration details. Hanami, being a Ruby framework that emphasizes modularity and explicit architecture, can inadvertently expose host-level paths, environment variables, or debug endpoints when container security controls are weak.
In this scenario, an attacker who has achieved code execution within the Hanami container (for example, through an input validation flaw or unsafe code evaluation) may probe the container’s filesystem or process space to locate DynamoDB credentials or configuration. Because Hanami applications often load AWS SDK configurations from environment variables or shared credential files (e.g., ~/.aws/credentials), a container escape can lead to access to these files. Once an attacker reads these credentials, they can interact directly with DynamoDB outside the intended application context, bypassing the Hanami layer entirely.
Additionally, if the Hanami container runs with elevated privileges or mounts sensitive host directories (such as /proc or Docker socket paths), an attacker can leverage DynamoDB as a pivot point: exfiltrating data or modifying tables to maintain persistence or expand lateral movement. The DynamoDB endpoint itself is not vulnerable, but the combination of a compromised container and misconfigured IAM permissions tied to DynamoDB amplifies the impact, turning a potential isolated compromise into a broader infrastructure risk.
During a middleBrick scan, such misconfigurations may be reflected in security findings related to Authentication, Data Exposure, and Unsafe Consumption, especially when unauthenticated endpoints expose debug information or when environment variables containing AWS keys are detectable. The scanner cross-references runtime behavior with OpenAPI specifications and detects anomalies such as missing authentication on administrative routes or excessive permissions in IAM policies associated with DynamoDB.
Dynamodb-Specific Remediation in Hanami — concrete code fixes
Remediation focuses on reducing the attack surface available to a container and ensuring that DynamoDB interactions within Hanami follow least-privilege principles. Below are concrete code examples for a Hanami application using the AWS SDK for Ruby.
1. Use IAM Roles Instead of Embedded Credentials
Ensure that the container runs with an IAM role (e.g., via ECS task roles or EKS IRSA) so that no AWS access keys are present in environment variables or files. This limits what an attacker can do even if they escape the container.
2. Configure the AWS SDK Securely in Hanami
Initialize the DynamoDB client without hardcoded credentials and restrict the SDK to use only the expected endpoint and region. Avoid passing credentials explicitly.
require 'aws-sdk-dynamodb'
# Hanami initializer: config/initializers/dynamodb.rb
Hanami.configure do
config.dynamodb = Aws::DynamoDB::Client.new(
region: 'us-east-1',
# Do not set :access_key_id or :secret_access_key here
# Rely on IAM role or environment variables with restricted permissions
http_open_timeout: 2,
http_read_timeout: 5
)
end
# Usage in a service object
class FetchItemService
def initialize(client = Hanami.container['config.dynamodb'])
@client = client
end
def call(table_name, key)
@client.get_item(
table_name: table_name,
key: { id: { s: key } }
)
end
end
3. Validate and Sanitize Input Before DynamoDB Calls
Prevent injection and malformed requests by validating primary key formats and table names. This reduces the risk of an attacker manipulating inputs to probe container internals or trigger errors that leak paths or configuration.
class ValidateInput
def self.table_name?(name)
# Only allow alphanumeric and underscore, no special characters
name.match?(\A[a-zA-Z0-9_]+\z)
end
def self.partition_key?(key)
# Ensure key is a non-empty string of reasonable length
key.is_a?(String) && key.length.between?(1, 255)
end
end
# In a Hanami action
class ItemsController < Hanami::Action
def show
table = params[:table]
id = params[:id]
unless ValidateInput.table_name?(table) && ValidateInput.partition_key?(id)
halt 400, { error: 'Invalid input' }.to_json
end
result = FetchItemService.new.call(table, id)
response.body = result.to_json
end
end
4. Restrict Filesystem Access in Container Configuration
While not Ruby code, ensure your container definition (e.g., Dockerfile or Kubernetes pod spec) does not mount the Docker socket or host’s credential store. For Hanami, avoid volume mounts of /root/.aws or other sensitive paths unless strictly necessary.
5. Enable SDK Logging at Appropriate Level
Avoid verbose logging that could expose sensitive data or internal paths. Configure the AWS SDK logger to warn or error level only.
# config/initializers/aws_logger.rb
require 'aws-sdk-dynamodb'
Aws.config[:logger] = Logger.new($stdout)
Aws.config[:logger].level = Logger::WARN