owasp-pipeline 0.8.5 → 0.8.6

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: bf5efee842fff5ee62a05d074fe47d057bc0dd1d
4
- data.tar.gz: 417d5379d1b73b82a0a20561d5d78d50e907c020
3
+ metadata.gz: e0a8269dc146b2c043c1f82f86a181b69e1bf35e
4
+ data.tar.gz: e1f15cfe853e2d53b8e894033a9b665f4813ff26
5
5
  SHA512:
6
- metadata.gz: 5c44a4dc6c22acacac6b6d3a4b6197da7427ed3373341b28f2c4b1d01064b9d7d3357ae59c9a4020bf7fc2bb462d913db3f353038bbed328d556f427c7d68c12
7
- data.tar.gz: 4a8f15ac36f2533638c0d8fc2d695168bc6bfa3bac7e3d41429b712d6e2b2618cd8b7c068f5b9d5140eaaaab9b9694e3e7100aad1a522e5fb75eefb3780a1206
6
+ metadata.gz: c6ff7447583d96ca3b88da5d54f0c85663879017c3e6d4cc4119e5d1969bfd36e356ab5db1e5aaea5bda4df181a95f39f826acac174d72bd53226058b609c741
7
+ data.tar.gz: 7d811611176d44b8f9d7c3a7955c049430142907f1fb453771724c102617a6a2b49bb9589e6d40e5ba2b880abe08dca874f0039aaadb7ed169fd5e0032ea21a8
@@ -0,0 +1,76 @@
1
+ require 'pipeline/filters/base_filter'
2
+
3
+ class Pipeline::ZAPCondensingFilter < Pipeline::BaseFilter
4
+
5
+ Pipeline::Filters.add self
6
+
7
+ def initialize
8
+ @name = "ZAP Condensing Filter"
9
+ @description = "Consolidate N ZAP warnings to one per issue type."
10
+ end
11
+
12
+ def filter tracker
13
+ Pipeline.debug "Have #{tracker.findings.count} items pre ZAP filter."
14
+ tracker.findings.each do |finding|
15
+ if zap? finding
16
+ if xframe? finding
17
+ record tracker,finding
18
+ elsif xcontenttypeoptions? finding
19
+ record tracker, finding
20
+ elsif dirbrowsing? finding
21
+ record tracker, finding
22
+ elsif xxssprotection? finding
23
+ record tracker, finding
24
+ end
25
+ end
26
+ end
27
+ Pipeline.debug "Have #{tracker.findings.count} items post ZAP filter."
28
+ end
29
+
30
+ def zap? finding
31
+ if finding.source =~ /\AZAP/
32
+ return true
33
+ end
34
+ return false
35
+ end
36
+
37
+ def xframe? finding
38
+ if finding.description == "X-Frame-Options header is not included in the HTTP response to protect against 'ClickJacking' attacks."
39
+ return true
40
+ end
41
+ return false
42
+ end
43
+
44
+ def xcontenttypeoptions? finding
45
+ if finding.description == "The Anti-MIME-Sniffing header X-Content-Type-Options was not set to 'nosniff'. This allows older versions of Internet Explorer and Chrome to perform MIME-sniffing on the response body, potentially causing the response body to be interpreted and displayed as a content type other than the declared content type. Current (early 2014) and legacy versions of Firefox will use the declared content type (if one is set), rather than performing MIME-sniffing."
46
+ return true
47
+ end
48
+ return false
49
+ end
50
+
51
+ def dirbrowsing? finding
52
+ if finding.description == "It is possible to view the directory listing. Directory listing may reveal hidden scripts, include files , backup source files etc which be accessed to read sensitive information."
53
+ return true
54
+ end
55
+ return false
56
+ end
57
+
58
+ def xxssprotection? finding
59
+ if finding.description == "Web Browser XSS Protection is not enabled, or is disabled by the configuration of the 'X-XSS-Protection' HTTP response header on the web server"
60
+ return true
61
+ end
62
+ return false
63
+ end
64
+
65
+ # Is it always true that the findings will be on the same site?
66
+ # For now, we can assume that.
67
+ # Note that this may not be an efficient way to to do this, but it seems to work as a first pass.
68
+ def record tracker, finding
69
+ tracker.findings.delete_if do |to_delete|
70
+ to_delete.description == finding.description
71
+ end
72
+ finding.detail << "\n\t** Consolidated ** - Potentially identified in > 1 spot." # Make sure to note that there were
73
+ tracker.findings.push finding
74
+ end
75
+
76
+ end
@@ -99,6 +99,13 @@ module Pipeline::Options
99
99
  options[:npm_registry] = url
100
100
  end
101
101
 
102
+ opts.on "--exclude path1,path2,path3,etc", Array, "A list of paths to ignore when running recursive tasks (npm, retirejs, snyk, etc)" do |paths|
103
+ paths.each do |path|
104
+ options[:exclude_dirs] ||= Set.new
105
+ options[:exclude_dirs] << path
106
+ end
107
+ end
108
+
102
109
  opts.separator ""
103
110
  opts.separator "Output options:"
104
111
 
@@ -43,6 +43,22 @@ class Pipeline::BaseTask
43
43
  @stage
44
44
  end
45
45
 
46
+ def directories_with? file, exclude_dirs = []
47
+ exclude_dirs = @tracker.options[:exclude_dirs] if exclude_dirs == [] and @tracker.options[:exclude_dirs]
48
+ results = []
49
+
50
+ Find.find(@trigger.path) do |path|
51
+ if FileTest.directory? path
52
+ Find.prune if exclude_dirs.include? File.basename(path) or exclude_dirs.include? File.basename(path) + '/'
53
+ next
54
+ end
55
+
56
+ Find.prune unless File.basename(path) == file
57
+
58
+ results << File.dirname(path)
59
+ end
60
+ return results
61
+ end
46
62
 
47
63
  def run
48
64
  end
@@ -17,7 +17,6 @@ class Pipeline::Brakeman < Pipeline::BaseTask
17
17
  end
18
18
 
19
19
  def run
20
- # Pipeline.notify "#{@name}"
21
20
  rootpath = @trigger.path
22
21
  @result=runsystem(true, "brakeman", "-A", "-q", "-f", "json", "#{rootpath}")
23
22
  end
@@ -57,4 +56,3 @@ class Pipeline::Brakeman < Pipeline::BaseTask
57
56
  end
58
57
 
59
58
  end
60
-
@@ -13,14 +13,15 @@ class Pipeline::BundleAudit < Pipeline::BaseTask
13
13
  @description = "Dependency Checker analysis for Ruby"
14
14
  @stage = :code
15
15
  @labels << "code" << "ruby"
16
+ @results = {}
16
17
  end
17
18
 
18
19
  def run
19
- # Pipeline.notify "#{@name}"
20
- rootpath = @trigger.path
21
- Pipeline.debug "Rootpath: #{rootpath}"
22
- Dir.chdir("#{rootpath}") do
23
- @result= runsystem(true, "bundle-audit", "check")
20
+ directories_with?('Gemfile.lock').each do |dir|
21
+ Pipeline.notify "#{@name} scanning: #{dir}"
22
+ Dir.chdir(dir) do
23
+ @results[dir] = runsystem(true, "bundle-audit", "check")
24
+ end
24
25
  end
25
26
  end
26
27
 
@@ -46,43 +47,45 @@ class Pipeline::BundleAudit < Pipeline::BaseTask
46
47
 
47
48
  private
48
49
  def get_warnings
49
- detail, jem, source, sev, hash = '','',{},'',''
50
- @result.each_line do | line |
50
+ @results.each do |dir, result|
51
+ detail, jem, source, sev, hash = '','',{},'',''
52
+ result.each_line do | line |
51
53
 
52
- if /\S/ !~ line
53
- # Signal section is over. Reset variables and report.
54
- if detail != ''
55
- report "Gem #{jem} has known security issues.", detail, source, sev, fingerprint(hash)
56
- end
54
+ if /\S/ !~ line
55
+ # Signal section is over. Reset variables and report.
56
+ if detail != ''
57
+ report "Gem #{jem} has known security issues.", detail, source, sev, fingerprint(hash)
58
+ end
57
59
 
58
- detail, jem, source, sev, hash = '','', {},'',''
59
- end
60
+ detail, jem, source, sev, hash = '','', {},'',''
61
+ end
60
62
 
61
- name, value = line.chomp.split(':')
62
- case name
63
- when 'Name'
64
- jem << value
65
- hash << value
66
- when 'Version'
67
- jem << value
68
- hash << value
69
- when 'Advisory'
70
- source = { :scanner => @name, :file => 'Gemfile.lock', :line => nil, :code => nil }
71
- hash << value
72
- when 'Criticality'
73
- sev = severity(value)
74
- hash << sev
75
- when 'URL'
76
- detail += line.chomp.split('URL:').last
77
- when 'Title'
78
- detail += ",#{value}"
79
- when 'Solution'
80
- detail += ": #{value}"
81
- when 'Insecure Source URI found'
82
- report "Insecure GEM Source", "#{line.chomp} - use git or https", {:scanner => @name, :file => 'Gemfile.lock', :line => nil, :code => nil}, severity('high'), fingerprint("bundlerauditgemsource#{line.chomp}")
83
- else
84
- if line =~ /\S/ and line !~ /Unpatched versions found/
85
- Pipeline.debug "Not sure how to handle line: #{line}"
63
+ name, value = line.chomp.split(':')
64
+ case name
65
+ when 'Name'
66
+ jem << value
67
+ hash << value
68
+ when 'Version'
69
+ jem << value
70
+ hash << value
71
+ when 'Advisory'
72
+ source = { :scanner => @name, :file => "#{relative_path(dir, @trigger.path)}/Gemfile.lock", :line => nil, :code => nil }
73
+ hash << value
74
+ when 'Criticality'
75
+ sev = severity(value)
76
+ hash << sev
77
+ when 'URL'
78
+ detail += line.chomp.split('URL:').last
79
+ when 'Title'
80
+ detail += ",#{value}"
81
+ when 'Solution'
82
+ detail += ": #{value}"
83
+ when 'Insecure Source URI found'
84
+ report "Insecure GEM Source", "#{line.chomp} - use git or https", {:scanner => @name, :file => 'Gemfile.lock', :line => nil, :code => nil}, severity('high'), fingerprint("bundlerauditgemsource#{line.chomp}")
85
+ else
86
+ if line =~ /\S/ and line !~ /Unpatched versions found/
87
+ Pipeline.debug "Not sure how to handle line: #{line}"
88
+ end
86
89
  end
87
90
  end
88
91
  end
@@ -90,4 +93,3 @@ class Pipeline::BundleAudit < Pipeline::BaseTask
90
93
 
91
94
 
92
95
  end
93
-
@@ -16,7 +16,6 @@ class Pipeline::Checkmarx < Pipeline::BaseTask
16
16
  end
17
17
 
18
18
  def run
19
- Pipeline.notify "#{@name}"
20
19
  rootpath = @trigger.path
21
20
  runsystem(true, "runCxConsole.sh", "scan", "-v",
22
21
  "-CxUser", "#{@tracker.options[:checkmarx_user]}",
@@ -16,7 +16,6 @@ class Pipeline::DawnScanner < Pipeline::BaseTask
16
16
  end
17
17
 
18
18
  def run
19
- Pipeline.notify "#{@name}"
20
19
  Dir.chdir("#{@trigger.path}") do
21
20
  @results_file = Tempfile.new(['dawnresults', 'xml'])
22
21
  runsystem(true, "dawn", "-F", "#{@results_file.path}", "-j", ".")
@@ -16,7 +16,6 @@ class Pipeline::ESLint < Pipeline::BaseTask
16
16
  end
17
17
 
18
18
  def run
19
- Pipeline.notify "#{@name}"
20
19
  rootpath = @trigger.path
21
20
  currentpath = File.expand_path File.dirname(__FILE__)
22
21
  Pipeline.debug "ESLint Config Path: #{currentpath}"
@@ -68,4 +67,3 @@ class Pipeline::ESLint < Pipeline::BaseTask
68
67
  end
69
68
 
70
69
  end
71
-
@@ -17,7 +17,6 @@ class Pipeline::FIM < Pipeline::BaseTask
17
17
  end
18
18
 
19
19
  def run
20
- Pipeline.notify "#{@name}"
21
20
  rootpath = @trigger.path
22
21
  if File.exists?("/area81/tmp/#{rootpath}/filehash")
23
22
  Pipeline.notify "File Hashes found, comparing to file system"
@@ -20,14 +20,23 @@ class Pipeline::FindSecurityBugs < Pipeline::BaseTask
20
20
  end
21
21
 
22
22
  def run
23
- Pipeline.notify "#{@name}"
24
23
  @results_file = Tempfile.new(['findsecbugs','xml'])
25
24
 
26
- Dir.chdir("#{@trigger.path}") do
27
- runsystem(true, "mvn", "compile", "-fn")
25
+ unless File.exist?("#{@trigger.path}/.git/config")
26
+ Dir.chdir(@trigger.path) do
27
+ system("git", "init")
28
+ system("git", "add", "*")
29
+ system("git", "commit", "-am", "fake commit for mvn compile")
30
+ end
31
+ end
32
+
33
+ directories_with?('pom.xml').each do |dir|
34
+ Dir.chdir(dir) do
35
+ runsystem(true, "mvn", "compile", "-fn")
36
+ end
28
37
  end
29
38
 
30
- Dir.chdir("#{@tracker.options[:findsecbugs_path]}") do
39
+ Dir.chdir(@tracker.options[:findsecbugs_path]) do
31
40
  runsystem(true, "/bin/sh", "#{@tracker.options[:findsecbugs_path]}/findsecbugs.sh", "-effort:max", "-quiet", "-xml:withMessages", "-output", "#{@results_file.path}", "#{@trigger.path}")
32
41
  @results = Nokogiri::XML(File.read(@results_file)).xpath '//BugInstance'
33
42
  end
@@ -0,0 +1,58 @@
1
+ require 'pipeline/tasks/base_task'
2
+ require 'pipeline/util'
3
+ require 'find'
4
+ require 'pry'
5
+
6
+ class Pipeline::Npm < Pipeline::BaseTask
7
+
8
+ Pipeline::Tasks.add self
9
+ include Pipeline::Util
10
+
11
+ def initialize(trigger, tracker)
12
+ super(trigger, tracker)
13
+ @name = "NPM"
14
+ @description = "Node Package Manager"
15
+ @stage = :file
16
+ @labels << "file" << "javascript"
17
+ @results = []
18
+ end
19
+
20
+ def run
21
+ exclude_dirs = ['node_modules','bower_components']
22
+ exclude_dirs = exclude_dirs.concat(@tracker.options[:exclude_dirs]).uniq if @tracker.options[:exclude_dirs]
23
+ directories_with?('package.json', exclude_dirs).each do |dir|
24
+ Pipeline.notify "#{@name} scanning: #{dir}"
25
+ Dir.chdir(dir) do
26
+ if @tracker.options.has_key?(:npm_registry)
27
+ registry = "--registry #{@tracker.options[:npm_registry]}"
28
+ else
29
+ registry = nil
30
+ end
31
+ @command = "npm install --ignore-scripts #{registry}"
32
+ @results << system(@command)
33
+ end
34
+ end
35
+ end
36
+
37
+ def analyze
38
+ begin
39
+ if @results.include? false
40
+ Pipeline.warn 'Error installing javascript dependencies with #{@command}'
41
+ end
42
+ rescue Exception => e
43
+ Pipeline.warn e.message
44
+ Pipeline.warn e.backtrace
45
+ end
46
+ end
47
+
48
+ def supported?
49
+ supported = find_executable0('npm')
50
+ unless supported
51
+ Pipeline.notify "Install npm: https://nodejs.org/en/download/"
52
+ return false
53
+ else
54
+ return true
55
+ end
56
+ end
57
+
58
+ end
@@ -12,31 +12,37 @@ class Pipeline::NodeSecurityProject < Pipeline::BaseTask
12
12
  @description = "Node Security Project"
13
13
  @stage = :code
14
14
  @labels << "code"
15
+ @results = []
15
16
  end
16
17
 
17
18
  def run
18
- Pipeline.notify "#{@name}"
19
- rootpath = @trigger.path
20
- Dir.chdir("#{rootpath}") do
21
- @results = JSON.parse `nsp check --output json 2>&1`
19
+ exclude_dirs = ['node_modules','bower_components']
20
+ exclude_dirs = exclude_dirs.concat(@tracker.options[:exclude_dirs]).uniq if @tracker.options[:exclude_dirs]
21
+ directories_with?('package.json', exclude_dirs).each do |dir|
22
+ Pipeline.notify "#{@name} scanning: #{dir}"
23
+ Dir.chdir(dir) do
24
+ @results << JSON.parse(`nsp check --output json 2>&1`)
25
+ end
22
26
  end
23
27
  end
24
28
 
25
29
  def analyze
26
30
  begin
27
- # This block iterates through each package name found and selects the unique nsp advisories
28
- # regardless of version, and builds a pipeline finding hash for each unique package/advisory combo.
29
- @results.uniq {|finding| finding['module']}.each do |package|
30
- @results.select {|f| f['module'] == package['module']}.uniq {|m| m['advisory']}.each do |unique_finding|
31
- description = "#{unique_finding['module']} - #{unique_finding['title']}"
32
- detail = "Upgrade to versions: #{unique_finding['patched_versions']}\n#{unique_finding['advisory']}"
33
- source = {
34
- :scanner => 'NodeSecurityProject',
35
- :file => "#{unique_finding['module']} - #{unique_finding['vulnerable_versions']}",
36
- :line => nil,
37
- :code => nil
38
- }
39
- report description, detail, source, 'medium', fingerprint("#{description}#{detail}#{source}")
31
+ @results.each do |dir_result|
32
+ # This block iterates through each package name found and selects the unique nsp advisories
33
+ # regardless of version, and builds a pipeline finding hash for each unique package/advisory combo.
34
+ dir_result.uniq {|finding| finding['module']}.each do |package|
35
+ dir_result.select {|f| f['module'] == package['module']}.uniq {|m| m['advisory']}.each do |unique_finding|
36
+ description = "#{unique_finding['module']} - #{unique_finding['title']}"
37
+ detail = "Upgrade to versions: #{unique_finding['patched_versions']}\n#{unique_finding['advisory']}"
38
+ source = {
39
+ :scanner => 'NodeSecurityProject',
40
+ :file => "#{unique_finding['module']} - #{unique_finding['vulnerable_versions']}",
41
+ :line => nil,
42
+ :code => nil
43
+ }
44
+ report description, detail, source, 'medium', fingerprint("#{description}#{detail}#{source}")
45
+ end
40
46
  end
41
47
  end
42
48
  rescue Exception => e
@@ -56,4 +62,3 @@ class Pipeline::NodeSecurityProject < Pipeline::BaseTask
56
62
  end
57
63
 
58
64
  end
59
-
@@ -17,7 +17,6 @@ class Pipeline::PMD < Pipeline::BaseTask
17
17
  end
18
18
 
19
19
  def run
20
- Pipeline.notify "#{@name}"
21
20
  @tracker.options[:pmd_checks] ||= "java-basic,java-sunsecure"
22
21
  Dir.chdir @tracker.options[:pmd_path] do
23
22
  @results = Nokogiri::XML(`bin/run.sh pmd -d #{@trigger.path} -f xml -R #{@tracker.options[:pmd_checks]}`).xpath('//file')
@@ -3,6 +3,7 @@ require 'json'
3
3
  require 'pipeline/util'
4
4
  require 'jsonpath'
5
5
  require 'pathname'
6
+ require 'pry'
6
7
 
7
8
  class Pipeline::RetireJS < Pipeline::BaseTask
8
9
 
@@ -15,28 +16,26 @@ class Pipeline::RetireJS < Pipeline::BaseTask
15
16
  @description = "Dependency analysis for JavaScript"
16
17
  @stage = :code
17
18
  @labels << "code" << "javascript"
19
+ @results = []
18
20
  end
19
21
 
20
22
  def run
21
- rootpath = @trigger.path
22
- Pipeline.debug "Retire rootpath: #{rootpath}"
23
- Dir.chdir("#{rootpath}") do
24
- if @tracker.options.has_key?(:npm_registry)
25
- registry = "--registry #{@tracker.options[:npm_registry]}"
26
- else
27
- registry = nil
28
- end
29
- @result = `npm install --ignore-scripts #{registry}` # Need this even though it is slow to get full dependency analysis.
23
+ exclude_dirs = ['node_modules','bower_components']
24
+ exclude_dirs = exclude_dirs.concat(@tracker.options[:exclude_dirs]).uniq if @tracker.options[:exclude_dirs]
25
+ directories_with?('package.json', exclude_dirs).each do |dir|
26
+ Pipeline.notify "#{@name} scanning: #{dir}"
27
+ @results << `retire -c --outputformat json --path #{dir} 2>&1`
30
28
  end
31
- @result = `retire -c --outputformat json --path #{rootpath} 2>&1`
32
29
  end
33
30
 
34
31
  def analyze
35
32
  begin
36
- vulnerabilities = parse_retire_json(JSON.parse(@result))
33
+ @results.each do |result|
34
+ vulnerabilities = parse_retire_json(JSON.parse(result))
37
35
 
38
- vulnerabilities.each do |vuln|
39
- report "Package #{vuln[:package]} has known security issues", vuln[:detail], vuln[:source], vuln[:severity], fingerprint("#{vuln[:package]}#{vuln[:source]}#{vuln[:severity]}")
36
+ vulnerabilities.each do |vuln|
37
+ report "Package #{vuln[:package]} has known security issues", vuln[:detail], vuln[:source], vuln[:severity], fingerprint("#{vuln[:package]}#{vuln[:source]}#{vuln[:severity]}")
38
+ end
40
39
  end
41
40
  rescue Exception => e
42
41
  Pipeline.warn e.message
@@ -84,7 +83,7 @@ class Pipeline::RetireJS < Pipeline::BaseTask
84
83
  result.select { |r| !r['file'].nil? }.each do |file_result|
85
84
  JsonPath.on(file_result, '$..component').uniq.each do |comp|
86
85
  JsonPath.on(file_result, "$..results[?(@.component == \'#{comp}\')].version").uniq.each do |version|
87
- source_path = Pathname.new(file_result['file']).relative_path_from Pathname.new(@trigger.path)
86
+ source_path = relative_path(file_result['file'], @trigger.path)
88
87
  vulnerabilities.select { |v| v[:package] == "#{comp}-#{version}" }.first[:source] = { :scanner => @name, :file => source_path.to_s, :line => nil, :code => nil }
89
88
  end
90
89
  end
@@ -103,4 +102,3 @@ class Pipeline::RetireJS < Pipeline::BaseTask
103
102
  end
104
103
 
105
104
  end
106
-
@@ -0,0 +1,81 @@
1
+ require 'pipeline/tasks/base_task'
2
+ require 'pipeline/util'
3
+ require 'redcarpet'
4
+
5
+ class Pipeline::Snyk < Pipeline::BaseTask
6
+
7
+ Pipeline::Tasks.add self
8
+ include Pipeline::Util
9
+
10
+ def initialize(trigger, tracker)
11
+ super(trigger, tracker)
12
+ @name = "Snyk"
13
+ @description = "Snyk.io JS dependency checker"
14
+ @stage = :code
15
+ @labels << "code" << "javascript"
16
+ @results = []
17
+ end
18
+
19
+ def run
20
+ exclude_dirs = ['node_modules','bower_components']
21
+ exclude_dirs = exclude_dirs.concat(@tracker.options[:exclude_dirs]).uniq if @tracker.options[:exclude_dirs]
22
+ directories_with?('package.json', exclude_dirs).each do |dir|
23
+ Pipeline.notify "#{@name} scanning: #{dir}"
24
+ Dir.chdir(dir) do
25
+ @results << JSON.parse(runsystem(true, "snyk", "test", "--json"))["vulnerabilities"]
26
+ end
27
+ end
28
+ end
29
+
30
+ def analyze
31
+ begin
32
+ markdown = Redcarpet::Markdown.new Redcarpet::Render::HTML.new(link_attributes: {target: "_blank"}), autolink: true, tables: true
33
+
34
+ @results.each do |dir_result|
35
+ # We build a single finding for each uniq result ID, adding the unique info (upgrade path and files) as a list
36
+ dir_result.uniq {|r| r['id']}.each do |result|
37
+ description = "#{result['name']}@#{result['version']} - #{result['title']}"
38
+
39
+ # Use Redcarpet to render the Markdown details to something pretty for web display
40
+ detail = markdown.render(result['description']).gsub('h2>','strong>').gsub('h3>', 'strong>')
41
+ upgrade_paths = [ "Upgrade Path:\n" ]
42
+ files = []
43
+
44
+ # Pull the list of files and upgrade paths from all results matching this ID
45
+ # This uses the same form as the retirejs task so it all looks nice together
46
+ dir_result.select{|r| r['id'] == result['id']}.each do |res|
47
+ res['upgradePath'].each_with_index do |upgrade, i|
48
+ upgrade_paths << "#{res['from'][i]} -> #{upgrade}"
49
+ end
50
+ files << res['from'].join('->')
51
+ end
52
+
53
+ source = {
54
+ :scanner => @name,
55
+ :file => files.join('<br>'),
56
+ :line => nil,
57
+ :code => upgrade_paths.uniq.join("\n"),
58
+ }
59
+ sev = severity(result['severity'])
60
+ fprint = fingerprint("#{description}#{detail}#{source}#{sev}")
61
+
62
+ report description, detail, source, sev, fprint
63
+ end
64
+ end
65
+ rescue Exception => e
66
+ Pipeline.warn e.message
67
+ Pipeline.warn e.backtrace
68
+ end
69
+ end
70
+
71
+ def supported?
72
+ supported = find_executable0('snyk')
73
+ unless supported
74
+ Pipeline.notify "Install Snyk: 'npm install -g snyk'"
75
+ return false
76
+ else
77
+ return true
78
+ end
79
+ end
80
+
81
+ end
@@ -24,7 +24,10 @@ class Pipeline::Zap < Pipeline::BaseTask
24
24
  context = SecureRandom.uuid
25
25
 
26
26
  Pipeline.debug "Running ZAP on: #{rootpath} from #{base} with #{context}"
27
-
27
+
28
+ # Create a new session so that the findings will be new.
29
+ Curl.get("#{base}/JSON/core/action/newSession/?zapapiformat=JSON&apikey=#{apikey}&name=&overwrite=")
30
+
28
31
  # Set up Context
29
32
  Curl.get("#{base}/JSON/context/action/newContext/?&apikey=#{apikey}&contextName=#{context}")
30
33
  Curl.get("#{base}/JSON/context/action/includeInContext/?apikey=#{apikey}&contextName=#{context}&regex=#{rootpath}.*")
@@ -85,10 +88,10 @@ class Pipeline::Zap < Pipeline::BaseTask
85
88
  def supported?
86
89
  base = "#{@tracker.options[:zap_host]}:#{@tracker.options[:zap_port]}"
87
90
  supported=JSON.parse(Curl.get("#{base}/JSON/core/view/version/").body_str)
88
- if supported["version"] == "2.4.3"
91
+ if supported["version"] =~ /2.(4|5).\d+/
89
92
  return true
90
93
  else
91
- Pipeline.notify "Install ZAP from owasp.org and ensure that the configuration to connect is correct."
94
+ Pipeline.notify "Install ZAP from owasp.org and ensure that the configuration to connect is correct. Supported versions = 2.4.0 and up - got #{supported['version']}"
92
95
  return false
93
96
  end
94
97
  end
@@ -60,8 +60,8 @@ class Pipeline::Tasks
60
60
 
61
61
  #Run or don't run task based on options
62
62
  #Now case-insensitive specifiers: nodesecurityproject = Pipeline::NodeSecurityProject
63
-
64
- if tracker.options[:skip_tasks]
63
+
64
+ if tracker.options[:skip_tasks]
65
65
  skip_tasks = tracker.options[:skip_tasks].map {|task| task.downcase}
66
66
  end
67
67
  if (tracker.options[:run_tasks])
@@ -73,9 +73,9 @@ class Pipeline::Tasks
73
73
 
74
74
  task = c.new(trigger, tracker)
75
75
  begin
76
- if task.supported? and task.stage == stage
77
- if task.labels.intersect? tracker.options[:labels] or # Only run tasks with labels
78
- ( run_tasks and run_tasks.include? task_name.downcase ) # or that are explicitly requested.
76
+ if task.supported? and task.stage == stage
77
+ if task.labels.intersect? tracker.options[:labels] or # Only run tasks with labels
78
+ ( run_tasks and run_tasks.include? task_name.downcase ) # or that are explicitly requested.
79
79
  Pipeline.notify "#{stage} - #{task_name} - #{task.labels}"
80
80
  task.run
81
81
  task.analyze
@@ -1,3 +1,3 @@
1
1
  module Pipeline
2
- Version = "0.8.5"
2
+ Version = "0.8.6"
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.5
4
+ version: 0.8.6
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-03-07 00:00:00.000000000 Z
13
+ date: 2016-04-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: terminal-table
@@ -166,6 +166,20 @@ dependencies:
166
166
  - - ">="
167
167
  - !ruby/object:Gem::Version
168
168
  version: 1.6.0
169
+ - !ruby/object:Gem::Dependency
170
+ name: redcarpet
171
+ requirement: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ type: :runtime
177
+ prerelease: false
178
+ version_requirements: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
169
183
  - !ruby/object:Gem::Dependency
170
184
  name: pry
171
185
  requirement: !ruby/object:Gem::Requirement
@@ -211,6 +225,7 @@ files:
211
225
  - lib/pipeline/filters/base_filter.rb
212
226
  - lib/pipeline/filters/jira_one_time_filter.rb
213
227
  - lib/pipeline/filters/remove_all_filter.rb
228
+ - lib/pipeline/filters/zap_consdensing_filter.rb
214
229
  - lib/pipeline/finding.rb
215
230
  - lib/pipeline/mounters.rb
216
231
  - lib/pipeline/mounters/base_mounter.rb
@@ -237,6 +252,7 @@ files:
237
252
  - lib/pipeline/tasks/eslint.rb
238
253
  - lib/pipeline/tasks/fim.rb
239
254
  - lib/pipeline/tasks/findsecbugs.rb
255
+ - lib/pipeline/tasks/npm.rb
240
256
  - lib/pipeline/tasks/nsp.rb
241
257
  - lib/pipeline/tasks/owasp-dep-check.rb
242
258
  - lib/pipeline/tasks/patterns.json
@@ -245,6 +261,7 @@ files:
245
261
  - lib/pipeline/tasks/scanjs-eslintrc
246
262
  - lib/pipeline/tasks/scanjs.rb
247
263
  - lib/pipeline/tasks/sfl.rb
264
+ - lib/pipeline/tasks/snyk.rb
248
265
  - lib/pipeline/tasks/test.rb
249
266
  - lib/pipeline/tasks/zap.rb
250
267
  - lib/pipeline/tracker.rb