Class: Brakeman::Checks

Inherits:
Object show all
Defined in:
lib/brakeman/checks.rb

Overview

Collects up results from running different checks.

Checks can be added with Check.add(check_class)

All .rb files in checks/ will be loaded.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = { }) ⇒ Checks

No need to use this directly.



24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/brakeman/checks.rb', line 24

def initialize options = { }
  if options[:min_confidence]
    @min_confidence = options[:min_confidence]
  else
    @min_confidence = Brakeman.get_defaults[:min_confidence]
  end

  @warnings = []
  @template_warnings = []
  @model_warnings = []
  @controller_warnings = []
  @checks_run = []
end

Instance Attribute Details

#checks_runObject (readonly)

Returns the value of attribute checks_run.



12
13
14
# File 'lib/brakeman/checks.rb', line 12

def checks_run
  @checks_run
end

#controller_warningsObject (readonly)

Returns the value of attribute controller_warnings.



12
13
14
# File 'lib/brakeman/checks.rb', line 12

def controller_warnings
  @controller_warnings
end

#model_warningsObject (readonly)

Returns the value of attribute model_warnings.



12
13
14
# File 'lib/brakeman/checks.rb', line 12

def model_warnings
  @model_warnings
end

#template_warningsObject (readonly)

Returns the value of attribute template_warnings.



12
13
14
# File 'lib/brakeman/checks.rb', line 12

def template_warnings
  @template_warnings
end

#warningsObject (readonly)

Returns the value of attribute warnings.



12
13
14
# File 'lib/brakeman/checks.rb', line 12

def warnings
  @warnings
end

Class Method Details

.add(klass) ⇒ Object

Add a check. This will call klass.new when running tests



15
16
17
# File 'lib/brakeman/checks.rb', line 15

def self.add klass
  @checks << klass
end

.checksObject



19
20
21
# File 'lib/brakeman/checks.rb', line 19

def self.checks
  @checks
end

.run_checks(app_tree, tracker) ⇒ Object

Run all the checks on the given Tracker. Returns a new instance of Checks with the results.



78
79
80
81
82
83
84
# File 'lib/brakeman/checks.rb', line 78

def self.run_checks(app_tree, tracker)
  if tracker.options[:parallel_checks]
    self.run_checks_parallel(app_tree, tracker)
  else
    self.run_checks_sequential(app_tree, tracker)
  end
end

.run_checks_parallel(app_tree, tracker) ⇒ Object

Run checks in parallel threads



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/brakeman/checks.rb', line 121

def self.run_checks_parallel(app_tree, tracker)
  threads = []
  error_mutex = Mutex.new

  check_runner = self.new :min_confidence => tracker.options[:min_confidence]

  @checks.each do |c|
    check_name = get_check_name c

    #Run or don't run check based on options
    unless tracker.options[:skip_checks].include? check_name or
      (tracker.options[:run_checks] and not tracker.options[:run_checks].include? check_name)

      Brakeman.notify " - #{check_name}"

      threads << Thread.new do
        check = c.new(app_tree, tracker)

        begin
          check.run_check
        rescue Exception => e
          error_mutex.synchronize do
            tracker.error e
          end
        end

        check.warnings
      end

      #Maintain list of which checks were run
      #mainly for reporting purposes
      check_runner.checks_run << check_name[5..-1]
    end
  end

  threads.each { |t| t.join }

  Brakeman.notify "Checks finished, collecting results..."

  #Collect results
  threads.each do |thread|
    thread.value.each do |warning|
      check_runner.add_warning warning
    end
  end

  check_runner
end

.run_checks_sequential(app_tree, tracker) ⇒ Object

Run checks sequentially



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/brakeman/checks.rb', line 87

def self.run_checks_sequential(app_tree, tracker)
  check_runner = self.new :min_confidence => tracker.options[:min_confidence]

  @checks.each do |c|
    check_name = get_check_name c

    #Run or don't run check based on options
    unless tracker.options[:skip_checks].include? check_name or
      (tracker.options[:run_checks] and not tracker.options[:run_checks].include? check_name)

      Brakeman.notify " - #{check_name}"

      check = c.new(app_tree, tracker)

      begin
        check.run_check
      rescue Exception => e
        tracker.error e
      end

      check.warnings.each do |w|
        check_runner.add_warning w
      end

      #Maintain list of which checks were run
      #mainly for reporting purposes
      check_runner.checks_run << check_name[5..-1]
    end
  end

  check_runner
end

Instance Method Details

#add_warning(warning) ⇒ Object

Add Warning to list of warnings to report. Warnings are split into four different arrays for template, controller, model, and generic warnings.

Will not add warnings which are below the minimum confidence level.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/brakeman/checks.rb', line 43

def add_warning warning
  unless warning.confidence > @min_confidence
    case warning.warning_set
    when :template
      @template_warnings << warning
    when :warning
      @warnings << warning
    when :controller
      @controller_warnings << warning
    when :model
      @model_warnings << warning
    else
      raise "Unknown warning: #{warning.warning_set}"
    end
  end
end

#all_warningsObject

Return an array of all warnings found.



72
73
74
# File 'lib/brakeman/checks.rb', line 72

def all_warnings
  @warnings + @template_warnings + @controller_warnings + @model_warnings
end

#diff(other_checks) ⇒ Object

Return a hash of arrays of new and fixed warnings

diff = checks.diff old_checks
diff[:fixed]  # [...]
diff[:new]    # [...]


65
66
67
68
69
# File 'lib/brakeman/checks.rb', line 65

def diff other_checks
  my_warnings = self.all_warnings
  other_warnings = other_checks.all_warnings
  Brakeman::Differ.new(my_warnings, other_warnings).diff
end