Reviews Sinatra applications for security vulnerabilities, performance issues, route conflicts, and framework best practices, scanning files and analyzing routes.
How this command is triggered — by the user, by Claude, or both
Slash command
/ruby-sinatra-advanced:sinatra-reviewFiles this command reads when invoked
The summary Claude sees in its command listing — used to decide when to auto-load this command
# Sinatra Review Command Performs comprehensive code review of Sinatra applications, identifying security vulnerabilities, performance issues, routing conflicts, and deviations from best practices. ## Arguments - **$1: path** (optional) - Path to review (defaults to current directory) ## Usage Examples ## Workflow ### Step 1: Scan and Identify Application Files **Discovery Phase:** 1. Locate `config.ru` to identify Rack application 2. Find Sinatra application files (controllers, routes) 3. Identify application structure (classic vs modular) 4. Scan for middleware configuration 5. L...
Performs comprehensive code review of Sinatra applications, identifying security vulnerabilities, performance issues, routing conflicts, and deviations from best practices.
# Review current directory
/sinatra-review
# Review specific directory
/sinatra-review /path/to/sinatra-app
# Review specific file
/sinatra-review app/controllers/users_controller.rb
Discovery Phase:
config.ru to identify Rack applicationFile Patterns to Search:
# Application files
*.rb files inheriting from Sinatra::Base
config.ru
app.rb (classic style)
app/controllers/*.rb
lib/**/*.rb
# View templates
views/**/*.erb
views/**/*.haml
views/**/*.slim
# Configuration
config/*.rb
Gemfile
.env files
Route Conflict Detection:
Check for:
Examples of Issues:
# ISSUE: Route order conflict
get '/users/new' do
# Never reached because of wildcard below
end
get '/users/:id' do
# This catches /users/new
end
# FIX: Specific routes before wildcards
get '/users/new' do
# Now reached first
end
get '/users/:id' do
# Only catches other IDs
end
# ISSUE: Duplicate routes
get '/api/users' do
# First definition
end
get '/api/users' do
# Overwrites first - only this runs
end
# ISSUE: Missing validation
get '/users/:id' do
user = User.find(params[:id]) # What if id is not numeric?
end
# FIX: Add validation
get '/users/:id', id: /\d+/ do
user = User.find(params[:id])
end
Route Analysis Report:
Route Analysis:
Total routes: 25
GET: 15, POST: 5, PUT: 3, DELETE: 2
⚠ Warnings:
- Route order issue in app/controllers/users_controller.rb:15
GET /users/:id should be after GET /users/new
- Missing parameter validation in app/controllers/posts_controller.rb:32
Route GET /posts/:id should validate :id is numeric
Security Checklist:
1. CSRF Protection:
# CHECK: Is CSRF protection enabled?
use Rack::Protection
# or
use Rack::Protection::AuthenticityToken
# ISSUE: Missing CSRF for POST/PUT/DELETE
post '/users' do
User.create(params[:user]) # Vulnerable to CSRF
end
# FIX: Ensure Rack::Protection is enabled
2. XSS Prevention:
# CHECK: Are templates auto-escaping HTML?
# ERB: Use <%= %> (escapes) not <%== %> (raw)
# ISSUE: Raw user input in template
<div><%== @user.bio %></div>
# FIX: Escape user input
<div><%= @user.bio %></div>
# CHECK: JSON responses properly encoded
# ISSUE: Manual JSON creation
get '/api/users' do
"{ \"name\": \"#{user.name}\" }" # XSS if name contains quotes
end
# FIX: Use JSON library
get '/api/users' do
json({ name: user.name })
end
3. SQL Injection:
# ISSUE: String interpolation in queries
DB["SELECT * FROM users WHERE email = '#{params[:email]}'"]
# FIX: Use parameterized queries
DB["SELECT * FROM users WHERE email = ?", params[:email]]
# ISSUE: Unsafe ActiveRecord
User.where("email = '#{params[:email]}'")
# FIX: Use hash conditions
User.where(email: params[:email])
4. Authentication & Authorization:
# CHECK: Protected routes have authentication
# ISSUE: Admin route without auth check
delete '/users/:id' do
User.find(params[:id]).destroy # No auth check!
end
# FIX: Add authentication
before '/admin/*' do
halt 401 unless current_user&.admin?
end
# CHECK: Session security
# ISSUE: Weak session configuration
use Rack::Session::Cookie, secret: 'easy'
# FIX: Strong secret and secure flags
use Rack::Session::Cookie,
secret: ENV['SESSION_SECRET'], # Long random string
same_site: :strict,
httponly: true,
secure: production?
5. Mass Assignment:
# ISSUE: Accepting all params
User.create(params)
# FIX: Whitelist allowed attributes
def user_params
params.slice(:name, :email, :bio)
end
User.create(user_params)
6. File Upload Security:
# ISSUE: Unrestricted file uploads
post '/upload' do
File.write("uploads/#{params[:file][:filename]}", params[:file][:tempfile].read)
end
# FIX: Validate file type and sanitize filename
post '/upload' do
file = params[:file]
# Validate content type
halt 400 unless ['image/jpeg', 'image/png'].include?(file[:type])
# Sanitize filename
filename = File.basename(file[:filename]).gsub(/[^a-zA-Z0-9\._-]/, '')
# Save with random name
secure_name = "#{SecureRandom.hex}-#{filename}"
File.write("uploads/#{secure_name}", file[:tempfile].read)
end
7. Information Disclosure:
# ISSUE: Detailed error messages in production
configure :production do
set :show_exceptions, true # Exposes stack traces
end
# FIX: Hide errors in production
configure :production do
set :show_exceptions, false
set :dump_errors, false
end
error do
log_error(env['sinatra.error'])
json({ error: 'Internal server error' }, 500)
end
Security Report:
Security Analysis:
✓ CSRF protection enabled (Rack::Protection)
✓ Session configured securely
⚠ Potential Issues:
- SQL injection risk in app/models/user.rb:45
- Raw HTML output in views/profile.erb:12
- Missing authentication check in app/controllers/admin_controller.rb:23
- Weak session secret detected
Critical: 1
High: 2
Medium: 3
Low: 2
Middleware Analysis:
Check for:
Common Issues:
# ISSUE: Missing compression
# FIX: Add Rack::Deflater
use Rack::Deflater
# ISSUE: Session middleware after authentication
use TokenAuth
use Rack::Session::Cookie # Session needed by auth!
# FIX: Session before authentication
use Rack::Session::Cookie
use TokenAuth
# ISSUE: No security headers
# FIX: Add Rack::Protection
use Rack::Protection, except: [:session_hijacking]
# ISSUE: Static file serving after application
run MyApp
use Rack::Static # Never reached!
# FIX: Static before application
use Rack::Static, urls: ['/css', '/js'], root: 'public'
run MyApp
Middleware Report:
Middleware Configuration:
✓ Rack::CommonLogger (logging)
✓ Rack::Session::Cookie (sessions)
✓ Rack::Protection (security)
⚠ Warnings:
- Missing Rack::Deflater (compression)
- Middleware order issue: Session should be before CustomAuth
- Consider adding Rack::Attack for rate limiting
Performance Patterns to Check:
1. Database Query Optimization:
# ISSUE: N+1 queries
get '/users' do
users = User.all
users.map { |u| { name: u.name, posts: u.posts.count } }
# Queries DB for each user's posts
end
# FIX: Eager load or use counter cache
get '/users' do
users = User.eager(:posts).all
users.map { |u| { name: u.name, posts: u.posts.count } }
end
# ISSUE: Loading entire collection
get '/users' do
json User.all.map(&:to_hash) # Load all users in memory
end
# FIX: Paginate
get '/users' do
page = params[:page]&.to_i || 1
per_page = 50
users = User.limit(per_page).offset((page - 1) * per_page)
json users.map(&:to_hash)
end
2. Caching Opportunities:
# ISSUE: Expensive operation on every request
get '/stats' do
json calculate_expensive_stats # Takes 2 seconds
end
# FIX: Add caching
get '/stats' do
stats = cache.fetch('stats', expires_in: 300) do
calculate_expensive_stats
end
json stats
end
# ISSUE: No HTTP caching headers
get '/public/data' do
json PublicData.all
end
# FIX: Add cache control
get '/public/data' do
cache_control :public, max_age: 3600
json PublicData.all
end
3. Response Optimization:
# ISSUE: Rendering large response synchronously
get '/large-export' do
csv = generate_large_csv # Blocks for 30 seconds
send_file csv
end
# FIX: Stream or queue as background job
get '/large-export' do
stream do |out|
CSV.generate(out) do |csv|
User.find_each do |user|
csv << user.to_csv_row
end
end
end
end
Performance Report:
Performance Analysis:
⚠ Issues Detected:
- Potential N+1 query in app/controllers/users_controller.rb:42
- Missing pagination in GET /api/posts (returns all records)
- No caching headers on GET /api/public/data
- Expensive operation in GET /stats without caching
Recommendations:
- Add database query optimization (eager loading)
- Implement pagination for collection endpoints
- Add HTTP caching headers for static content
- Consider Redis caching for expensive operations
Error Handling Patterns:
# ISSUE: No error handlers defined
get '/users/:id' do
User.find(params[:id]) # Raises if not found, shows stack trace
end
# FIX: Add error handlers
error ActiveRecord::RecordNotFound do
json({ error: 'Not found' }, 404)
end
error 404 do
json({ error: 'Endpoint not found' }, 404)
end
error 500 do
json({ error: 'Internal server error' }, 500)
end
# ISSUE: Not handling exceptions in routes
post '/users' do
User.create!(params) # Raises on validation error
end
# FIX: Handle exceptions
post '/users' do
user = User.create(params)
if user.persisted?
json(user.to_hash, 201)
else
json({ errors: user.errors }, 422)
end
end
Test Analysis:
Check for:
Report:
Testing Analysis:
Framework: RSpec
Total specs: 45
Coverage: 78%
⚠ Missing Tests:
- No tests for POST /api/users
- Error cases not tested in app/controllers/posts_controller.rb
- Missing integration tests for authentication flow
Recommendations:
- Add tests for all POST/PUT/DELETE routes
- Test error scenarios (404, 422, 500)
- Increase coverage to 90%+
Final Report Structure:
================================================================================
SINATRA CODE REVIEW REPORT
================================================================================
Project: my-sinatra-app
Path: /path/to/app
Date: 2024-01-15
Reviewer: Sinatra Review Tool
--------------------------------------------------------------------------------
SUMMARY
--------------------------------------------------------------------------------
Total Issues: 15
Critical: 2
High: 4
Medium: 6
Low: 3
Categories:
Security: 5 issues
Performance: 4 issues
Best Practices: 6 issues
--------------------------------------------------------------------------------
CRITICAL ISSUES
--------------------------------------------------------------------------------
1. SQL Injection Vulnerability
Location: app/models/user.rb:45
Severity: Critical
Issue:
DB["SELECT * FROM users WHERE email = '#{email}'"]
Fix:
DB["SELECT * FROM users WHERE email = ?", email]
Impact: Attacker can execute arbitrary SQL queries
2. Missing Authentication on Admin Route
Location: app/controllers/admin_controller.rb:23
Severity: Critical
Issue:
delete '/users/:id' do
User.find(params[:id]).destroy
end
Fix:
before '/admin/*' do
authenticate_admin!
end
Impact: Unauthorized users can delete records
--------------------------------------------------------------------------------
HIGH PRIORITY ISSUES
--------------------------------------------------------------------------------
[List high priority issues...]
--------------------------------------------------------------------------------
RECOMMENDATIONS
--------------------------------------------------------------------------------
Security:
- Enable Rack::Protection::AuthenticityToken for CSRF
- Rotate session secret to strong random value
- Implement rate limiting with Rack::Attack
- Add Content-Security-Policy headers
Performance:
- Add Rack::Deflater for response compression
- Implement caching strategy (Redis or Memcached)
- Add pagination to collection endpoints
- Optimize database queries (N+1 issues)
Testing:
- Increase test coverage to 90%+
- Add integration tests for critical flows
- Test error scenarios
- Add security-focused tests
Best Practices:
- Extract business logic to service objects
- Use helpers for repeated code
- Implement proper error handling
- Add API documentation
--------------------------------------------------------------------------------
DETAILED FINDINGS
--------------------------------------------------------------------------------
[Full list of all issues with locations, descriptions, and fixes]
================================================================================
END REPORT
================================================================================
npx claudepluginhub p/geoffjay-ruby-sinatra-advanced-plugins-ruby-sinatra-advanced