diff --git a/lib/brakeman.rb b/lib/brakeman.rb index e0a1f2d2737dfb9cc569baaf08fb8514f72744eb..d1b585d7f718c0e23b1789b01d7be76376d1fee2 100644 --- a/lib/brakeman.rb +++ b/lib/brakeman.rb @@ -10,6 +10,7 @@ module Brakeman @debug = false @quiet = false + @loaded_dependencies = [] #Run Brakeman scan. Returns Tracker object. # @@ -366,6 +367,19 @@ module Brakeman Brakeman::Differ.new(new_results, previous_results).diff end + def self.load_dependency name + return if @loaded_dependencies.include? name + + begin + require name + rescue LoadError => e + $stderr.puts e.message + $stderr.puts "Please install the appropriate dependency." + exit! -1 + end + end + + class DependencyError < RuntimeError; end class RakeInstallError < RuntimeError; end class NoBrakemanError < RuntimeError; end end diff --git a/lib/brakeman/parsers/rails2_erubis.rb b/lib/brakeman/parsers/rails2_erubis.rb index f6486848e3e771ac6d957a9974d5b73e0fd11010..9c33503b1cb7d69c5e421e90d27f18f6cb49213d 100644 --- a/lib/brakeman/parsers/rails2_erubis.rb +++ b/lib/brakeman/parsers/rails2_erubis.rb @@ -1,3 +1,5 @@ +Brakeman.load_dependency 'erubis' + #Erubis processor which ignores any output which is plain text. class Brakeman::ScannerErubis < Erubis::Eruby include Erubis::NoTextEnhancer diff --git a/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb b/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb index e7dbf5c65ec432c93a1f4943f9c2515d2b6a54bc..f11b621694638485c44fa62270995446c9542dcd 100644 --- a/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +++ b/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb @@ -1,3 +1,5 @@ +Brakeman.load_dependency 'erubis' + #This is from the rails_xss plugin for Rails 2 class Brakeman::Rails2XSSPluginErubis < ::Erubis::Eruby def add_preamble(src) diff --git a/lib/brakeman/parsers/rails3_erubis.rb b/lib/brakeman/parsers/rails3_erubis.rb index 1eed1e800c92832ee5d0e29805a394818492cc02..af5aafa380f9968eca22c04431384d3b8fd55bc0 100644 --- a/lib/brakeman/parsers/rails3_erubis.rb +++ b/lib/brakeman/parsers/rails3_erubis.rb @@ -1,3 +1,5 @@ +Brakeman.load_dependency 'erubis' + #This is from Rails 3 version of the Erubis handler class Brakeman::Rails3Erubis < ::Erubis::Eruby diff --git a/lib/brakeman/report/renderer.rb b/lib/brakeman/report/renderer.rb index 860169964489288e8fb73f203df58d4cf7882b5a..27ea483c37f9f3801b971b45c9a59ac3c01cc36c 100644 --- a/lib/brakeman/report/renderer.rb +++ b/lib/brakeman/report/renderer.rb @@ -1,3 +1,5 @@ +require 'erb' + class Brakeman::Report class Renderer def initialize(template_file, hash = {}) diff --git a/lib/brakeman/report/report_base.rb b/lib/brakeman/report/report_base.rb index b985e7fe718bf5f2808231e6d0a7b61b28ae3503..60c543ebd3a616adcb1a3ee372d19e9e51069bb8 100644 --- a/lib/brakeman/report/report_base.rb +++ b/lib/brakeman/report/report_base.rb @@ -1,5 +1,4 @@ require 'set' -require 'highline' require 'brakeman/util' require 'brakeman/version' require 'brakeman/report/renderer' diff --git a/lib/brakeman/report/report_csv.rb b/lib/brakeman/report/report_csv.rb index 94d4c506ae0b9b3de66f2af940b73e3a6a1debdf..c69301f9c0076b4171726c9811f17a58fc9e39e0 100644 --- a/lib/brakeman/report/report_csv.rb +++ b/lib/brakeman/report/report_csv.rb @@ -1,4 +1,4 @@ -require "csv" +Brakeman.load_dependency 'csv' require "brakeman/report/initializers/faster_csv" require "brakeman/report/report_table" diff --git a/lib/brakeman/report/report_json.rb b/lib/brakeman/report/report_json.rb index b8de9b7ae292f48887b12475b1a233c29de58e65..0d1ba167b5d677b8d8d590013a07c9fd21ac702f 100644 --- a/lib/brakeman/report/report_json.rb +++ b/lib/brakeman/report/report_json.rb @@ -1,4 +1,4 @@ -require 'multi_json' +Brakeman.load_dependency 'multi_json' require 'brakeman/report/initializers/multi_json' class Brakeman::Report::JSON < Brakeman::Report::Base diff --git a/lib/brakeman/report/report_table.rb b/lib/brakeman/report/report_table.rb index 34cee6c91adaa119c81cfd9868776f99b4101260..52eac267898957218abb9d9908cbd91627efb358 100644 --- a/lib/brakeman/report/report_table.rb +++ b/lib/brakeman/report/report_table.rb @@ -1,4 +1,4 @@ -require 'terminal-table' +Brakeman.load_dependency 'terminal-table' class Brakeman::Report::Table < Brakeman::Report::Base def generate_report diff --git a/lib/brakeman/scanner.rb b/lib/brakeman/scanner.rb index 509775e5a10e8cb1d620c351ded284a4514cb849..bf464fc032d728a8d61e39c19fcdf057810f11ed 100644 --- a/lib/brakeman/scanner.rb +++ b/lib/brakeman/scanner.rb @@ -1,19 +1,11 @@ require 'rubygems' + begin require 'ruby_parser' require 'ruby_parser/bm_sexp.rb' require 'ruby_parser/bm_sexp_processor.rb' - - require 'haml' - require 'sass' - require 'erb' - require 'erubis' - require 'slim' require 'brakeman/processor' require 'brakeman/app_tree' - require 'brakeman/parsers/rails2_erubis' - require 'brakeman/parsers/rails2_xss_plugin_erubis' - require 'brakeman/parsers/rails3_erubis' rescue LoadError => e $stderr.puts e.message $stderr.puts "Please install the appropriate dependency." @@ -272,24 +264,33 @@ class Brakeman::Scanner if tracker.config[:escape_html] type = :erubis if options[:rails3] + require 'brakeman/parsers/rails3_erubis' src = Brakeman::Rails3Erubis.new(text).src else + require 'brakeman/parsers/rails2_xss_plugin_erubis' src = Brakeman::Rails2XSSPluginErubis.new(text).src end elsif tracker.config[:erubis] + require 'brakeman/parsers/rails2_erubis' type = :erubis src = Brakeman::ScannerErubis.new(text).src else + require 'erb' src = ERB.new(text, nil, "-").src src.sub!(/^#.*\n/, '') if RUBY_1_9 end parsed = parse_ruby src elsif type == :haml + Brakeman.load_dependency 'haml' + Brakeman.load_dependency 'sass' + src = Haml::Engine.new(text, :escape_html => !!tracker.config[:escape_html]).precompiled parsed = parse_ruby src elsif type == :slim + Brakeman.load_dependency 'slim' + src = Slim::Template.new(:disable_capture => true, :generator => Temple::Generators::RailsOutputBuffer) { text }.precompiled_template @@ -358,3 +359,6 @@ class Brakeman::Scanner class NoApplication < RuntimeError; end end + +# This is to allow operation without loading the Haml library +module Haml; class Error < StandardError; end; end diff --git a/lib/brakeman/util.rb b/lib/brakeman/util.rb index 8713c13d4f412a576896b42e3df281e416ff9564..9c3d7c65c070403a98128606c59620adb9c487ab 100644 --- a/lib/brakeman/util.rb +++ b/lib/brakeman/util.rb @@ -385,6 +385,7 @@ module Brakeman::Util def truncate_table str @terminal_width ||= if $stdin && $stdin.tty? + Brakeman.load_dependency 'highline' ::HighLine.new.terminal_size[0] else 80 @@ -402,6 +403,7 @@ module Brakeman::Util # rely on Terminal::Table to build the structure, extract the data out in CSV format def table_to_csv table + Brakeman.load_dependency 'terminal-table' output = CSV.generate_line(table.headings.cells.map{|cell| cell.to_s.strip}) table.rows.each do |row| output << CSV.generate_line(row.cells.map{|cell| cell.to_s.strip})