Brakeman Ruby auf Rails Security Scanner Cheat Sheet
Überblick
Brakeman ist ein statischer Analyse-Sicherheitssscanner speziell für Ruby auf Rails Anwendungen entwickelt. Es analysiert Rails Anwendungscode, um Sicherheitslücken zu finden, ohne dass die Anwendung ausgeführt werden muss. Brakeman ist ein wesentliches Werkzeug in DevSecOps Pipelines für Rails-Anwendungen und hilft Entwicklern, gemeinsame Sicherheitsprobleme wie SQL-Injektion, Cross-Site-Skripting (XSS) und andere Rails-spezifische Schwachstellen frühzeitig im Entwicklungsprozess zu identifizieren.
ZEIT Note: Brakeman ist speziell für Ruby auf Rails-Anwendungen konzipiert und kann nicht korrekt mit anderen Ruby-Frameworks arbeiten. Es sollte als Teil einer umfassenden Sicherheitsteststrategie verwendet werden.
Installation
Edelstein verwenden
```bash
Install Brakeman gem
gem install brakeman
Install specific version
gem install brakeman -v 5.4.1
Install from source
git clone https://github.com/presidentbeef/brakeman.git cd brakeman gem build brakeman.gemspec gem install brakeman-*.gem
Verify installation
brakeman --version ```_
Mit Bundler
```ruby
Add to Gemfile
group :development do gem 'brakeman', require: false end
Install
bundle install
Run via bundle
bundle exec brakeman ```_
Verwendung von Docker
```bash
Pull official Brakeman image
docker pull presidentbeef/brakeman
Run Brakeman in container
docker run --rm -v $(pwd):/code presidentbeef/brakeman
Build custom image
cat > Dockerfile ``<< 'EOF' FROM ruby:3.0-slim RUN gem install brakeman WORKDIR /app ENTRYPOINT ["brakeman"] EOF
docker build -t custom-brakeman . docker run --rm -v $(pwd):/app custom-brakeman ```_
Paketmanager
```bash
Ubuntu/Debian (via RubyGems)
sudo apt update sudo apt install ruby-dev sudo gem install brakeman
macOS with Homebrew
brew install brakeman
CentOS/RHEL/Fedora
sudo dnf install ruby-devel sudo gem install brakeman ```_
Basisnutzung
Einfache Scans
```bash
Scan current Rails application
brakeman
Scan specific Rails application
brakeman /path/to/rails/app
Scan with verbose output
brakeman -v
Scan with debug output
brakeman -d
Quick scan (faster, less thorough)
brakeman -q
Scan specific files
brakeman --only-files app/controllers/users_controller.rb,app/models/user.rb ```_
Ausgabeformate
```bash
Default text output
brakeman
JSON output
brakeman -f json
HTML output
brakeman -f html
CSV output
brakeman -f csv
Markdown output
brakeman -f markdown
SARIF output (for GitHub integration)
brakeman -f sarif
Save output to file
brakeman -o brakeman-report.html -f html brakeman -o brakeman-report.json -f json brakeman -o brakeman-report.csv -f csv ```_
Sicherheitsstufen
```bash
Show only high confidence warnings
brakeman -w3
Show high and medium confidence warnings
brakeman -w2
Show all warnings (including low confidence)
brakeman -w1
Default behavior (medium and high confidence)
brakeman ```_
Konfiguration
Konfigurationsdatei (.brakeman.yml)
```yaml
.brakeman.yml
:app_path: "." :output_files: - "brakeman-report.html" - "brakeman-report.json" :output_formats: - :html - :json :quiet: false :min_confidence: 2 :combine_locations: true :collapse_mass_assignment: true :highlight_user_input: true :ignore_redirect_to_model: true :ignore_model_output: false :check_arguments: true :safe_methods: - :sanitize - :h - :html_escape :skip_checks: - :SSL - :LinkTo :report_progress: true :parallel_checks: true ```_
Konfiguration der Befehlszeile
```bash
Set minimum confidence level
brakeman --confidence-level 2 # Medium and high only brakeman --confidence-level 3 # High only
Skip specific checks
brakeman --skip-checks SSL,LinkTo,Render
Run only specific checks
brakeman --test SQL,XSS,Command
Ignore specific files
brakeman --skip-files app/controllers/admin_controller.rb
Set Rails version explicitly
brakeman --rails3 brakeman --rails4 brakeman --rails5 brakeman --rails6 brakeman --rails7
Additional options
brakeman --no-progress # Disable progress reporting brakeman --no-pager # Disable pager for output brakeman --table-width 120 # Set table width brakeman --url-safe-methods method1,method2 # Additional URL-safe methods ```_
Erweiterte Nutzung
Baseline und Progressive Scanning
```bash
Create baseline
brakeman -f json -o baseline.json
Compare against baseline
brakeman --compare baseline.json
Ignore baseline warnings
brakeman --ignore-config baseline.ignore
Generate ignore file from current warnings
brakeman --ignore-config brakeman.ignore --interactive-ignore ```_
Zollkontrollen
```ruby
custom_check.rb
class CustomCheck < Brakeman::BaseCheck Brakeman::Checks.add self
@description = "Check for custom security pattern"
def run_check | tracker.find_call(:target =>`` nil, :method => :dangerous_method).each do | result | | warn :result => result, :warning_type => "Custom Warning", :warning_code => :custom_dangerous_method, :message => "Avoid using dangerous_method", :confidence => :high end end end ```_
Integration mit Schienen
```ruby
config/brakeman.yml in Rails app
:app_path: "." :output_files: - "tmp/brakeman-report.html" :output_formats: - :html :quiet: true :min_confidence: 2
Rake task integration
lib/tasks/security.rake
namespace :security do desc "Run Brakeman security scan" task :scan do require 'brakeman'
options = \\\\{
:app_path => Rails.root.to_s,
:output_formats => [:html, :json],
:output_files => [
Rails.root.join('tmp', 'brakeman-report.html').to_s,
Rails.root.join('tmp', 'brakeman-report.json').to_s
],
:quiet => false,
:min_confidence => 2
\\\\}
tracker = Brakeman.run(options)
if tracker.warnings.any?
puts "Security warnings found! Check tmp/brakeman-report.html"
exit 1
else
puts "No security warnings found."
end
end end ```_
CI/CD Integration
GitHub Aktionen
```yaml
.github/workflows/security.yml
name: Security Scan
on: [push, pull_request]
jobs: brakeman: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
bundler-cache: true
- name: Install Brakeman
run: gem install brakeman
- name: Run Brakeman
run: brakeman -f sarif -o brakeman-results.sarif
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: brakeman-results.sarif
- name: Upload results
uses: actions/upload-artifact@v3
with:
name: brakeman-report
path: brakeman-results.sarif
```_
GitLab CI
```yaml
.gitlab-ci.yml
stages: - security
brakeman: stage: security image: ruby:3.0 before_script: - gem install brakeman script: - brakeman -f json -o brakeman-report.json artifacts: reports: sast: brakeman-report.json paths: - brakeman-report.json expire_in: 1 week allow_failure: true ```_
Jenkins Pipeline
```groovy // Jenkinsfile pipeline \\{ agent any
stages \\\\{
stage('Security Scan') \\\\{
steps \\\\{
script \\\\{
sh 'gem install brakeman'
sh 'brakeman -f json -o brakeman-report.json'
sh 'brakeman -f html -o brakeman-report.html'
\\\\}
\\\\}
post \\\\{
always \\\\{
archiveArtifacts artifacts: 'brakeman-report.*', fingerprint: true
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: '.',
reportFiles: 'brakeman-report.html',
reportName: 'Brakeman Security Report'
])
\\\\}
failure \\\\{
emailext (
subject: "Security Scan Failed: $\\\\{env.JOB_NAME\\\\} - $\\\\{env.BUILD_NUMBER\\\\}",
body: "Brakeman found security issues. Check the report for details.",
to: "$\\\\{env.CHANGE_AUTHOR_EMAIL\\\\}"
)
\\\\}
\\\\}
\\\\}
\\\\}
\\} ```_
Kreis
```yaml
.circleci/config.yml
version: 2.1
jobs: security_scan: docker: - image: cimg/ruby:3.0 steps: - checkout - run: name: Install Brakeman command: gem install brakeman - run: name: Run Brakeman command: | brakeman -f json -o brakeman-report.json brakeman -f html -o brakeman-report.html - store_artifacts: path: brakeman-report.html - store_artifacts: path: brakeman-report.json
workflows: version: 2 security: jobs: - security_scan ```_
Gemeinsame Schwachstelle Muster
SQL Injection
```ruby
BAD: String interpolation in queries
User.where("name = '#\\{params[:name]\\}'") User.find_by_sql("SELECT * FROM users WHERE id = #\\{params[:id]\\}")
GOOD: Parameterized queries
User.where(name: params[:name]) User.where("name = ?", params[:name]) User.find_by_sql(["SELECT * FROM users WHERE id = ?", params[:id]]) ```_
Cross-Site Scripting (XSS)
```erb
<%= params[:message] %> <%= raw user_input %> <%= content.html_safe %>
<%= h(params[:message]) %> <%= sanitize(user_input) %> <%= simple_format(content) %> ```_
Massenzuweisung
```ruby
BAD: Unfiltered parameters
User.create(params[:user]) user.update_attributes(params[:user])
GOOD: Strong parameters
def user_params params.require(:user).permit(:name, :email) end
User.create(user_params) user.update_attributes(user_params) ```_
Befehlsinjektion
```ruby
BAD: Unescaped system calls
system("ls #\\{params[:directory]\\}")
grep #\\{params[:pattern]\\} file.txt
GOOD: Escaped or parameterized calls
system("ls", params[:directory]) Open3.capture3("grep", params[:pattern], "file.txt") ```_
Cross-Site Request Forgery (CSRF)
```ruby
BAD: Missing CSRF protection
class ApplicationController ``< ActionController::Base # protect_from_forgery commented out end
GOOD: CSRF protection enabled
class ApplicationController < ActionController::Base protect_from_forgery with: :exception end ```_
Automatisierung und Schrift
Automatischer Sicherheitsscanner
```ruby
!/usr/bin/env ruby
brakeman_scanner.rb
require 'brakeman' require 'json' require 'optparse'
class BrakemanScanner def initialize(app_path, options = \{\}) @app_path = app_path @options = \{ app_path: app_path, quiet: true, min_confidence: 2, output_formats: [:json, :html], output_files: [ File.join(app_path, 'tmp', 'brakeman-report.json'), File.join(app_path, 'tmp', 'brakeman-report.html') ] \}.merge(options) end
def run_scan puts "Running Brakeman scan on #\{@app_path\}..."
begin
@tracker = Brakeman.run(@options)
generate_summary
return @tracker.warnings.empty?
rescue =>`` e
puts "Error running Brakeman: #\\\\{e.message\\\\}"
return false
end
end
def generate_summary warnings = @tracker.warnings
puts "\n=== Brakeman Security Scan Summary ==="
puts "Total warnings: #\\\\{warnings.length\\\\}"
# Group by confidence
by_confidence = warnings.group_by(&:confidence)
| puts "High confidence: #\\{(by_confidence[:high] | | []).length\\}" | | puts "Medium confidence: #\\{(by_confidence[:medium] | | []).length\\}" | | puts "Low confidence: #\\{(by_confidence[:low] | | []).length\\}" |
# Group by warning type
by_type = warnings.group_by(&:warning_type)
puts "\nWarnings by type:"
| by_type.each do | type, type_warnings | | puts " #\\{type\\}: #\\{type_warnings.length\\}" end
# Show high confidence warnings
| high_warnings = by_confidence[:high] | | [] | if high_warnings.any? puts "\n=== High Confidence Warnings ===" | high_warnings.each do | warning | | puts "#\\{warning.file\\}:#\\{warning.line\\} - #\\{warning.warning_type\\}: #\\{warning.message\\}" end end end
def save_baseline baseline_file = File.join(@app_path, 'brakeman.baseline') File.write(baseline_file, @tracker.warnings.to_json) puts "Baseline saved to #\\{baseline_file\\}" end
def compare_with_baseline baseline_file = File.join(@app_path, 'brakeman.baseline') return unless File.exist?(baseline_file)
baseline_warnings = JSON.parse(File.read(baseline_file))
current_warnings = @tracker.warnings.map(&:to_hash)
new_warnings = current_warnings - baseline_warnings
fixed_warnings = baseline_warnings - current_warnings
puts "\n=== Baseline Comparison ==="
puts "New warnings: #\\\\{new_warnings.length\\\\}"
puts "Fixed warnings: #\\\\{fixed_warnings.length\\\\}"
if new_warnings.any?
puts "\nNew warnings found:"
| new_warnings.each do | warning | | puts " #\\{warning['file']\\}:#\\{warning['line']\\} - #\\{warning['warning_type']\\}" end end end end
Command line interface
options = \\{\\} | OptionParser.new do | opts | | opts.banner = "Usage: #\\{$0\\} [options] [app_path]"
| opts.on("-c", "--confidence LEVEL", Integer, "Minimum confidence level (1-3)") do | c | | options[:min_confidence] = c end
opts.on("-q", "--quiet", "Quiet mode") do options[:quiet] = true end
opts.on("-b", "--baseline", "Save current scan as baseline") do options[:save_baseline] = true end
opts.on("--compare", "Compare with baseline") do options[:compare_baseline] = true end
opts.on("-h", "--help", "Show this help") do puts opts exit end end.parse!
| app_path = ARGV[0] | | Dir.pwd |
scanner = BrakemanScanner.new(app_path, options) success = scanner.run_scan
if options[:save_baseline] scanner.save_baseline end
if options[:compare_baseline] scanner.compare_with_baseline end
exit(success ? 0 : 1) ```_
Batch Processing Script
```bash
!/bin/bash
batch_brakeman_scan.sh
Configuration
RAILS_APPS_DIR="/path/to/rails/apps" REPORTS_DIR="/path/to/reports" DATE=$(date +%Y%m%d_%H%M%S)
Create reports directory
mkdir -p "$REPORTS_DIR"
Function to scan Rails app
scan_rails_app() \\{ local app_path="$1" local app_name=$(basename "$app_path") local report_file="$REPORTS_DIR/$\\{app_name\\}$\\{DATE\\}.json" local html_report="$REPORTS_DIR/$\\{app_name\\}$\\{DATE\\}.html"
echo "Scanning $app_name..."
# Check if it's a Rails app
if [ ! -f "$app_path/config/application.rb" ]; then
echo "Skipping $app_name - not a Rails application"
return
fi
# Run Brakeman scan
cd "$app_path"
brakeman -f json -o "$report_file" -q
brakeman -f html -o "$html_report" -q
# Check for high confidence warnings
| high_warnings=$(jq '[.warnings[] | select(.confidence == "High")] | length' "$report_file" 2>/dev/null | | echo "0") |
if [ "$high_warnings" -gt 0 ]; then
echo "WARNING: $app_name has $high_warnings high confidence warnings!"
echo "$app_name" >> "$REPORTS_DIR/high_risk_apps.txt"
fi
echo "Scan completed for $app_name"
\\}
Find and scan all Rails applications
find "$RAILS_APPS_DIR" -name "application.rb" -path "/config/"|while read -r config_file; do app_dir=$(dirname "$(dirname "$config_file")") scan_rails_app "$app_dir" done
echo "Batch scanning completed. Reports saved to $REPORTS_DIR"
Generate summary report
echo "=== Batch Scan Summary ===" > "$REPORTS_DIR/summary_$\\{DATE\\}.txt" echo "Scan Date: $(date)" >> "$REPORTS_DIR/summary_$\\{DATE\\}.txt" echo "Total applications scanned: $(find "$REPORTS_DIR" -name "*$\\{DATE\\}.json"|wc -l)" >> "$REPORTS_DIR/summary$\\{DATE\\}.txt"
if [ -f "$REPORTS_DIR/high_risk_apps.txt" ]; then echo "High risk applications: $(wc -l < "$REPORTS_DIR/high_risk_apps.txt")" >> "$REPORTS_DIR/summary_$\\{DATE\\}.txt" echo "" >> "$REPORTS_DIR/summary_$\\{DATE\\}.txt" echo "High risk applications:" >> "$REPORTS_DIR/summary_$\\{DATE\\}.txt" cat "$REPORTS_DIR/high_risk_apps.txt" >> "$REPORTS_DIR/summary_$\\{DATE\\}.txt" fi ```_
Integration in Entwicklungswerkzeuge
VS Code Integration
```json // .vscode/tasks.json \\{ "version": "2.0.0", "tasks": [ \\{ "label": "Brakeman Security Scan", "type": "shell", "command": "brakeman", "args": ["-f", "html", "-o", "tmp/brakeman-report.html"], "group": "test", "presentation": \\{ "echo": true, "reveal": "always", "focus": false, "panel": "shared" \\}, "problemMatcher": [] \\} ] \\}
// .vscode/settings.json \\{ "ruby.lint": \\{ "brakeman": \\{ "enable": true, "command": "brakeman" \\} \\} \\} ```_
RubyMine Integration
```bash
External tool configuration
Program: brakeman
Arguments: -f html -o $ProjectFileDir$/tmp/brakeman-report.html
Working directory: $ProjectFileDir$
```_
Integration von Schutzmaßnahmen
```ruby
Guardfile
guard :brakeman, :run_on_start => true do watch(%r\\{^app/.+.(rb|erb)$\\}) watch(%r\\{^config/.+.rb$\\}) watch(%r\\{^lib/.+.rb$\\}) watch('Gemfile') end ```_
Best Practices
Konfigurationsmanagement
```yaml
.brakeman.yml - Production configuration
:app_path: "." :output_files: - "tmp/brakeman-report.html" - "tmp/brakeman-report.json" :output_formats: - :html - :json :quiet: false :min_confidence: 2 :combine_locations: true :collapse_mass_assignment: true :highlight_user_input: true :ignore_redirect_to_model: true :ignore_model_output: false :check_arguments: true :safe_methods: - :sanitize - :h - :html_escape - :simple_format :skip_checks: [] :report_progress: true :parallel_checks: true :absolute_paths: false :summary_only: false ```_
Ignorieren von Dateimanagement
```yaml
brakeman.ignore
:ignored_warnings: - :warning_type: SQL :fingerprint: 1234567890abcdef :note: "Reviewed and accepted - admin only functionality" - :warning_type: CrossSiteScripting :fingerprint: abcdef1234567890 :note: "False positive - output is properly sanitized" ```_
Teamworkflow
```bash
Makefile integration
.PHONY: security-scan security-scan: @echo "Running Brakeman security scan..." @brakeman -q -f json -o tmp/brakeman-report.json @if [ -s tmp/brakeman-report.json ]; then \ echo "Security warnings found! Check tmp/brakeman-report.html"; \ brakeman -f html -o tmp/brakeman-report.html; \ exit 1; \ else \ echo "No security warnings found."; \ fi
.PHONY: security-baseline security-baseline: @echo "Creating security baseline..." @brakeman -f json -o brakeman.baseline @echo "Baseline created. Commit brakeman.baseline to version control."
Pre-commit hook
!/bin/bash
.git/hooks/pre-commit
echo "Running Brakeman security scan..." brakeman -q --no-pager if [ $? -ne 0 ]; then echo "Security issues found. Commit aborted." echo "Run 'brakeman' to see details or 'brakeman -I' to ignore warnings." exit 1 fi ```_
Fehlerbehebung
Gemeinsame Themen
```bash
Issue: Brakeman not detecting Rails app
Solution: Ensure you're in Rails root directory
cd /path/to/rails/app ls config/application.rb # Should exist
Issue: Too many false positives
Solution: Use ignore file and tune confidence levels
brakeman --confidence-level 3 # High confidence only brakeman -I # Interactive ignore mode
Issue: Performance issues with large apps
Solution: Use parallel processing and skip unnecessary checks
brakeman --parallel-checks --skip-checks Render,LinkTo
Issue: Integration with CI/CD failing
Solution: Use appropriate exit codes and formats
| brakeman -q -f json -o results.json | | true | ```_
Leistungsoptimierung
```bash
Skip time-consuming checks
brakeman --skip-checks Render,LinkTo,DetailedExceptions
Use parallel processing
brakeman --parallel-checks
Scan only specific directories
brakeman --only-files app/controllers/,app/models/
Quick scan mode
brakeman -q --faster ```_
Debugging
```bash
Debug mode
brakeman -d
Verbose output
brakeman -v
Show timing information
brakeman --timing
Test specific warning types
brakeman --test SQL,XSS ```_
Ressourcen
- (__LINK_5___)
- Brakeman GitHub Repository
- (LINK_5)
- (LINK_5)
- (__LINK_5___)
--
*Dieses Betrugsblatt bietet umfassende Anleitung für die Verwendung von Brakeman, um Sicherheitslücken in Ruby auf Rails Anwendungen zu identifizieren. Kombinieren Sie immer statische Analyse mit anderen Sicherheitstestmethoden für eine umfassende Deckung. *