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 |
|---|---|---|
| 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 |