Class: Pipeline::Zap

Inherits:
BaseTask show all
Includes:
Util
Defined in:
lib/pipeline/tasks/zap.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) ⇒ Zap

Returns a new instance of Zap.



12
13
14
15
16
17
18
# File 'lib/pipeline/tasks/zap.rb', line 12

def initialize(trigger,tracker)
  super(trigger,tracker)
  @name = "ZAP"
  @description = "App Scanning"
  @stage = :live
  @labels << "live"
end

Instance Method Details

#analyzeObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/pipeline/tasks/zap.rb', line 66

def analyze
  begin   
    json = JSON.parse @result
    alerts = json["alerts"]
    count = 0
    alerts.each do |alert|
      count = count + 1
      description = alert["description"]
      detail = "Url: #{alert["url"]} Param: #{alert["param"]} \nReference: #{alert["reference"]}\n"+
               "Solution: #{alert["solution"]}\nCWE: #{alert["cweid"]}\tWASCID: #{alert["wascid"]}"
      source = @name + alert["url"]
      sev = severity alert["risk"]
      fingerprint = @name + alert["url"] + alert["alert"] + alert["param"]
      report description, detail, source, sev, fingerprint
    end
    Pipeline.debug "ZAP Identified #{count} issues."
  rescue Exception => e
    Pipeline.warn e.message
    Pipeline.notify "Problem running ZAP."
  end
end

#get_scan_id(response) ⇒ Object



50
51
52
53
# File 'lib/pipeline/tasks/zap.rb', line 50

def get_scan_id(response)
  json = JSON.parse response.body_str
  return json["scan"]
end

#poll_until_100(url) ⇒ Object



55
56
57
58
59
60
61
62
63
64
# File 'lib/pipeline/tasks/zap.rb', line 55

def poll_until_100(url)
  count = 0
  loop do
    sleep 5
    status = JSON.parse(Curl.get(url).body_str)
    count = count + 1      
    Pipeline.notify "Count ... #{count}"
    break if status["status"] == "100" or count > 100
  end
end

#runObject



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/pipeline/tasks/zap.rb', line 20

def run
  rootpath = @trigger.path
  base = "#{@tracker.options[:zap_host]}:#{@tracker.options[:zap_port]}"
  apikey = "#{@tracker.options[:zap_api_token]}"
  context = SecureRandom.uuid

  Pipeline.debug "Running ZAP on: #{rootpath} from #{base} with #{context}"

  # Create a new session so that the findings will be new.
  Curl.get("#{base}/JSON/core/action/newSession/?zapapiformat=JSON&apikey=#{apikey}&name=&overwrite=")

  # Set up Context
  Curl.get("#{base}/JSON/context/action/newContext/?&apikey=#{apikey}&contextName=#{context}")
  Curl.get("#{base}/JSON/context/action/includeInContext/?apikey=#{apikey}&contextName=#{context}&regex=#{rootpath}.*")

  # Spider
  spider = get_scan_id( Curl.get("#{base}/JSON/spider/action/scan/?apikey=#{apikey}&url=#{rootpath}&context=#{context}") )
  poll_until_100("#{base}/JSON/spider/view/status/?scanId=#{spider}")

  # Active Scan
  scan = get_scan_id ( Curl.get("#{base}/JSON/ascan/action/scan/?apikey=#{apikey}&recurse=true&inScopeOnly=true&url=#{rootpath}") )
  poll_until_100("#{base}/JSON/ascan/view/status/?scanId=#{scan}")
    
  # Result
  @result = Curl.get("#{base}/JSON/core/view/alerts/?baseurl=#{rootpath}").body_str

  # Remove Context
  Curl.get("#{base}/JSON/context/action/removeContext/?&apikey=#{apikey}&contextName=#{context}")
end

#supported?Boolean

Returns:

  • (Boolean)


88
89
90
91
92
93
94
95
96
97
# File 'lib/pipeline/tasks/zap.rb', line 88

def supported?
  base = "#{@tracker.options[:zap_host]}:#{@tracker.options[:zap_port]}"
  supported=JSON.parse(Curl.get("#{base}/JSON/core/view/version/").body_str)
  if supported["version"] =~ /2.(4|5).\d+/
    return true
  else
    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']}"
    return false
  end
end