owasp-pipeline 0.8.3 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c19bcf63e27cbc2579358e2f581943797d31b056
4
- data.tar.gz: 4b1daacd45d7dcb1d5bad0643da0b9c9cf8e93ad
3
+ metadata.gz: bf5efee842fff5ee62a05d074fe47d057bc0dd1d
4
+ data.tar.gz: 417d5379d1b73b82a0a20561d5d78d50e907c020
5
5
  SHA512:
6
- metadata.gz: cf4edf3934d7f2b596bc6baf3c1e85449100026b86aec1fcb690723a8f4cb2f48c2e3a974c7b79ec478384970501c1f8413ed7a4743f1e5087f922cb8571a06e
7
- data.tar.gz: c7cdbd7eaf00185447d5fbb2ebf042f4c68cdfa15ef10547bd923b98d8373a736b69b3c48cc030728f05164502852e07a7eaad6a38f7660bd17e7db77c91b1f5
6
+ metadata.gz: 5c44a4dc6c22acacac6b6d3a4b6197da7427ed3373341b28f2c4b1d01064b9d7d3357ae59c9a4020bf7fc2bb462d913db3f353038bbed328d556f427c7d68c12
7
+ data.tar.gz: 4a8f15ac36f2533638c0d8fc2d695168bc6bfa3bac7e3d41429b712d6e2b2618cd8b7c068f5b9d5140eaaaab9b9694e3e7100aad1a522e5fb75eefb3780a1206
@@ -2,7 +2,7 @@ require 'pipeline/mounters/base_mounter'
2
2
 
3
3
  class Pipeline::FileSystemMounter < Pipeline::BaseMounter
4
4
  Pipeline::Mounters.add self
5
-
5
+
6
6
  def initialize trigger, options
7
7
  super(trigger)
8
8
  @options = options
@@ -15,11 +15,6 @@ class Pipeline::FileSystemMounter < Pipeline::BaseMounter
15
15
  end
16
16
 
17
17
  def supports? target
18
- last = target.slice(-1)
19
- if last === "/" or last === "."
20
- return true
21
- else
22
- return false
23
- end
18
+ File.directory? target
24
19
  end
25
20
  end
@@ -190,6 +190,24 @@ module Pipeline::Options
190
190
  options[:checkmarx_project] = project
191
191
  end
192
192
 
193
+ opts.separator ""
194
+ opts.separator "PMD options:"
195
+
196
+ opts.on "--pmd-path PATH", "The full path to the base PMD directory" do |dir|
197
+ options[:pmd_path] = dir
198
+ end
199
+
200
+ opts.on "--pmd-checks CHECK1,CHECK2", "The list of checks passed to PMD run.sh -R, default: 'java-basic,java-sunsecure'" do |checks|
201
+ options[:pmd_checks] = checks
202
+ end
203
+
204
+ opts.separator ""
205
+ opts.separator "FindSecurityBugs options:"
206
+
207
+ opts.on "--findsecbugs-path PATH", "The full path to the base FindSecurityBugs directory" do |dir|
208
+ options[:findsecbugs_path] = dir
209
+ end
210
+
193
211
  opts.separator ""
194
212
  opts.separator "Configuration files:"
195
213
 
@@ -1,6 +1,6 @@
1
1
  require 'pipeline/tasks/base_task'
2
2
  require 'pipeline/util'
3
- # require 'nokogiri'
3
+ require 'nokogiri'
4
4
 
5
5
  class Pipeline::Checkmarx < Pipeline::BaseTask
6
6
 
@@ -28,7 +28,7 @@ class Pipeline::Checkmarx < Pipeline::BaseTask
28
28
  "-ReportXML", "#{rootpath}checkmarx_results.xml",
29
29
  "-Log", "#{@tracker.options[:checkmarx_log]}"
30
30
  )
31
- # @results = Nokogiri::XML(File.read("#{rootpath}checkmarx_results.xml")).xpath '//Result'
31
+ @results = Nokogiri::XML(File.read("#{rootpath}checkmarx_results.xml")).xpath '//Result'
32
32
  end
33
33
 
34
34
  def analyze
@@ -38,9 +38,9 @@ class Pipeline::Checkmarx < Pipeline::BaseTask
38
38
  detail = result.attributes['DeepLink'].value
39
39
  source = { :scanner => @name, :file => result.attributes['FileName'].value, :line => result.attributes['Line'].value.to_i, :code => result.at_xpath('Path/PathNode/Snippet/Line/Code').text }
40
40
  sev = severity(result.parent.attributes['Severity'].value)
41
- print = fingerprint("#{description}#{source}#{sev}")
41
+ fprint = fingerprint("#{description}#{source}#{sev}")
42
42
 
43
- report description, detail, source, sev, print
43
+ report description, detail, source, sev, fprint
44
44
  end
45
45
  rescue Exception => e
46
46
  Pipeline.warn e.message
@@ -59,4 +59,3 @@ class Pipeline::Checkmarx < Pipeline::BaseTask
59
59
  end
60
60
 
61
61
  end
62
-
@@ -0,0 +1,56 @@
1
+ require 'pipeline/tasks/base_task'
2
+ require 'pipeline/util'
3
+ require 'tempfile'
4
+
5
+ class Pipeline::DawnScanner < Pipeline::BaseTask
6
+
7
+ Pipeline::Tasks.add self
8
+ include Pipeline::Util
9
+
10
+ def initialize(trigger, tracker)
11
+ super(trigger, tracker)
12
+ @name = "DawnScanner"
13
+ @description = "DawnScanner ruby analyzer"
14
+ @stage = :code
15
+ @labels << "code"
16
+ end
17
+
18
+ def run
19
+ Pipeline.notify "#{@name}"
20
+ Dir.chdir("#{@trigger.path}") do
21
+ @results_file = Tempfile.new(['dawnresults', 'xml'])
22
+ runsystem(true, "dawn", "-F", "#{@results_file.path}", "-j", ".")
23
+ @results = JSON.parse(File.read("#{@results_file.path}"))['vulnerabilities']
24
+ end
25
+ end
26
+
27
+ def analyze
28
+ begin
29
+ @results.each do |result|
30
+ description = result['name'].gsub('\n',' ')
31
+ detail = "#{result['message']}\n#{result['remediation']}\n#{result['cve_link']}"
32
+ source = {:scanner => @name, :file => nil, :line => nil, :code => nil}
33
+ sev = severity(result['severity'])
34
+ fprint = fingerprint("#{description}#{detail}#{source}#{sev}")
35
+
36
+ report description, detail, source, sev, fprint
37
+ end
38
+ rescue Exception => e
39
+ Pipeline.warn e.message
40
+ Pipeline.warn e.backtrace
41
+ ensure
42
+ File.unlink @results_file
43
+ end
44
+ end
45
+
46
+ def supported?
47
+ supported=runsystem(true, "dawn", "--version")
48
+ if supported =~ /command not found/
49
+ Pipeline.notify "Install dawnscanner: 'gem install dawnscanner'"
50
+ return false
51
+ else
52
+ return true
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,81 @@
1
+ require 'pipeline/tasks/base_task'
2
+ require 'pipeline/util'
3
+ require 'nokogiri'
4
+ require 'tempfile'
5
+ require 'mkmf'
6
+
7
+ MakeMakefile::Logging.instance_variable_set(:@logfile, File::NULL)
8
+
9
+ class Pipeline::FindSecurityBugs < Pipeline::BaseTask
10
+
11
+ Pipeline::Tasks.add self
12
+ include Pipeline::Util
13
+
14
+ def initialize(trigger, tracker)
15
+ super(trigger, tracker)
16
+ @name = "FindSecurityBugs"
17
+ @description = "FindSecurityBugs plugin for FindBugs"
18
+ @stage = :code
19
+ @labels << "code"
20
+ end
21
+
22
+ def run
23
+ Pipeline.notify "#{@name}"
24
+ @results_file = Tempfile.new(['findsecbugs','xml'])
25
+
26
+ Dir.chdir("#{@trigger.path}") do
27
+ runsystem(true, "mvn", "compile", "-fn")
28
+ end
29
+
30
+ Dir.chdir("#{@tracker.options[:findsecbugs_path]}") do
31
+ runsystem(true, "/bin/sh", "#{@tracker.options[:findsecbugs_path]}/findsecbugs.sh", "-effort:max", "-quiet", "-xml:withMessages", "-output", "#{@results_file.path}", "#{@trigger.path}")
32
+ @results = Nokogiri::XML(File.read(@results_file)).xpath '//BugInstance'
33
+ end
34
+ end
35
+
36
+ def analyze
37
+ begin
38
+ @results.each do |result|
39
+ description = result.xpath('ShortMessage').text
40
+ bug_type = result.attributes['type'].value
41
+ 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}"
42
+
43
+ file = result.at_xpath('SourceLine').attributes['sourcepath'].value
44
+ trigger_path = Pathname.new(@trigger.path)
45
+ real_path = nil
46
+ trigger_path.find {|path| real_path = path if path.fnmatch "*/#{file}"}
47
+ file = real_path.relative_path_from(trigger_path).to_s unless real_path.nil?
48
+
49
+ line = result.at_xpath('SourceLine[@primary="true"]').attributes['start'].value
50
+ code = "#{result.at_xpath('String').attributes['value'].value}"
51
+ source = {:scanner => @name, :file => file, :line => line, :code => code}
52
+ sev = result.attributes['priority'].value
53
+ fprint = fingerprint("#{description}#{detail}#{source}")
54
+
55
+ report description, detail, source, sev, fprint
56
+ end
57
+ rescue Exception => e
58
+ Pipeline.warn e.message
59
+ Pipeline.warn e.backtrace
60
+ ensure
61
+ File.unlink @results_file
62
+ end
63
+ end
64
+
65
+ def supported?
66
+ unless find_executable0('mvn') and File.exist?("#{@trigger.path}/pom.xml")
67
+ Pipeline.notify "FindSecurityBugs support requires maven and pom.xml"
68
+ Pipeline.notify "Please install maven somewhere in your PATH and include a valid pom.xml in the project root"
69
+ return false
70
+ end
71
+
72
+ unless @tracker.options.has_key?(:findsecbugs_path) and File.exist?("#{@tracker.options[:findsecbugs_path]}/findsecbugs.sh")
73
+ Pipeline.notify "#{@tracker.options[:findsecbugs_path]}"
74
+ Pipeline.notify "Download and unpack the latest findsecbugs-cli release: https://github.com/find-sec-bugs/find-sec-bugs/releases"
75
+ return false
76
+ else
77
+ return true
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,64 @@
1
+ require 'pipeline/tasks/base_task'
2
+ require 'pipeline/util'
3
+ require 'nokogiri'
4
+ require 'pathname'
5
+
6
+ class Pipeline::PMD < Pipeline::BaseTask
7
+
8
+ Pipeline::Tasks.add self
9
+ include Pipeline::Util
10
+
11
+ def initialize(trigger, tracker)
12
+ super(trigger, tracker)
13
+ @name = "PMD"
14
+ @description = "PMD Source Code Analyzer"
15
+ @stage = :code
16
+ @labels << "code"
17
+ end
18
+
19
+ def run
20
+ Pipeline.notify "#{@name}"
21
+ @tracker.options[:pmd_checks] ||= "java-basic,java-sunsecure"
22
+ Dir.chdir @tracker.options[:pmd_path] do
23
+ @results = Nokogiri::XML(`bin/run.sh pmd -d #{@trigger.path} -f xml -R #{@tracker.options[:pmd_checks]}`).xpath('//file')
24
+ end
25
+ end
26
+
27
+ def analyze
28
+ begin
29
+ @results.each do |result|
30
+ attributes = result.at_xpath('violation').attributes
31
+ description = result.children.children.to_s.strip
32
+ detail = "Ruleset: #{attributes['ruleset']}"
33
+ source = {:scanner => @name, :file => result.attributes['name'].to_s.split(Pathname.new(@trigger.path).cleanpath.to_s)[1][1..-1], :line => attributes['beginline'].to_s, :code => "package: #{attributes['package'].to_s}\nclass: #{attributes['class'].to_s}\nmethod: #{attributes['method'].to_s}" }
34
+ case attributes['priority'].value.to_i
35
+ when 3
36
+ sev = 1
37
+ when 2
38
+ sev = 2
39
+ when 1
40
+ sev = 3
41
+ else
42
+ sev = 0
43
+ end
44
+ fprint = fingerprint("#{description}#{detail}#{source}#{sev}")
45
+
46
+ report description, detail, source, sev, fprint
47
+ end
48
+ rescue Exception => e
49
+ Pipeline.warn e.message
50
+ Pipeline.warn e.backtrace
51
+ end
52
+ end
53
+
54
+ def supported?
55
+ unless @tracker.options.has_key?(:pmd_path) and File.exist?("#{@tracker.options[:pmd_path]}/bin/run.sh")
56
+ Pipeline.notify "#{@tracker.options[:pmd_path]}"
57
+ Pipeline.notify "Install PMD from: https://pmd.github.io/"
58
+ return false
59
+ else
60
+ return true
61
+ end
62
+ end
63
+
64
+ end
@@ -2,6 +2,7 @@ require 'pipeline/tasks/base_task'
2
2
  require 'pipeline/util'
3
3
  require 'json'
4
4
  require 'curb'
5
+ require 'securerandom'
5
6
 
6
7
  class Pipeline::Zap < Pipeline::BaseTask
7
8
 
@@ -19,21 +20,33 @@ class Pipeline::Zap < Pipeline::BaseTask
19
20
  def run
20
21
  rootpath = @trigger.path
21
22
  base = "#{@tracker.options[:zap_host]}:#{@tracker.options[:zap_port]}"
22
- Pipeline.debug "Running ZAP on: #{rootpath} from #{base}"
23
+ apikey = "#{@tracker.options[:zap_api_token]}"
24
+ context = SecureRandom.uuid
23
25
 
24
- # TODO: Add API Key
25
- # TODO: Find out if we need to worry about "contexts" stepping on each other.
26
+ Pipeline.debug "Running ZAP on: #{rootpath} from #{base} with #{context}"
27
+
28
+ # Set up Context
29
+ Curl.get("#{base}/JSON/context/action/newContext/?&apikey=#{apikey}&contextName=#{context}")
30
+ Curl.get("#{base}/JSON/context/action/includeInContext/?apikey=#{apikey}&contextName=#{context}&regex=#{rootpath}.*")
26
31
 
27
32
  # Spider
28
- Curl.get("#{base}/JSON/spider/action/scan/?#{rootpath}")
29
- poll_until_100("#{base}/JSON/spider/view/status")
33
+ spider = get_scan_id( Curl.get("#{base}/JSON/spider/action/scan/?apikey=#{apikey}&url=#{rootpath}&context=#{context}") )
34
+ poll_until_100("#{base}/JSON/spider/view/status/?scanId=#{spider}")
30
35
 
31
36
  # Active Scan
32
- Curl.get("#{base}/JSON/ascan/action/scan/?recurse=true&inScopeOnly=true&url=#{rootpath}")
33
- poll_until_100("#{base}/JSON/ascan/view/status/")
37
+ scan = get_scan_id ( Curl.get("#{base}/JSON/ascan/action/scan/?apikey=#{apikey}&recurse=true&inScopeOnly=true&url=#{rootpath}") )
38
+ poll_until_100("#{base}/JSON/ascan/view/status/?scanId=#{scan}")
34
39
 
35
40
  # Result
36
- @result = Curl.get("#{base}/JSON/core/view/alerts/").body_str
41
+ @result = Curl.get("#{base}/JSON/core/view/alerts/?baseurl=#{rootpath}").body_str
42
+
43
+ # Remove Context
44
+ Curl.get("#{base}/JSON/context/action/removeContext/?&apikey=#{apikey}&contextName=#{context}")
45
+ end
46
+
47
+ def get_scan_id(response)
48
+ json = JSON.parse response.body_str
49
+ return json["scan"]
37
50
  end
38
51
 
39
52
  def poll_until_100(url)
@@ -1,3 +1,3 @@
1
1
  module Pipeline
2
- Version = "0.8.3"
2
+ Version = "0.8.5"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: owasp-pipeline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.3
4
+ version: 0.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Konda
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-02-05 00:00:00.000000000 Z
13
+ date: 2016-03-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: terminal-table
@@ -124,6 +124,76 @@ dependencies:
124
124
  - - ">="
125
125
  - !ruby/object:Gem::Version
126
126
  version: 0.5.7
127
+ - !ruby/object:Gem::Dependency
128
+ name: nokogiri
129
+ requirement: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: 1.6.6.2
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: 1.6.6.2
141
+ - !ruby/object:Gem::Dependency
142
+ name: rake
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ type: :runtime
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ - !ruby/object:Gem::Dependency
156
+ name: dawnscanner
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: 1.6.0
162
+ type: :runtime
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: 1.6.0
169
+ - !ruby/object:Gem::Dependency
170
+ name: pry
171
+ requirement: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ type: :development
177
+ prerelease: false
178
+ version_requirements: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ - !ruby/object:Gem::Dependency
184
+ name: pry-byebug
185
+ requirement: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ type: :development
191
+ prerelease: false
192
+ version_requirements: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: '0'
127
197
  description: Pipeline detects security vulnerabilities in code.
128
198
  email: matt.konda@owasp.org
129
199
  executables:
@@ -163,11 +233,14 @@ files:
163
233
  - lib/pipeline/tasks/brakeman.rb
164
234
  - lib/pipeline/tasks/bundle-audit.rb
165
235
  - lib/pipeline/tasks/checkmarx.rb
236
+ - lib/pipeline/tasks/dawnscanner.rb
166
237
  - lib/pipeline/tasks/eslint.rb
167
238
  - lib/pipeline/tasks/fim.rb
239
+ - lib/pipeline/tasks/findsecbugs.rb
168
240
  - lib/pipeline/tasks/nsp.rb
169
241
  - lib/pipeline/tasks/owasp-dep-check.rb
170
242
  - lib/pipeline/tasks/patterns.json
243
+ - lib/pipeline/tasks/pmd.rb
171
244
  - lib/pipeline/tasks/retirejs.rb
172
245
  - lib/pipeline/tasks/scanjs-eslintrc
173
246
  - lib/pipeline/tasks/scanjs.rb