Class: Pipeline::FindSecurityBugs

Inherits:
BaseTask
  • Object
show all
Includes:
Util
Defined in:
lib/pipeline/tasks/findsecbugs.rb

Instance Attribute Summary

Attributes inherited from BaseTask

#appname, #description, #findings, #labels, #name, #stage, #trigger, #warnings

Instance Method Summary collapse

Methods included from Util

#fingerprint, #relative_path, #runsystem, #strip_archive_path

Methods inherited from BaseTask

#directories_with?, #report, #severity, #warn

Constructor Details

#initialize(trigger, tracker) ⇒ FindSecurityBugs

Returns a new instance of FindSecurityBugs.



14
15
16
17
18
19
20
# File 'lib/pipeline/tasks/findsecbugs.rb', line 14

def initialize(trigger, tracker)
  super(trigger, tracker)
  @name = "FindSecurityBugs"
  @description = "FindSecurityBugs plugin for FindBugs"
  @stage = :code
  @labels << "code"
end

Instance Method Details

#analyzeObject



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/pipeline/tasks/findsecbugs.rb', line 45

def analyze
  begin
    @results.each do |result|
      description = result.xpath('ShortMessage').text
      bug_type = result.attributes['type'].value
      detail = "Class: #{result.at_xpath('Method').attributes['classname'].value}, Method: #{result.at_xpath('Method').attributes['name'].value}\n#{result.xpath('LongMessage').text}\nhttps://find-sec-bugs.github.io/bugs.htm##{bug_type}"

      file = result.at_xpath('SourceLine').attributes['sourcepath'].value
      trigger_path = Pathname.new(@trigger.path)
      real_path = nil
      trigger_path.find {|path| real_path = path if path.fnmatch "*/#{file}"}
      file = real_path.relative_path_from(trigger_path).to_s unless real_path.nil?

      line = result.at_xpath('SourceLine[@primary="true"]').attributes['start'].value
      code = "#{result.at_xpath('String').attributes['value'].value}"
      source = {:scanner => @name, :file => file, :line => line, :code => code}
      sev = result.attributes['priority'].value
      fprint = fingerprint("#{description}#{detail}#{source}")

      report description, detail, source, sev, fprint
    end
  rescue Exception => e
    Pipeline.warn e.message
    Pipeline.warn e.backtrace
  ensure
    File.unlink @results_file
  end
end

#runObject



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/pipeline/tasks/findsecbugs.rb', line 22

def run
  @results_file = Tempfile.new(['findsecbugs','xml'])

  unless File.exist?("#{@trigger.path}/.git/config")
    Dir.chdir(@trigger.path) do
      runsystem(true, "git", "init")
      runsystem(true, "git", "add", "*")
      runsystem(true, "git", "commit", "-am", "fake commit for mvn compile")
    end
  end

  directories_with?('pom.xml').each do |dir|
    Dir.chdir(dir) do
      runsystem(true, "mvn", "compile", "-fn")
    end
  end

  Dir.chdir(@tracker.options[:findsecbugs_path]) do
    runsystem(true, "/bin/sh", "#{@tracker.options[:findsecbugs_path]}/findsecbugs.sh", "-effort:max", "-quiet", "-xml:withMessages", "-output", "#{@results_file.path}", "#{@trigger.path}")
    @results = Nokogiri::XML(File.read(@results_file)).xpath '//BugInstance'
  end
end

#supported?Boolean

Returns:

  • (Boolean)


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/pipeline/tasks/findsecbugs.rb', line 74

def supported?
  unless find_executable0('mvn') and File.exist?("#{@trigger.path}/pom.xml")
    Pipeline.notify "FindSecurityBugs support requires maven and pom.xml"
    Pipeline.notify "Please install maven somewhere in your PATH and include a valid pom.xml in the project root"
    return false
  end

  unless @tracker.options.has_key?(:findsecbugs_path) and File.exist?("#{@tracker.options[:findsecbugs_path]}/findsecbugs.sh")
    Pipeline.notify "#{@tracker.options[:findsecbugs_path]}"
    Pipeline.notify "Download and unpack the latest findsecbugs-cli release: https://github.com/find-sec-bugs/find-sec-bugs/releases"
    return false
  else
    return true
  end
end