qualys 0.1.4 → 0.1.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 +4 -4
- data/.gitignore +3 -2
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +71 -0
- data/.travis.yml +13 -1
- data/Gemfile +3 -1
- data/Gemfile.lock +91 -0
- data/README.md +50 -10
- data/Rakefile +3 -4
- data/lib/qualys.rb +10 -11
- data/lib/qualys/api.rb +38 -47
- data/lib/qualys/auth.rb +11 -20
- data/lib/qualys/compliance.rb +3 -7
- data/lib/qualys/config.rb +3 -5
- data/lib/qualys/host.rb +17 -0
- data/lib/qualys/report.rb +90 -0
- data/lib/qualys/scans.rb +10 -22
- data/lib/qualys/version.rb +1 -1
- data/lib/qualys/vulnerability.rb +74 -0
- data/qualys.gemspec +18 -19
- data/spec/fixtures/vcr_cassettes/api_get.yml +52 -0
- data/spec/fixtures/vcr_cassettes/create_global_report.yml +68 -0
- data/spec/fixtures/vcr_cassettes/emptyscans.yml +35 -0
- data/spec/fixtures/vcr_cassettes/get.yml +107 -0
- data/spec/fixtures/vcr_cassettes/global_report.yml +17800 -0
- data/spec/fixtures/vcr_cassettes/load_global_report.yml +625 -0
- data/spec/fixtures/vcr_cassettes/login.yml +50 -0
- data/spec/fixtures/vcr_cassettes/logout.yml +50 -0
- data/spec/fixtures/vcr_cassettes/scan.yml +73 -0
- data/spec/fixtures/vcr_cassettes/scans.yml +89 -0
- data/spec/fixtures/vcr_cassettes/templates.yml +121 -0
- data/spec/fixtures/vcr_cassettes/try_load_not_existing_report.yml +63 -0
- data/spec/fixtures/vcr_cassettes/unlogged.yml +45 -0
- data/spec/fixtures/vcr_cassettes/wrong.yml +101 -0
- data/spec/qualys/api_spec.rb +27 -0
- data/spec/qualys/report_spec.rb +65 -0
- data/spec/qualys/scans_spec.rb +75 -0
- data/spec/qualys/version_spec.rb +11 -0
- data/spec/qualys/vulnerability_spec.rb +53 -0
- data/spec/qualys_spec.rb +20 -0
- data/spec/spec_helper.rb +37 -0
- metadata +61 -15
- data/.rock.yml +0 -17
- data/lib/qualys/reports.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d239fdef1e63e56d32021e4a56638200fcb71fb
|
4
|
+
data.tar.gz: 8943a665c47520cb349caf0c3d92d2931abf41fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d646857008c5095b373aa90216ffc03ef5ba1459e3e0ef65cdf12834a2b3aced1dccc08d6d12b14e8181572dcbb5c305434c316ad18004ac876b11d37fa5cca3
|
7
|
+
data.tar.gz: 9364b0a37083e4da14da213a5e3de308bbc0e2c20059e327db5bbafcd478a370d1e381ba1d1b349a0fe85075d4722dfa269cd7f6a758e18766e4dcac562e5cec
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2017-12-06 13:40:31 +0100 using RuboCop version 0.51.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 2
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Max: 21
|
12
|
+
|
13
|
+
# Offense count: 13
|
14
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
15
|
+
# URISchemes: http, https
|
16
|
+
Metrics/LineLength:
|
17
|
+
Max: 126
|
18
|
+
|
19
|
+
# Offense count: 2
|
20
|
+
# Configuration parameters: CountComments.
|
21
|
+
Metrics/MethodLength:
|
22
|
+
Max: 12
|
23
|
+
|
24
|
+
# Offense count: 10
|
25
|
+
Style/Documentation:
|
26
|
+
Exclude:
|
27
|
+
- 'spec/**/*'
|
28
|
+
- 'test/**/*'
|
29
|
+
- 'lib/qualys.rb'
|
30
|
+
- 'lib/qualys/api.rb'
|
31
|
+
- 'lib/qualys/auth.rb'
|
32
|
+
- 'lib/qualys/compliance.rb'
|
33
|
+
- 'lib/qualys/config.rb'
|
34
|
+
- 'lib/qualys/report.rb'
|
35
|
+
- 'lib/qualys/scans.rb'
|
36
|
+
|
37
|
+
# Offense count: 13
|
38
|
+
# Cop supports --auto-correct.
|
39
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
40
|
+
# SupportedStyles: when_needed, always, never
|
41
|
+
Style/FrozenStringLiteralComment:
|
42
|
+
Exclude:
|
43
|
+
- 'Gemfile'
|
44
|
+
- 'Rakefile'
|
45
|
+
- 'lib/qualys.rb'
|
46
|
+
- 'lib/qualys/api.rb'
|
47
|
+
- 'lib/qualys/auth.rb'
|
48
|
+
- 'lib/qualys/compliance.rb'
|
49
|
+
- 'lib/qualys/config.rb'
|
50
|
+
- 'lib/qualys/reports.rb'
|
51
|
+
- 'lib/qualys/scans.rb'
|
52
|
+
- 'lib/qualys/version.rb'
|
53
|
+
- 'qualys.gemspec'
|
54
|
+
- 'spec/qualys_spec.rb'
|
55
|
+
- 'spec/spec_helper.rb'
|
56
|
+
|
57
|
+
# Offense count: 4
|
58
|
+
# Configuration parameters: MinBodyLength.
|
59
|
+
Style/GuardClause:
|
60
|
+
Exclude:
|
61
|
+
- 'lib/qualys/api.rb'
|
62
|
+
- 'lib/qualys/config.rb'
|
63
|
+
- 'lib/qualys/reports.rb'
|
64
|
+
|
65
|
+
# Offense count: 2
|
66
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
67
|
+
# SupportedStyles: module_function, extend_self
|
68
|
+
Style/ModuleFunction:
|
69
|
+
Exclude:
|
70
|
+
- 'lib/qualys.rb'
|
71
|
+
- 'lib/qualys/config.rb'
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
qualys (0.1.5)
|
5
|
+
erubis
|
6
|
+
httparty (~> 0.15)
|
7
|
+
json
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.5.2)
|
13
|
+
public_suffix (>= 2.0.2, < 4.0)
|
14
|
+
ast (2.3.0)
|
15
|
+
coveralls (0.8.21)
|
16
|
+
json (>= 1.8, < 3)
|
17
|
+
simplecov (~> 0.14.1)
|
18
|
+
term-ansicolor (~> 1.3)
|
19
|
+
thor (~> 0.19.4)
|
20
|
+
tins (~> 1.6)
|
21
|
+
crack (0.4.3)
|
22
|
+
safe_yaml (~> 1.0.0)
|
23
|
+
diff-lcs (1.3)
|
24
|
+
docile (1.1.5)
|
25
|
+
erubis (2.7.0)
|
26
|
+
hashdiff (0.3.7)
|
27
|
+
httparty (0.15.6)
|
28
|
+
multi_xml (>= 0.5.2)
|
29
|
+
json (2.1.0)
|
30
|
+
multi_xml (0.6.0)
|
31
|
+
parallel (1.12.0)
|
32
|
+
parser (2.4.0.2)
|
33
|
+
ast (~> 2.3)
|
34
|
+
powerpack (0.1.1)
|
35
|
+
public_suffix (3.0.1)
|
36
|
+
rainbow (2.2.2)
|
37
|
+
rake
|
38
|
+
rake (12.3.0)
|
39
|
+
rspec (3.7.0)
|
40
|
+
rspec-core (~> 3.7.0)
|
41
|
+
rspec-expectations (~> 3.7.0)
|
42
|
+
rspec-mocks (~> 3.7.0)
|
43
|
+
rspec-core (3.7.0)
|
44
|
+
rspec-support (~> 3.7.0)
|
45
|
+
rspec-expectations (3.7.0)
|
46
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
47
|
+
rspec-support (~> 3.7.0)
|
48
|
+
rspec-mocks (3.7.0)
|
49
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
50
|
+
rspec-support (~> 3.7.0)
|
51
|
+
rspec-support (3.7.0)
|
52
|
+
rubocop (0.51.0)
|
53
|
+
parallel (~> 1.10)
|
54
|
+
parser (>= 2.3.3.1, < 3.0)
|
55
|
+
powerpack (~> 0.1)
|
56
|
+
rainbow (>= 2.2.2, < 3.0)
|
57
|
+
ruby-progressbar (~> 1.7)
|
58
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
59
|
+
ruby-progressbar (1.9.0)
|
60
|
+
safe_yaml (1.0.4)
|
61
|
+
simplecov (0.14.1)
|
62
|
+
docile (~> 1.1.0)
|
63
|
+
json (>= 1.8, < 3)
|
64
|
+
simplecov-html (~> 0.10.0)
|
65
|
+
simplecov-html (0.10.2)
|
66
|
+
term-ansicolor (1.6.0)
|
67
|
+
tins (~> 1.0)
|
68
|
+
thor (0.19.4)
|
69
|
+
tins (1.16.1)
|
70
|
+
unicode-display_width (1.3.0)
|
71
|
+
vcr (4.0.0)
|
72
|
+
webmock (3.1.1)
|
73
|
+
addressable (>= 2.3.6)
|
74
|
+
crack (>= 0.3.2)
|
75
|
+
hashdiff
|
76
|
+
|
77
|
+
PLATFORMS
|
78
|
+
ruby
|
79
|
+
|
80
|
+
DEPENDENCIES
|
81
|
+
bundler
|
82
|
+
coveralls
|
83
|
+
qualys!
|
84
|
+
rake
|
85
|
+
rspec
|
86
|
+
rubocop
|
87
|
+
vcr
|
88
|
+
webmock
|
89
|
+
|
90
|
+
BUNDLED WITH
|
91
|
+
1.16.0
|
data/README.md
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
[](https://travis-ci.org/Cyberwatch/ruby-qualys)
|
2
|
+
[](https://coveralls.io/github/Cyberwatch/ruby-qualys?branch=master)
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
[](https://gemnasium.com/mikemackintosh/ruby-qualys)
|
4
|
+
# Ruby Qualys API v2
|
7
5
|
|
8
|
-
|
6
|
+
A Ruby extension for interfacing with Qualys v2 API.
|
9
7
|
|
10
8
|
### Introduction
|
11
9
|
|
@@ -13,11 +11,13 @@ I had the need to pull stats and details from Qualys automatically to collect an
|
|
13
11
|
|
14
12
|
## Installation
|
15
13
|
|
16
|
-
|
14
|
+
Add this line to your application's Gemfile:
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
gem 'ruby-qualys', git: 'https://github.com/Cyberwatch/ruby-qualys.git'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
21
|
|
22
22
|
## Usage
|
23
23
|
|
@@ -72,7 +72,47 @@ If your URL differs from the default, set it using:
|
|
72
72
|
```ruby
|
73
73
|
Qualys::Api.base_uri = OTHER_PRODUCTION_ENDPOINT
|
74
74
|
```
|
75
|
+
### Getting vulnerabilities
|
76
|
+
|
77
|
+
You can load all vulnerability detected by qualys so far for the logged user
|
78
|
+
Here an example printing some information on the vulnerabilities for two hosts :
|
75
79
|
|
80
|
+
```ruby
|
81
|
+
Qualys::Reports.global_report.hosts.each{ |host|
|
82
|
+
p "ip:#{ host.ip }"
|
83
|
+
p "vulns : (#{ host.vulnerabilities.count })"
|
84
|
+
host.vulnerabilities.each{ |vuln|
|
85
|
+
p vuln.to_s
|
86
|
+
}
|
87
|
+
}
|
88
|
+
```
|
89
|
+
|
90
|
+
Output :
|
91
|
+
```
|
92
|
+
"ip:12.34.156.89"
|
93
|
+
"vulns : (16)"
|
94
|
+
"qid_38173, SSL Certificate - Signature Verification Failed Vulnerability, severity : 2, cves: no cve"
|
95
|
+
"qid_38685, SSL Certificate - Invalid Maximum Validity Date Detected, severity : 2, cves: no cve"
|
96
|
+
"qid_38169, SSL Certificate - Self-Signed Certificate, severity : 2, cves: no cve"
|
97
|
+
"qid_38170, SSL Certificate - Subject Common Name Does Not Match Server FQDN, severity : 2, cves: no cve"
|
98
|
+
"qid_38628, SSL/TLS Server supports TLSv1.0, severity : 3, cves: no cve"
|
99
|
+
"qid_38601, SSL/TLS use of weak RC4 cipher, severity : 3, cves: CVE-2013-2566, CVE-2015-2808"
|
100
|
+
"qid_38140, SSL Server Supports Weak Encryption Vulnerability, severity : 3, cves: no cve"
|
101
|
+
"qid_38142, SSL Server Allows Anonymous Authentication Vulnerability, severity : 4, cves: no cve"
|
102
|
+
"qid_38657, Birthday attacks against TLS ciphers with 64bit block size vulnerability (Sweet32), severity : 3, cves: CVE-2016-2183"
|
103
|
+
"qid_38606, SSL Server Has SSLv3 Enabled Vulnerability, severity : 3, cves: no cve"
|
104
|
+
"qid_82003, ICMP Timestamp Request, severity : 1, cves: CVE-1999-0524"
|
105
|
+
"qid_38603, SSLv3 Padding Oracle Attack Information Disclosure Vulnerability (POODLE), severity : 3, cves: CVE-2014-3566"
|
106
|
+
"qid_11827, HTTP Security Header Not Detected, severity : 2, cves: no cve"
|
107
|
+
"qid_11827, HTTP Security Header Not Detected, severity : 2, cves: no cve"
|
108
|
+
"qid_38628, SSL/TLS Server supports TLSv1.0, severity : 3, cves: no cve"
|
109
|
+
"qid_38657, Birthday attacks against TLS ciphers with 64bit block size vulnerability (Sweet32), severity : 3, cves: CVE-2016-2183"
|
110
|
+
"ip:10.34.156.89"
|
111
|
+
"vulns : (3)"
|
112
|
+
"qid_11827, HTTP Security Header Not Detected, severity : 2, cves: no cve"
|
113
|
+
"qid_11827, HTTP Security Header Not Detected, severity : 2, cves: no cve"
|
114
|
+
"qid_38628, SSL/TLS Server supports TLSv1.0, severity : 3, cves: no cve"
|
115
|
+
```
|
76
116
|
|
77
117
|
## References
|
78
118
|
|
data/Rakefile
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
|
-
require "bundler/gem_tasks"
|
1
|
+
require 'bundler/gem_tasks'
|
3
2
|
require 'rspec/core/rake_task'
|
4
3
|
require 'rubocop/rake_task'
|
5
4
|
|
6
|
-
task :
|
5
|
+
task default: :test
|
7
6
|
|
8
7
|
RSpec::Core::RakeTask.new do |spec|
|
9
8
|
spec.verbose = false
|
@@ -24,4 +23,4 @@ RuboCop::RakeTask.new(:rubocop) do |task|
|
|
24
23
|
task.formatters = ['progress']
|
25
24
|
# don't abort rake on failure
|
26
25
|
task.fail_on_error = false
|
27
|
-
end
|
26
|
+
end
|
data/lib/qualys.rb
CHANGED
@@ -10,23 +10,22 @@ require 'qualys/auth'
|
|
10
10
|
|
11
11
|
require 'qualys/scans'
|
12
12
|
require 'qualys/compliance'
|
13
|
-
require 'qualys/
|
13
|
+
require 'qualys/report'
|
14
14
|
|
15
|
+
require 'qualys/host'
|
16
|
+
require 'qualys/vulnerability'
|
15
17
|
|
16
18
|
module Qualys
|
17
|
-
|
18
19
|
extend self
|
19
20
|
|
20
21
|
def configure
|
21
22
|
block_given? ? yield(Config) : Config
|
22
|
-
%w
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
23
|
+
%w[username password].each do |key|
|
24
|
+
next unless Qualys::Config.instance_variable_get("@#{key}").nil?
|
25
|
+
raise Qualys::Config::RequiredOptionMissing,
|
26
|
+
"Configuration parameter missing: '#{key}'. " \
|
27
|
+
'Please add it to the Qualys.configure block'
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
31
|
-
|
32
|
-
end
|
30
|
+
alias config configure
|
31
|
+
end
|
data/lib/qualys/api.rb
CHANGED
@@ -1,71 +1,62 @@
|
|
1
1
|
module Qualys
|
2
2
|
class Api
|
3
|
-
|
4
3
|
class InvalidResponse < RuntimeError; end
|
5
4
|
class AuthorizationRequired < RuntimeError; end
|
6
5
|
class Exception < RuntimeError; end
|
7
6
|
|
8
7
|
# Set the current production endpoint
|
9
|
-
PRODUCTION_ENDPOINT = 'https://qualysapi.qualys.com/api/2.0/fo/'
|
8
|
+
PRODUCTION_ENDPOINT = 'https://qualysapi.qualys.com/api/2.0/fo/'.freeze
|
10
9
|
|
11
10
|
# Set HTTParty defaults
|
12
11
|
HTTParty::Basement.default_options.update(base_uri: PRODUCTION_ENDPOINT)
|
13
12
|
HTTParty::Basement.default_options.update(headers: {
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
#
|
18
|
-
#
|
19
|
-
def self.api_get(url, options={})
|
13
|
+
'X-Requested-With' => "Qualys Ruby Client v#{Qualys::VERSION}"
|
14
|
+
})
|
20
15
|
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
class << self
|
17
|
+
def api_get(url, options = {})
|
18
|
+
HTTParty::Basement.default_cookies.add_cookies(Qualys::Config.session_key) unless Qualys::Config.session_key.nil?
|
24
19
|
|
25
|
-
|
26
|
-
|
20
|
+
# Send Request
|
21
|
+
response = HTTParty.get(url, options)
|
27
22
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
raise Qualys::Api::Exception, response.parsed_response['SIMPLE_RETURN']['RESPONSE']['TEXT']
|
33
|
-
elsif !response.code.eql?(200)
|
34
|
-
raise Qualys::Api::InvalidResponse, "Invalid Response Received"
|
23
|
+
# Check if you need to be authorized
|
24
|
+
check_response(response)
|
25
|
+
# return the response
|
26
|
+
response
|
35
27
|
end
|
36
28
|
|
37
|
-
#
|
38
|
-
|
39
|
-
|
29
|
+
#
|
30
|
+
#
|
31
|
+
def api_post(url, options = {})
|
32
|
+
HTTParty::Basement.default_cookies.add_cookies(Qualys::Config.session_key) unless Qualys::Config.session_key.nil?
|
40
33
|
|
41
|
-
|
42
|
-
|
43
|
-
def self.api_post(url, options={})
|
44
|
-
|
45
|
-
unless Qualys::Config.session_key.nil?
|
46
|
-
HTTParty::Basement.default_cookies.add_cookies(Qualys::Config.session_key)
|
47
|
-
end
|
34
|
+
# Send Request
|
35
|
+
response = HTTParty.post(url, options)
|
48
36
|
|
49
|
-
|
50
|
-
|
37
|
+
# Check if you need to be authorized
|
38
|
+
check_response(response)
|
39
|
+
# return the response
|
40
|
+
response
|
41
|
+
end
|
51
42
|
|
52
|
-
#
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
raise Qualys::Api::Exception, response.parsed_response['SIMPLE_RETURN']['RESPONSE']['TEXT']
|
57
|
-
elsif response.code.eql?(500)
|
58
|
-
raise Qualys::Api::InvalidResponse, "Invalid Response Received"
|
43
|
+
#
|
44
|
+
# Sets the base URI.
|
45
|
+
def base_uri=(base_uri)
|
46
|
+
HTTParty::Basement.default_options.update(base_uri: base_uri)
|
59
47
|
end
|
60
48
|
|
61
|
-
|
62
|
-
response
|
63
|
-
end
|
49
|
+
private
|
64
50
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
51
|
+
def check_response(response)
|
52
|
+
code = response.code
|
53
|
+
raise(Qualys::Api::AuthorizationRequired, 'Please Login Before Communicating With The API') if code.eql?(401)
|
54
|
+
raise(Qualys::Api::Exception, response.parsed_response['SIMPLE_RETURN']['RESPONSE']['TEXT']) if code.eql?(403)
|
55
|
+
unless code.eql?(200)
|
56
|
+
raise(Qualys::Api::InvalidResponse, 'Invalid Response Received' + response.code.to_s + ' ' +
|
57
|
+
response.request.last_uri.to_s)
|
58
|
+
end
|
59
|
+
end
|
69
60
|
end
|
70
61
|
end
|
71
|
-
end
|
62
|
+
end
|