CrackedRuby CrackedRuby

Overview

Network attacks target vulnerabilities in application architecture, protocol implementation, and data handling to compromise system security, steal data, or disrupt service availability. These attacks exploit weaknesses at various layers of the network stack, from application-level vulnerabilities in web frameworks to protocol-level flaws in network communication.

Understanding network attacks requires knowledge of both attack vectors and defense mechanisms. Attack vectors include injection attacks that manipulate data inputs, authentication bypass techniques that circumvent access controls, denial-of-service methods that overwhelm system resources, and man-in-the-middle attacks that intercept communications. Defense mechanisms involve input validation, output encoding, rate limiting, encryption, and secure session management.

Ruby web applications face specific attack surfaces through frameworks like Rails and Sinatra, database interfaces, HTTP client libraries, and API endpoints. The dynamic nature of Ruby and convention-over-configuration patterns in Rails can introduce vulnerabilities if developers rely solely on framework defaults without understanding underlying security principles.

Network attacks fall into several categories: injection attacks (SQL, command, LDAP), cross-site attacks (XSS, CSRF), authentication attacks (brute force, session hijacking), denial-of-service attacks (DDoS, resource exhaustion), and protocol attacks (man-in-the-middle, DNS spoofing). Each category requires distinct detection and mitigation strategies.

Key Principles

Attack Surface Reduction minimizes the number of potential entry points for attackers by disabling unnecessary services, closing unused ports, removing debug endpoints in production, and limiting API exposure. Applications should expose only required functionality and enforce strict access controls on all endpoints.

Defense in Depth implements multiple layers of security controls so that if one layer fails, others provide protection. This includes perimeter security (firewalls, load balancers), application security (input validation, authentication), data security (encryption, access controls), and monitoring (intrusion detection, logging). No single security control should be the sole protection mechanism.

Least Privilege Principle grants users, processes, and systems only the minimum permissions required for their function. Database users should have limited query permissions, application processes should run with restricted system access, and API clients should receive scoped tokens with specific capabilities rather than administrative access.

Input Validation and Output Encoding treats all external data as untrusted. Input validation verifies that data matches expected format, type, and range before processing. Output encoding ensures that data displayed to users or sent to other systems cannot be interpreted as executable code. These controls prevent injection attacks by enforcing strict data boundaries.

Secure Session Management protects user authentication state through secure session identifiers, appropriate timeout periods, and protection against session fixation and hijacking. Sessions should use cryptographically random identifiers, transmit over encrypted channels, and invalidate on logout or timeout.

Rate Limiting and Throttling prevents resource exhaustion attacks by restricting request frequency from individual clients. This includes limiting login attempts to prevent brute force attacks, throttling API requests to prevent abuse, and implementing backoff strategies for failed authentication attempts.

Security Headers configure HTTP response headers to enable browser-based security features. Headers like Content-Security-Policy restrict resource loading, X-Frame-Options prevents clickjacking, Strict-Transport-Security enforces HTTPS, and X-Content-Type-Options prevents MIME-type sniffing attacks.

Cryptographic Controls use strong encryption algorithms and proper key management to protect sensitive data. This includes encrypting data at rest and in transit, using secure random number generation for tokens and identifiers, and implementing proper certificate validation for SSL/TLS connections.

Security Implications

SQL Injection Attacks occur when applications construct database queries by concatenating user input without proper sanitization. Attackers inject malicious SQL code that executes within the database context, potentially reading sensitive data, modifying records, or executing administrative commands. The impact ranges from data theft to complete database compromise.

Rails provides protection through parameterized queries in ActiveRecord, but raw SQL queries and string interpolation bypass these protections. Applications using execute, find_by_sql, or building queries with string concatenation remain vulnerable. Additional risks arise from NoSQL databases where query language differences require different sanitization approaches.

Cross-Site Scripting (XSS) allows attackers to inject malicious JavaScript into web pages viewed by other users. Stored XSS persists in databases and executes whenever users view affected content. Reflected XSS executes through crafted URLs that victims click. DOM-based XSS manipulates client-side JavaScript without server involvement. All forms enable session hijacking, credential theft, and malicious actions performed in victim contexts.

Rails automatically escapes HTML output in views, but developers can disable this with html_safe or raw methods. JSON APIs that return unescaped user content for client-side rendering create XSS vulnerabilities. Rich text editors and markdown processors that allow HTML input require careful sanitization to prevent malicious script injection.

Cross-Site Request Forgery (CSRF) tricks authenticated users into executing unintended actions by submitting forged requests. Attackers craft malicious pages or links that submit requests to target applications using victim authentication cookies. Without CSRF protection, attackers can trigger state-changing operations like fund transfers, password changes, or data deletion.

Rails includes CSRF protection through authenticity tokens embedded in forms, but API endpoints and JavaScript-heavy applications often disable this protection. Applications accepting JSON requests without CSRF validation or using custom authentication schemes outside cookies remain vulnerable.

Command Injection exploits applications that execute system commands with unsanitized user input. Attackers inject shell metacharacters to execute arbitrary commands on the server. This occurs in applications using system, exec, backticks, or other shell execution methods with user-controlled data. Successful attacks grant attackers shell access with application process privileges.

Path Traversal manipulates file path inputs to access files outside intended directories. Attackers use sequences like ../ to navigate directory structures and read sensitive files like configuration files, source code, or system files. Applications serving user-uploaded files or generating reports from user-specified templates face this risk.

Server-Side Request Forgery (SSRF) tricks applications into making HTTP requests to unintended destinations. Attackers provide URLs pointing to internal services, metadata endpoints, or external systems. This exposes internal network topology, accesses cloud metadata services, or launches attacks against third-party systems appearing to originate from the victim server.

Denial of Service (DoS) overwhelms application resources to prevent legitimate access. Distributed DoS (DDoS) amplifies attacks across many sources. Attack vectors include flooding network bandwidth, exhausting connection pools, triggering expensive computations, or exploiting algorithmic complexity. Regular expression denial of service (ReDoS) uses specially crafted input to trigger exponential regex evaluation time.

Authentication Bypass circumvents access controls through various techniques including credential stuffing with leaked passwords, brute force attacks against weak passwords, session fixation to hijack sessions, timing attacks against comparison operations, and exploiting logic flaws in authentication code.

Ruby Implementation

Parameterized Queries prevent SQL injection by separating query structure from data values. ActiveRecord automatically parameterizes queries using placeholder syntax:

# Vulnerable: string interpolation
User.where("email = '#{params[:email]}'")

# Secure: parameterized query
User.where("email = ?", params[:email])
User.where(email: params[:email])

# Complex queries with multiple parameters
User.where("created_at > ? AND role = ?", 1.month.ago, params[:role])

# Named parameters for clarity
User.where("email = :email AND active = :active", 
  email: params[:email], 
  active: true
)

Output Encoding prevents XSS by escaping HTML entities in user content. Rails escapes output by default, but requires explicit handling for raw HTML:

# Automatic HTML escaping in ERB
<%= user.name %>  # Escapes HTML entities

# Dangerous: bypasses escaping
<%= raw(user.bio) %>
<%= user.bio.html_safe %>

# Secure: explicit sanitization
<%= sanitize(user.bio, tags: %w[p br strong em], attributes: %w[href]) %>

# For JSON APIs rendering user content
def show
  render json: {
    name: user.name,  # Already safe in JSON
    bio: sanitize(user.bio)  # Sanitize if client renders as HTML
  }
end

CSRF Protection validates authenticity tokens for state-changing requests. Rails includes CSRF protection by default:

class ApplicationController < ActionController::Base
  # Enabled by default in Rails
  protect_from_forgery with: :exception
  
  # For APIs using token authentication
  protect_from_forgery with: :null_session
  
  # Skip CSRF for specific actions (use carefully)
  skip_before_action :verify_authenticity_token, only: [:webhook]
end

# In views, forms include CSRF token automatically
<%= form_with model: @user do |f| %>
  <%= f.text_field :name %>
<% end %>

# For AJAX requests, include token in headers
# In application.js
document.addEventListener('DOMContentLoaded', () => {
  const token = document.querySelector('meta[name="csrf-token"]').content;
  // Set as default header for fetch requests
  fetch('/api/data', {
    method: 'POST',
    headers: {
      'X-CSRF-Token': token,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  });
});

Safe Command Execution avoids shell injection by using array argument format:

# Vulnerable: shell interpretation
filename = params[:file]
`convert #{filename} output.pdf`  # Shell injection risk

# Secure: array arguments bypass shell
system('convert', filename, 'output.pdf')

# Secure: spawn with explicit arguments
pid = spawn('convert', filename, 'output.pdf')
Process.wait(pid)

# Additional validation
def safe_filename?(filename)
  filename.match?(/\A[a-zA-Z0-9_\-\.]+\z/)
end

# Whitelist approach
ALLOWED_FORMATS = %w[jpg png gif].freeze

def convert_image(filename, format)
  raise ArgumentError unless ALLOWED_FORMATS.include?(format)
  raise ArgumentError unless safe_filename?(filename)
  
  system('convert', filename, "output.#{format}")
end

Path Traversal Prevention validates file paths against directory traversal:

require 'pathname'

class FileDownloadController < ApplicationController
  SAFE_DIRECTORY = Rails.root.join('uploads')
  
  def download
    filename = params[:filename]
    
    # Resolve to absolute path and verify containment
    requested_path = Pathname.new(File.join(SAFE_DIRECTORY, filename)).realpath
    
    unless requested_path.to_s.start_with?(SAFE_DIRECTORY.to_s)
      raise ActionController::BadRequest, 'Invalid file path'
    end
    
    send_file requested_path
  rescue Errno::ENOENT
    head :not_found
  end
end

# Alternative: whitelist approach
class ReportController < ApplicationController
  ALLOWED_REPORTS = {
    'sales' => 'reports/sales.pdf',
    'inventory' => 'reports/inventory.pdf'
  }.freeze
  
  def download
    report_key = params[:report]
    filepath = ALLOWED_REPORTS[report_key]
    
    raise ActionController::BadRequest unless filepath
    
    send_file Rails.root.join(filepath)
  end
end

SSRF Prevention validates and restricts outbound HTTP requests:

require 'resolv'

class WebhookService
  BLOCKED_NETWORKS = [
    IPAddr.new('127.0.0.0/8'),    # Localhost
    IPAddr.new('10.0.0.0/8'),     # Private network
    IPAddr.new('172.16.0.0/12'),  # Private network
    IPAddr.new('192.168.0.0/16'), # Private network
    IPAddr.new('169.254.0.0/16')  # Link-local
  ].freeze
  
  def self.safe_request(url)
    uri = URI.parse(url)
    
    # Validate scheme
    raise ArgumentError unless %w[http https].include?(uri.scheme)
    
    # Resolve hostname to IP
    ip_address = IPAddr.new(Resolv.getaddress(uri.host))
    
    # Check against blocked networks
    if BLOCKED_NETWORKS.any? { |network| network.include?(ip_address) }
      raise SecurityError, 'Request to private network blocked'
    end
    
    # Make request with timeout
    HTTP.timeout(5).get(url)
  rescue Resolv::ResolvError
    raise ArgumentError, 'Cannot resolve hostname'
  end
end

# Usage with explicit validation
def process_webhook
  url = params[:callback_url]
  
  # Validate URL format
  raise ArgumentError unless url.match?(/\Ahttps?:\/\//)
  
  response = WebhookService.safe_request(url)
  # Process response
end

Rate Limiting restricts request frequency to prevent abuse:

# Using Rack::Attack gem
class Rack::Attack
  # Throttle login attempts
  throttle('logins/ip', limit: 5, period: 20.seconds) do |req|
    req.ip if req.path == '/login' && req.post?
  end
  
  # Throttle API requests per user
  throttle('api/user', limit: 100, period: 1.hour) do |req|
    req.env['current_user']&.id if req.path.start_with?('/api/')
  end
  
  # Block suspicious requests
  blocklist('block suspicious IPs') do |req|
    SuspiciousIP.exists?(address: req.ip)
  end
  
  # Exponential backoff for failed logins
  self.throttled_responder = lambda do |env|
    retry_after = (env['rack.attack.match_data'] || {})[:period]
    [
      429,
      {'Content-Type' => 'application/json', 'Retry-After' => retry_after.to_s},
      [{error: 'Rate limit exceeded'}.to_json]
    ]
  end
end

# Custom rate limiting implementation
class LoginController < ApplicationController
  def create
    identifier = "login_attempt:#{request.ip}"
    attempts = Rails.cache.read(identifier).to_i
    
    if attempts >= 5
      render json: {error: 'Too many attempts'}, status: :too_many_requests
      return
    end
    
    user = User.authenticate(params[:email], params[:password])
    
    if user
      Rails.cache.delete(identifier)
      session[:user_id] = user.id
      render json: {success: true}
    else
      Rails.cache.write(identifier, attempts + 1, expires_in: 15.minutes)
      render json: {error: 'Invalid credentials'}, status: :unauthorized
    end
  end
end

Practical Examples

Complete SQL Injection Prevention requires careful handling of dynamic queries:

class UserSearchController < ApplicationController
  def search
    query = params[:query]
    sort_column = params[:sort] || 'created_at'
    sort_direction = params[:direction] || 'desc'
    
    # Validate sort parameters against whitelist
    allowed_columns = %w[name email created_at]
    allowed_directions = %w[asc desc]
    
    unless allowed_columns.include?(sort_column) && 
           allowed_directions.include?(sort_direction)
      raise ActionController::BadRequest
    end
    
    # Safe parameterized query with validated dynamic ordering
    @users = User.where("name LIKE ? OR email LIKE ?", 
                        "%#{query}%", "%#{query}%")
                 .order("#{sort_column} #{sort_direction}")
                 .limit(50)
    
    render json: @users
  end
end

# Complex query builder with multiple optional filters
class ProductSearchService
  def self.search(params)
    query = Product.all
    
    if params[:category].present?
      query = query.where(category_id: params[:category])
    end
    
    if params[:min_price].present?
      query = query.where("price >= ?", params[:min_price])
    end
    
    if params[:max_price].present?
      query = query.where("price <= ?", params[:max_price])
    end
    
    if params[:search].present?
      query = query.where("name ILIKE ?", "%#{sanitize_sql_like(params[:search])}%")
    end
    
    query.order(created_at: :desc)
  end
  
  def self.sanitize_sql_like(string)
    string.gsub(/[%_]/, '\\\\\0')
  end
end

XSS Prevention in Rich Text Content balances functionality with security:

class ArticleController < ApplicationController
  # Using Rails HTML sanitizer
  def create
    @article = Article.new(article_params)
    
    # Sanitize rich text content
    @article.content = sanitize_content(@article.content)
    
    if @article.save
      render json: @article
    else
      render json: {errors: @article.errors}, status: :unprocessable_entity
    end
  end
  
  private
  
  def sanitize_content(html)
    # Allow specific safe tags and attributes
    sanitize(html, 
      tags: %w[p br strong em ul ol li a h2 h3 blockquote code pre],
      attributes: %w[href title]
    )
  end
  
  def article_params
    params.require(:article).permit(:title, :content, :excerpt)
  end
end

# For markdown content with syntax highlighting
require 'redcarpet'
require 'rouge'
require 'rouge/plugins/redcarpet'

class MarkdownRenderer < Redcarpet::Render::HTML
  include Rouge::Plugins::Redcarpet
  
  def initialize(extensions = {})
    super(extensions.merge(
      filter_html: true,        # Strip HTML tags
      no_styles: true,          # Remove inline styles
      safe_links_only: true,    # Only allow safe URL schemes
      link_attributes: {rel: 'nofollow', target: '_blank'}
    ))
  end
end

class CommentService
  MARKDOWN = Redcarpet::Markdown.new(
    MarkdownRenderer.new,
    autolink: true,
    tables: true,
    fenced_code_blocks: true,
    no_intra_emphasis: true,
    strikethrough: true
  )
  
  def self.render_comment(raw_content)
    # Markdown processing with HTML sanitization
    html = MARKDOWN.render(raw_content)
    
    # Additional sanitization pass
    sanitize(html, tags: %w[p br strong em ul ol li a code pre blockquote],
                   attributes: %w[href rel target class])
  end
end

Comprehensive Authentication Security implements multiple protective layers:

class SessionsController < ApplicationController
  before_action :rate_limit_login, only: [:create]
  
  def create
    user = User.find_by(email: params[:email])
    
    # Constant-time comparison to prevent timing attacks
    if user&.authenticate(params[:password])
      # Check for account lockout
      if user.locked?
        render json: {error: 'Account locked'}, status: :forbidden
        return
      end
      
      # Reset failed attempts
      user.update(failed_login_attempts: 0, locked_at: nil)
      
      # Regenerate session ID to prevent fixation
      reset_session
      session[:user_id] = user.id
      session[:created_at] = Time.current
      
      # Log successful login
      LoginAudit.create(
        user: user,
        ip_address: request.ip,
        user_agent: request.user_agent,
        status: 'success'
      )
      
      render json: {success: true, user: user.as_json(only: [:id, :email, :name])}
    else
      # Record failed attempt
      if user
        user.increment!(:failed_login_attempts)
        
        # Lock account after threshold
        if user.failed_login_attempts >= 5
          user.update(locked_at: Time.current)
        end
      end
      
      # Log failed attempt
      LoginAudit.create(
        email: params[:email],
        ip_address: request.ip,
        user_agent: request.user_agent,
        status: 'failed'
      )
      
      # Generic error message to prevent user enumeration
      render json: {error: 'Invalid credentials'}, status: :unauthorized
    end
  end
  
  private
  
  def rate_limit_login
    identifier = "login:#{request.ip}"
    attempts = Rails.cache.increment(identifier, 1, expires_in: 1.hour)
    
    if attempts.nil?
      Rails.cache.write(identifier, 1, expires_in: 1.hour)
    elsif attempts > 10
      render json: {error: 'Too many login attempts'}, 
             status: :too_many_requests
    end
  end
end

# Session timeout middleware
class SessionTimeout
  def initialize(app, timeout: 30.minutes)
    @app = app
    @timeout = timeout
  end
  
  def call(env)
    session = env['rack.session']
    
    if session[:created_at]
      if Time.current - session[:created_at] > @timeout
        session.clear
      end
    end
    
    @app.call(env)
  end
end

Multi-Layer DoS Protection combines application and infrastructure controls:

# Expensive operation protection
class ReportController < ApplicationController
  def generate
    # Check if similar recent request exists
    cache_key = "report:#{current_user.id}:#{params[:type]}"
    cached_report = Rails.cache.read(cache_key)
    
    if cached_report
      render json: cached_report
      return
    end
    
    # Limit concurrent report generation per user
    lock_key = "report_lock:#{current_user.id}"
    
    if Rails.cache.read(lock_key)
      render json: {error: 'Report already generating'}, 
             status: :conflict
      return
    end
    
    begin
      Rails.cache.write(lock_key, true, expires_in: 5.minutes)
      
      # Generate report with timeout
      report_data = Timeout.timeout(30) do
        ReportGenerator.generate(current_user, params[:type])
      end
      
      # Cache result
      Rails.cache.write(cache_key, report_data, expires_in: 1.hour)
      
      render json: report_data
    rescue Timeout::Error
      render json: {error: 'Report generation timed out'}, 
             status: :request_timeout
    ensure
      Rails.cache.delete(lock_key)
    end
  end
end

# ReDoS protection for user-provided patterns
class SearchController < ApplicationController
  MAX_PATTERN_LENGTH = 100
  SAFE_PATTERN_CHARS = /\A[a-zA-Z0-9\s\-_]+\z/
  
  def search
    pattern = params[:pattern]
    
    # Validate pattern length
    if pattern.length > MAX_PATTERN_LENGTH
      raise ActionController::BadRequest, 'Pattern too long'
    end
    
    # Validate pattern characters
    unless pattern.match?(SAFE_PATTERN_CHARS)
      raise ActionController::BadRequest, 'Invalid pattern characters'
    end
    
    # Use simple pattern matching instead of regex
    results = Product.where("name ILIKE ?", "%#{pattern}%").limit(100)
    
    render json: results
  end
end

# Connection pool exhaustion protection
Rails.application.config.middleware.use Rack::Timeout, 
  service_timeout: 15,
  wait_timeout: 30,
  term_on_timeout: true

Common Pitfalls

Disabling Rails Security Features introduces vulnerabilities when developers override framework protections without understanding implications. Calling html_safe on user input bypasses XSS protection. Using skip_before_action :verify_authenticity_token disables CSRF protection. Setting config.force_ssl = false in production allows unencrypted traffic. Each override requires careful security analysis and alternative controls.

Insufficient Input Validation occurs when applications validate presence but not content format. Checking params[:id].present? validates existence but not type or range. String length validation prevents DoS but not injection. Regex validation must account for encoding attacks and ReDoS patterns. Validation should occur at boundaries between trust domains, not solely at database layer.

Trusting Indirect User Input treats data from databases, caches, or cookies as safe because it originated from application storage. Stored XSS attacks persist malicious content in databases that executes when displayed. Session tampering modifies cookies despite server-side generation. Cache poisoning injects malicious content into shared caches. All data retrieved from storage requires output encoding before display.

Inadequate Authentication Timeout allows sessions to persist indefinitely, creating windows for session hijacking. Applications should implement absolute timeouts (maximum session duration) and idle timeouts (maximum inactivity period). Both require careful balance between security and usability. Long-lived API tokens require refresh token patterns and scope limitation.

Overlooking Error Information Disclosure reveals system internals through detailed error messages. Stack traces expose file paths, library versions, and implementation details. Database errors reveal schema information. Failed authentication messages enable user enumeration. Production applications should log detailed errors internally while displaying generic messages to users.

Inconsistent Security Controls applies different validation or encoding rules across endpoints. API endpoints may skip CSRF protection while web forms enforce it. JSON responses may lack output encoding despite HTML views including it. Administrative interfaces may use weaker authentication than user-facing areas. Security controls must apply consistently across all entry points.

Race Conditions in Security Checks create time-of-check to time-of-use vulnerabilities. Validating file paths then operating on files allows path manipulation between checks. Checking rate limits then processing requests enables limit bypass through concurrent requests. Security-critical operations require atomic transactions or locking mechanisms.

Weak Random Number Generation uses predictable values for security tokens. Ruby's rand method uses pseudorandom generation unsuitable for security. Session identifiers, CSRF tokens, password reset tokens, and API keys require cryptographically secure random generation using SecureRandom.

# Weak: predictable
token = Random.rand(1000000).to_s

# Strong: cryptographically secure
token = SecureRandom.hex(32)
uuid = SecureRandom.uuid

Tools & Ecosystem

Rack::Attack provides middleware-level rate limiting and request blocking for Rack-based applications. The gem offers IP-based throttling, user-based throttling, blocklists, allowlists, and flexible matching criteria. Configuration supports complex rules combining request attributes like path, method, IP address, and custom headers. Integration with Rails requires minimal setup and automatically handles response headers for rate-limited requests.

Brakeman performs static security analysis on Rails applications, detecting common vulnerabilities without running code. The tool identifies SQL injection, XSS, CSRF, mass assignment, and other security issues through code inspection. Brakeman integrates into CI/CD pipelines, generating reports in multiple formats. Regular scanning catches security regressions during development.

bundler-audit checks Ruby gem dependencies against known vulnerability databases. The tool alerts developers to security issues in third-party libraries, enabling prompt updates before exploitation. Running bundle audit as part of deployment processes prevents introducing vulnerable dependencies into production. The database updates regularly with new vulnerability disclosures.

Secure Headers gem configures HTTP security headers following current best practices. The gem sets Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, and Strict-Transport-Security headers with sensible defaults. Configuration supports customization per controller or globally. Proper header configuration prevents clickjacking, MIME-sniffing, and XSS attacks.

Devise implements authentication with security features including password complexity requirements, account locking, session timeout, and failed login tracking. The gem provides modules for various authentication strategies while enforcing secure defaults. Integration requires careful configuration of timeout periods, lockout thresholds, and password policies matching security requirements.

Pundit and CanCanCan enforce authorization policies, preventing privilege escalation and unauthorized access. These gems separate authorization logic from controllers, enabling centralized security policy definition. Proper authorization prevents horizontal privilege escalation (accessing other users' data) and vertical privilege escalation (accessing administrative functions).

bcrypt provides adaptive password hashing resistant to brute force attacks. The algorithm includes computational cost factors that increase over time with hardware improvements. Rails uses bcrypt through has_secure_password helper, automatically handling password encryption and verification. Cost factors balance security against authentication performance.

Loofah and Rails HTML Sanitizer clean user-provided HTML, removing malicious content while preserving formatting. These libraries provide configurable tag and attribute allowlists, removing script tags, event handlers, and other XSS vectors. Integration with Rails view helpers enables automatic sanitization of user content.

Rack SSL and Rails force_ssl enforce HTTPS connections, preventing man-in-the-middle attacks. Strict-Transport-Security headers instruct browsers to only access applications over HTTPS, even if users type HTTP URLs. Certificate validation ensures connections terminate at intended servers rather than attackers.

Reference

Attack Categories

Attack Type Target Impact Primary Defense
SQL Injection Database queries Data theft, modification Parameterized queries
XSS HTML output Session hijacking, defacement Output encoding
CSRF State-changing requests Unauthorized actions Authenticity tokens
Command Injection System commands Server compromise Input validation, avoid shell
Path Traversal File operations Unauthorized file access Path validation
SSRF HTTP requests Internal network access URL validation
DoS Resource availability Service disruption Rate limiting
Brute Force Authentication Account compromise Rate limiting, lockouts

Rails Security Methods

Method Purpose Usage Example
where Parameterized query User.where(email: params[:email])
sanitize HTML sanitization sanitize(content, tags: ['p', 'strong'])
protect_from_forgery CSRF protection protect_from_forgery with: :exception
system Safe command execution system('convert', filename, 'output.pdf')
SecureRandom.hex Secure random generation SecureRandom.hex(32)
force_ssl HTTPS enforcement force_ssl in: :production

Security Headers

Header Purpose Recommended Value
Content-Security-Policy Restricts resource loading default-src 'self'
X-Frame-Options Prevents clickjacking SAMEORIGIN
X-Content-Type-Options Prevents MIME sniffing nosniff
Strict-Transport-Security Enforces HTTPS max-age=31536000; includeSubDomains
X-XSS-Protection Browser XSS protection 1; mode=block
Referrer-Policy Controls referrer information strict-origin-when-cross-origin

Rate Limiting Strategies

Strategy Use Case Implementation
Per IP Public endpoints Throttle by request.ip
Per User Authenticated APIs Throttle by user ID
Per Action Login attempts Separate limits per endpoint
Exponential Backoff Failed authentication Increase delay with attempts
Token Bucket API requests Allow burst with sustained rate

Input Validation Patterns

Input Type Validation Approach Example
Email Format regex /\A[\w+-.]+@[a-z\d-]+(.[a-z\d-]+)*.[a-z]+\z/i
URL URI parse + scheme check URI.parse(url).scheme.in?(['http', 'https'])
Filename Character whitelist /\A[a-zA-Z0-9_-.]+\z/
Integer Type coercion + range Integer(params[:id]) rescue raise
Enum Whitelist ALLOWED_VALUES.include?(params[:type])

Security Testing Checklist

Test Category What to Verify Tool
Static Analysis Code vulnerabilities Brakeman
Dependency Audit Vulnerable gems bundler-audit
SQL Injection Parameterized queries Manual + SQLMap
XSS Output encoding Manual + OWASP ZAP
CSRF Token validation Manual testing
Authentication Lockout, timeouts RSpec + manual
Authorization Access controls RSpec + Pundit tests
Rate Limiting Throttle effectiveness Load testing