fluent-plugin-jfrog-siem 0.1.7 → 2.0.0
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/.rspec +1 -0
- data/CHANGELOG.md +36 -0
- data/Gemfile.lock +90 -0
- data/README.md +10 -3
- data/Rakefile +1 -1
- data/fluent-plugin-jfrog-siem.gemspec +8 -3
- data/lib/fluent/plugin/in_jfrog_siem.rb +41 -215
- data/lib/fluent/plugin/position_file.rb +32 -0
- data/lib/fluent/plugin/violations.json +380 -0
- data/lib/fluent/plugin/xray.rb +164 -0
- data/spec/position_file_spec.rb +56 -0
- data/spec/spec_helper.rb +111 -0
- data/spec/xray_spec.rb +135 -0
- data/test/helper.rb +1 -0
- data/test/plugin/test_in_jfrog_siem.rb +31 -5
- metadata +76 -10
- data/elastic.conf +0 -18
- data/splunk.conf +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e34dd9d1fb60e95b931f7c67bb508e635057b9e2f349f681eb2b54cb182c2396
|
4
|
+
data.tar.gz: b0acda337195accb81ce6bf3ee7bf05ef7e79630793dbc7553c0df5e541e26a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9116c506cf562af1566e6001748f5464752b2c07aace2d9f6fe04573c5a97db4cbf0e638d048dea536387559a71fa493fad882dc55650f1597c4030ab13be962
|
7
|
+
data.tar.gz: 2aaeaa3f4a22753db0b97c35b93938c4049cb9037f56f3cc6199dc222034a9d26609e1906973c0b9f11960f856227b2cf93ab000e8bd677aee9045df0bd684b0
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# JFrog Fluentd SIEM Input Plugin Changelog
|
2
|
+
All changes to the SIEM plugin will be documented in this file.
|
3
|
+
|
4
|
+
## [1.0.0] - May 18, 2020
|
5
|
+
* [BREAKING] Using JFrog API Key for authentication
|
6
|
+
|
7
|
+
## [0.1.9] - May 17, 2021
|
8
|
+
* Handling the case where violations are left in a batch to be processed
|
9
|
+
|
10
|
+
## [0.1.8] - May 10, 2021
|
11
|
+
* Fixing persist, not persist item conditions
|
12
|
+
|
13
|
+
## [0.1.7] - April 21, 2021
|
14
|
+
* Adding policies and rules to payload
|
15
|
+
|
16
|
+
## [0.1.6] - April 13, 2021
|
17
|
+
* Adding additonal parameters to match with access logs for correlation
|
18
|
+
|
19
|
+
## [0.1.5] - March 29, 2021
|
20
|
+
* Normalizing the format of Impacted Artifact, fixing properties not found case
|
21
|
+
|
22
|
+
## [0.1.4] - February 02, 2021
|
23
|
+
* Adding dependencies, gemspec updates
|
24
|
+
|
25
|
+
## [0.1.3] - January 21, 2021
|
26
|
+
* Fixing thread pool issues (moving loop inside a thread pool)
|
27
|
+
|
28
|
+
## [0.1.2] - November 17, 2020
|
29
|
+
* Changes to better README
|
30
|
+
|
31
|
+
## [0.1.1] - November 17, 2020
|
32
|
+
* Adding dependencies to gemspec
|
33
|
+
|
34
|
+
## [0.1.0] - October 05, 2020
|
35
|
+
* Initial release of Jfrog Logs Analytic integration
|
36
|
+
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
fluent-plugin-jfrog-siem (1.0.0)
|
5
|
+
concurrent-ruby (~> 1.1.8)
|
6
|
+
concurrent-ruby-edge
|
7
|
+
fluentd (>= 0.14.10, < 2)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
concurrent-ruby (1.1.8)
|
13
|
+
concurrent-ruby-edge (0.6.0)
|
14
|
+
concurrent-ruby (~> 1.1.6)
|
15
|
+
cool.io (1.7.1)
|
16
|
+
diff-lcs (1.4.4)
|
17
|
+
domain_name (0.5.20190701)
|
18
|
+
unf (>= 0.0.5, < 1.0.0)
|
19
|
+
fluentd (1.13.1)
|
20
|
+
bundler
|
21
|
+
cool.io (>= 1.4.5, < 2.0.0)
|
22
|
+
http_parser.rb (>= 0.5.1, < 0.7.0)
|
23
|
+
msgpack (>= 1.3.1, < 2.0.0)
|
24
|
+
serverengine (>= 2.2.2, < 3.0.0)
|
25
|
+
sigdump (~> 0.2.2)
|
26
|
+
strptime (>= 0.2.2, < 1.0.0)
|
27
|
+
tzinfo (>= 1.0, < 3.0)
|
28
|
+
tzinfo-data (~> 1.0)
|
29
|
+
webrick (>= 1.4.2, < 1.8.0)
|
30
|
+
yajl-ruby (~> 1.0)
|
31
|
+
http-accept (1.7.0)
|
32
|
+
http-cookie (1.0.3)
|
33
|
+
domain_name (~> 0.5)
|
34
|
+
http_parser.rb (0.6.0)
|
35
|
+
mime-types (3.3.1)
|
36
|
+
mime-types-data (~> 3.2015)
|
37
|
+
mime-types-data (3.2021.0225)
|
38
|
+
msgpack (1.4.2)
|
39
|
+
netrc (0.11.0)
|
40
|
+
power_assert (2.0.0)
|
41
|
+
rake (12.3.3)
|
42
|
+
rest-client (2.1.0)
|
43
|
+
http-accept (>= 1.7.0, < 2.0)
|
44
|
+
http-cookie (>= 1.0.2, < 2.0)
|
45
|
+
mime-types (>= 1.16, < 4.0)
|
46
|
+
netrc (~> 0.8)
|
47
|
+
rspec (3.10.0)
|
48
|
+
rspec-core (~> 3.10.0)
|
49
|
+
rspec-expectations (~> 3.10.0)
|
50
|
+
rspec-mocks (~> 3.10.0)
|
51
|
+
rspec-core (3.10.1)
|
52
|
+
rspec-support (~> 3.10.0)
|
53
|
+
rspec-expectations (3.10.1)
|
54
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
55
|
+
rspec-support (~> 3.10.0)
|
56
|
+
rspec-mocks (3.10.2)
|
57
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
58
|
+
rspec-support (~> 3.10.0)
|
59
|
+
rspec-support (3.10.2)
|
60
|
+
serverengine (2.2.4)
|
61
|
+
sigdump (~> 0.2.2)
|
62
|
+
sigdump (0.2.4)
|
63
|
+
strptime (0.2.5)
|
64
|
+
test-unit (3.4.2)
|
65
|
+
power_assert
|
66
|
+
tzinfo (2.0.4)
|
67
|
+
concurrent-ruby (~> 1.0)
|
68
|
+
tzinfo-data (1.2021.1)
|
69
|
+
tzinfo (>= 1.0.0)
|
70
|
+
unf (0.1.4)
|
71
|
+
unf_ext
|
72
|
+
unf_ext (0.0.7.7)
|
73
|
+
webrick (1.7.0)
|
74
|
+
yajl-ruby (1.4.1)
|
75
|
+
|
76
|
+
PLATFORMS
|
77
|
+
x86_64-darwin-20
|
78
|
+
|
79
|
+
DEPENDENCIES
|
80
|
+
bundler (~> 2.0)
|
81
|
+
concurrent-ruby (~> 1.1.8)
|
82
|
+
concurrent-ruby-edge
|
83
|
+
fluent-plugin-jfrog-siem!
|
84
|
+
rake (~> 12.0)
|
85
|
+
rest-client (~> 2.0)
|
86
|
+
rspec (~> 3.10.0)
|
87
|
+
test-unit (~> 3.0)
|
88
|
+
|
89
|
+
BUNDLED WITH
|
90
|
+
2.2.3
|
data/README.md
CHANGED
@@ -68,20 +68,27 @@ Splunk:
|
|
68
68
|
|
69
69
|
Splunk setup can be found at [README.](https://github.com/jfrog/log-analytics-splunk/blob/master/README.md)
|
70
70
|
````text
|
71
|
-
wget https://raw.githubusercontent.com/jfrog/log-analytics/master/
|
71
|
+
wget https://raw.githubusercontent.com/jfrog/log-analytics-splunk/master/siem/splunk_siem.conf
|
72
72
|
````
|
73
73
|
Elasticsearch:
|
74
74
|
|
75
75
|
Elasticsearch Kibana setup can be found at [README.](https://github.com/jfrog/log-analytics-elastic/blob/master/README.md)
|
76
76
|
````text
|
77
|
-
wget https://raw.githubusercontent.com/jfrog/log-analytics/master/
|
77
|
+
wget https://raw.githubusercontent.com/jfrog/log-analytics-elastic/master/siem/elastic_siem.conf
|
78
|
+
````
|
79
|
+
Datadog:
|
80
|
+
|
81
|
+
Datadog setup can be found at [README.](https://github.com/jfrog/log-analytics-datadog/blob/master/README.md)
|
82
|
+
````text
|
83
|
+
wget https://raw.githubusercontent.com/jfrog/log-analytics-datadog/master/siem/datadog_siem.conf
|
78
84
|
````
|
79
85
|
|
80
86
|
#### Configuration parameters
|
81
87
|
Integration is done by setting up Xray. Obtain JPD url and access token for API. Configure the source directive parameters specified below
|
82
88
|
* **tag** (string) (required): The value is the tag assigned to the generated events.
|
83
89
|
* **jpd_url** (string) (required): JPD url required to pull Xray SIEM violations
|
84
|
-
* **
|
90
|
+
* **apikey** (string) (required): API Key is the [Artifactory API Key](https://www.jfrog.com/confluence/display/JFROG/User+Profile#UserProfile-APIKey) for authentication
|
91
|
+
* **username** (string) (required): USER is the Artifactory username for authentication
|
85
92
|
* **pos_file** (string) (required): Position file to record last SIEM violation pulled
|
86
93
|
* **batch_size** (integer) (optional): Batch size for processing violations
|
87
94
|
* Default value: `25`
|
data/Rakefile
CHANGED
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |spec|
|
5
5
|
spec.name = "fluent-plugin-jfrog-siem"
|
6
|
-
spec.version = "0.
|
6
|
+
spec.version = "2.0.0"
|
7
7
|
spec.authors = ["John Peterson", "Mahitha Byreddy"]
|
8
8
|
spec.email = ["johnp@jfrog.com", "mahithab@jfrog.com"]
|
9
9
|
|
@@ -24,7 +24,12 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "rake", "~> 12.0"
|
25
25
|
spec.add_development_dependency "test-unit", "~> 3.0"
|
26
26
|
spec.add_development_dependency "rest-client", "~> 2.0"
|
27
|
-
spec.add_development_dependency "
|
28
|
-
spec.
|
27
|
+
spec.add_development_dependency "concurrent-ruby", "~> 1.1.8"
|
28
|
+
spec.add_development_dependency "concurrent-ruby-edge", '>= 0'
|
29
|
+
spec.add_development_dependency 'rspec', '~> 3.10.0'
|
30
|
+
|
31
|
+
spec.add_runtime_dependency "rest-client", "~> 2.0"
|
32
|
+
spec.add_runtime_dependency "concurrent-ruby", "~> 1.1.8"
|
33
|
+
spec.add_runtime_dependency "concurrent-ruby-edge", '>= 0'
|
29
34
|
spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
|
30
35
|
end
|
@@ -14,10 +14,10 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
require "fluent/plugin/input"
|
16
16
|
require "rest-client"
|
17
|
-
require "thread/pool"
|
18
|
-
require "json"
|
19
17
|
require "date"
|
20
18
|
require "uri"
|
19
|
+
require "fluent/plugin/xray"
|
20
|
+
require "fluent/plugin/position_file"
|
21
21
|
|
22
22
|
module Fluent
|
23
23
|
module Plugin
|
@@ -30,12 +30,12 @@ module Fluent
|
|
30
30
|
# `:default` means that the parameter is optional.
|
31
31
|
config_param :tag, :string, default: ""
|
32
32
|
config_param :jpd_url, :string, default: ""
|
33
|
-
config_param :
|
34
|
-
config_param :
|
33
|
+
config_param :username, :string, default: ""
|
34
|
+
config_param :apikey, :string, default: ""
|
35
35
|
config_param :batch_size, :integer, default: 25
|
36
|
-
config_param :thread_count, :integer, default: 5
|
37
36
|
config_param :wait_interval, :integer, default: 60
|
38
|
-
|
37
|
+
config_param :from_date, :string, default: ""
|
38
|
+
config_param :pos_file_path, :string, default: ""
|
39
39
|
|
40
40
|
# `configure` is called before `start`.
|
41
41
|
# 'conf' is a `Hash` that includes the configuration parameters.
|
@@ -50,26 +50,22 @@ module Fluent
|
|
50
50
|
raise Fluent::ConfigError, "Must define the JPD URL to pull Xray SIEM violations."
|
51
51
|
end
|
52
52
|
|
53
|
-
if @
|
54
|
-
raise Fluent::ConfigError, "Must define the
|
55
|
-
end
|
56
|
-
|
57
|
-
if @pos_file == ""
|
58
|
-
raise Fluent::ConfigError, "Must define a position file to record last SIEM violation pulled."
|
53
|
+
if @username == ""
|
54
|
+
raise Fluent::ConfigError, "Must define the username to use for authentication."
|
59
55
|
end
|
60
56
|
|
61
|
-
if @
|
62
|
-
raise Fluent::ConfigError, "Must define
|
63
|
-
end
|
64
|
-
|
65
|
-
if @thread_count > @batch_size
|
66
|
-
raise Fluent::ConfigError, "Violation detail url thread count exceeds batch size."
|
57
|
+
if @apikey == ""
|
58
|
+
raise Fluent::ConfigError, "Must define the API Key to use for authentication."
|
67
59
|
end
|
68
60
|
|
69
61
|
if @wait_interval < 1
|
70
62
|
raise Fluent::ConfigError, "Wait interval must be greater than 1 to wait between pulling new events."
|
71
63
|
end
|
72
64
|
|
65
|
+
if @from_date == ""
|
66
|
+
puts "From date not specified, so getting violations from current date if pos_file doesn't exist"
|
67
|
+
end
|
68
|
+
|
73
69
|
end
|
74
70
|
|
75
71
|
|
@@ -89,223 +85,53 @@ module Fluent
|
|
89
85
|
|
90
86
|
|
91
87
|
def run
|
92
|
-
call_home(@jpd_url
|
93
|
-
# runs the violation pull
|
94
|
-
last_created_date_string = get_last_item_create_date()
|
95
|
-
begin
|
96
|
-
last_created_date = DateTime.parse(last_created_date_string).strftime("%Y-%m-%dT%H:%M:%SZ")
|
97
|
-
rescue
|
98
|
-
last_created_date = DateTime.parse("1970-01-01T00:00:00Z").strftime("%Y-%m-%dT%H:%M:%SZ")
|
99
|
-
end
|
100
|
-
offset_count=1
|
101
|
-
left_violations=0
|
102
|
-
waiting_for_violations = false
|
103
|
-
xray_json={"filters": { "created_from": last_created_date }, "pagination": {"order_by": "created","limit": @batch_size ,"offset": offset_count } }
|
104
|
-
|
105
|
-
while true
|
106
|
-
# Grab the batch of records
|
107
|
-
resp=get_xray_violations(xray_json, @jpd_url, @access_token)
|
108
|
-
number_of_violations = JSON.parse(resp)['total_violations']
|
109
|
-
if left_violations <= 0
|
110
|
-
left_violations = number_of_violations
|
111
|
-
end
|
112
|
-
|
113
|
-
xray_violation_urls_list = []
|
114
|
-
for index in 0..JSON.parse(resp)['violations'].length-1 do
|
115
|
-
# Get the violation
|
116
|
-
item = JSON.parse(resp)['violations'][index]
|
117
|
-
|
118
|
-
# Get the created date and check if we should skip (already processed) or process this record.
|
119
|
-
created_date_string = item['created']
|
120
|
-
created_date = DateTime.parse(created_date_string).strftime("%Y-%m-%dT%H:%M:%SZ")
|
88
|
+
# call_home(@jpd_url)
|
121
89
|
|
122
|
-
|
123
|
-
persistItem = true
|
124
|
-
if waiting_for_violations
|
125
|
-
if created_date <= last_created_date
|
126
|
-
# "not persisting it - waiting for violations"
|
127
|
-
persistItem = false
|
128
|
-
end
|
129
|
-
else
|
130
|
-
if created_date < last_created_date
|
131
|
-
# "persisting everything"
|
132
|
-
persistItem = true
|
133
|
-
end
|
134
|
-
end
|
90
|
+
last_created_date = get_last_item_create_date()
|
135
91
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
now = Fluent::Engine.now
|
140
|
-
router.emit(@tag, now, item)
|
141
|
-
|
142
|
-
# write to the pos_file created_date_string
|
143
|
-
open(@pos_file, 'a') do |f|
|
144
|
-
f << "#{created_date_string}\n"
|
145
|
-
end
|
146
|
-
|
147
|
-
# Mark this as the last record successfully processed
|
148
|
-
last_created_date_string = created_date_string
|
149
|
-
last_created_date = created_date
|
150
|
-
|
151
|
-
# Grab violation detail url and add to url list to process w/ thread pool
|
152
|
-
xray_violation_details_url=item['violation_details_url']
|
153
|
-
xray_violation_urls_list.append(xray_violation_details_url)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
# iterate over url array adding to thread pool each url.
|
158
|
-
# limit max workers to thread count to prevent overloading xray.
|
159
|
-
thread_pool = Thread.pool(thread_count)
|
160
|
-
thread_pool.process {
|
161
|
-
for xray_violation_url in xray_violation_urls_list do
|
162
|
-
pull_violation_details(xray_violation_url, @access_token)
|
163
|
-
end
|
164
|
-
}
|
165
|
-
thread_pool.shutdown
|
166
|
-
|
167
|
-
# reduce left violations by jump size (not all batches have full item count??)
|
168
|
-
left_violations = left_violations - @batch_size
|
169
|
-
if left_violations <= 0
|
170
|
-
waiting_for_violations = true
|
171
|
-
sleep(@wait_interval)
|
172
|
-
else
|
173
|
-
# Grab the next record to process for the violation details url
|
174
|
-
waiting_for_violations = false
|
175
|
-
offset_count = offset_count + 1
|
176
|
-
xray_json={"filters": { "created_from": last_created_date_string }, "pagination": {"order_by": "created","limit": @batch_size , "offset": offset_count } }
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
|
182
|
-
# pull the last item create date from the pos_file return created_date_string
|
183
|
-
def get_last_item_create_date()
|
184
|
-
if(!(File.exist?(@pos_file)))
|
185
|
-
@pos_file = File.new(@pos_file, "w")
|
92
|
+
if (@from_date != "")
|
93
|
+
last_created_date = DateTime.parse(@from_date).strftime("%Y-%m-%dT%H:%M:%SZ")
|
186
94
|
end
|
187
|
-
|
95
|
+
date_since = last_created_date
|
96
|
+
puts "Getting queries from #{date_since}"
|
97
|
+
xray = Xray.new(@jpd_url, @username, @apikey, @wait_interval, @batch_size, @pos_file_path, router, @tag)
|
98
|
+
violations_channel = xray.violations(date_since)
|
99
|
+
xray.violation_details(violations_channel)
|
100
|
+
sleep 100
|
188
101
|
end
|
189
102
|
|
190
103
|
#call home functionality
|
191
|
-
def call_home(jpd_url
|
104
|
+
def call_home(jpd_url)
|
192
105
|
call_home_json = { "productId": "jfrogLogAnalytics/v0.5.1", "features": [ { "featureId": "Platform/Xray" }, { "featureId": "Channel/xrayeventsiem" } ] }
|
193
106
|
response = RestClient::Request.new(
|
194
107
|
:method => :post,
|
195
108
|
:url => jpd_url + "/artifactory/api/system/usage",
|
196
109
|
:payload => call_home_json.to_json,
|
197
|
-
:
|
198
|
-
|
199
|
-
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
# queries the xray API for violations based upon the input json
|
204
|
-
def get_xray_violations_detail(xray_violation_detail_url, access_token)
|
205
|
-
response = RestClient::Request.new(
|
206
|
-
:method => :get,
|
207
|
-
:url => xray_violation_detail_url,
|
208
|
-
headers: {Authorization:'Bearer ' + access_token}
|
209
|
-
).execute do |response, request, result|
|
210
|
-
case response.code
|
211
|
-
when 200
|
212
|
-
return response.to_str
|
213
|
-
else
|
214
|
-
raise Fluent::StandardError, "Cannot reach Artifactory URL to pull Xray SIEM violations."
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
|
220
|
-
# queries the xray API for violations based upon the input json
|
221
|
-
def get_xray_violations(xray_json, jpd_url, access_token)
|
222
|
-
response = RestClient::Request.new(
|
223
|
-
:method => :post,
|
224
|
-
:url => jpd_url + "/xray/api/v1/violations",
|
225
|
-
:payload => xray_json.to_json,
|
226
|
-
:headers => { :accept => :json, :content_type => :json, Authorization:'Bearer ' + access_token }
|
110
|
+
:user => @username,
|
111
|
+
:password => @apikey,
|
112
|
+
:headers => { :accept => :json, :content_type => :json}
|
227
113
|
).execute do |response, request, result|
|
228
|
-
|
229
|
-
when 200
|
230
|
-
return response.to_str
|
231
|
-
else
|
232
|
-
raise Fluent::StandardError, "Cannot reach Artifactory URL to pull Xray SIEM violations."
|
233
|
-
end
|
114
|
+
puts "Posting call home information"
|
234
115
|
end
|
235
116
|
end
|
236
117
|
|
237
|
-
#
|
238
|
-
def
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
impacted_artifact_url_list = []
|
246
|
-
if detailResp_json.key?('properties')
|
247
|
-
properties = detailResp_json['properties']
|
248
|
-
for index in 0..properties.length-1 do
|
249
|
-
if properties[index].key?('cve')
|
250
|
-
cve.push(properties[index]['cve'])
|
251
|
-
end
|
252
|
-
if properties[index].key?('cvss_v2')
|
253
|
-
cvss_v2_list.push(properties[index]['cvss_v2'])
|
254
|
-
end
|
255
|
-
if properties[index].key?('cvss_v3')
|
256
|
-
cvss_v3_list.push(properties[index]['cvss_v3'])
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
detailResp_json["cve"] = cve.sort.reverse[0]
|
261
|
-
cvss_v2 = cvss_v2_list.sort.reverse[0]
|
262
|
-
cvss_v3 = cvss_v3_list.sort.reverse[0]
|
263
|
-
if !cvss_v3.nil?
|
264
|
-
cvss = cvss_v3
|
265
|
-
elsif !cvss_v2.nil?
|
266
|
-
cvss = cvss_v2
|
267
|
-
end
|
268
|
-
cvss_score = cvss[0..2]
|
269
|
-
cvss_version = cvss.split(':')[1][0..2]
|
270
|
-
detailResp_json["cvss_score"] = cvss_score
|
271
|
-
detailResp_json["cvss_version"] = cvss_version
|
272
|
-
end
|
273
|
-
|
274
|
-
if detailResp_json.key?('matched_policies')
|
275
|
-
matched_policies = detailResp_json['matched_policies']
|
276
|
-
for index in 0..matched_policies.length-1 do
|
277
|
-
if matched_policies[index].key?('policy')
|
278
|
-
policy_list.push(matched_policies[index]['policy'])
|
279
|
-
end
|
280
|
-
if matched_policies[index].key?('rule')
|
281
|
-
rule_list.push(matched_policies[index]['rule'])
|
282
|
-
end
|
283
|
-
end
|
284
|
-
detailResp_json['policies'] = policy_list
|
285
|
-
detailResp_json['rules'] = rule_list
|
286
|
-
end
|
287
|
-
|
288
|
-
impacted_artifacts = detailResp_json['impacted_artifacts']
|
289
|
-
for impacted_artifact in impacted_artifacts do
|
290
|
-
matchdata = impacted_artifact.match /default\/(?<repo_name>[^\/]*)\/(?<path>.*)/
|
291
|
-
impacted_artifact_url = matchdata['repo_name'] + ":" + matchdata['path'] + " "
|
292
|
-
impacted_artifact_url_list.append(impacted_artifact_url)
|
118
|
+
# pull the last item create date from the pos_file return created_date_string
|
119
|
+
def get_last_item_create_date()
|
120
|
+
recent_pos_file = get_recent_pos_file()
|
121
|
+
if recent_pos_file != nil
|
122
|
+
last_created_date_string = IO.readlines(recent_pos_file).last
|
123
|
+
return DateTime.parse(last_created_date_string).strftime("%Y-%m-%dT%H:%M:%SZ")
|
124
|
+
else
|
125
|
+
return DateTime.now.strftime("%Y-%m-%dT%H:%M:%SZ")
|
293
126
|
end
|
294
|
-
detailResp_json['impacted_artifacts_url'] = impacted_artifact_url_list
|
295
|
-
return detailResp_json
|
296
127
|
end
|
297
128
|
|
298
|
-
def
|
299
|
-
|
300
|
-
|
301
|
-
time = Fluent::Engine.now
|
302
|
-
detailResp_json = data_normalization(detailResp)
|
303
|
-
router.emit(@tag, time, detailResp_json)
|
304
|
-
rescue
|
305
|
-
raise Fluent::StandardError, "Error pulling violation details url #{xray_violation_detail_url}"
|
306
|
-
end
|
129
|
+
def get_recent_pos_file()
|
130
|
+
pos_file = @pos_file_path + "*.siem.pos"
|
131
|
+
return Dir.glob(pos_file).sort.last
|
307
132
|
end
|
308
133
|
|
309
134
|
end
|
310
135
|
end
|
311
136
|
end
|
137
|
+
|