Class: Nexpose::VulnException

Inherits:
Object
  • Object
show all
Defined in:
lib/nexpose/vuln_exception.rb

Overview

A vulnerability exception.

Certain attributes are necessary for some exception scopes, even though they are optional otherwise.

  • An exception for all instances of a vulnerability on all assets only requires the vuln_id attribute. The asset_id, vuln_key and port attributes are ignored for this scope type.

  • An exception for all instances on a specific asset requires the vuln_id and asset_id attributes. The vuln_key and port attributes are ignored for this scope type.

  • An exception for a specific instance of a vulnerability on a specific asset requires the vuln_id, asset_id. Additionally, the port and/or the key attribute must be specified.

Defined Under Namespace

Modules: Reason, Scope, Status

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(vuln_id, scope, reason, status = nil) ⇒ VulnException

Returns a new instance of VulnException.



193
194
195
196
197
198
# File 'lib/nexpose/vuln_exception.rb', line 193

def initialize(vuln_id, scope, reason, status = nil)
  @vuln_id = vuln_id
  @scope   = scope
  @reason  = reason
  @status  = status
end

Instance Attribute Details

#asset_group_idObject

ID of the Asset Group, if this exception applies to all instances on an asset group



174
175
176
# File 'lib/nexpose/vuln_exception.rb', line 174

def asset_group_id
  @asset_group_id
end

#asset_idObject Also known as: device_id

ID of asset, if this exception applies to only one asset.



168
169
170
# File 'lib/nexpose/vuln_exception.rb', line 168

def asset_id
  @asset_id
end

#expirationObject

The date an exception will expire, causing the vulnerability to be included in report risk scores.



183
184
185
# File 'lib/nexpose/vuln_exception.rb', line 183

def expiration
  @expiration
end

#idObject

Unique identifier assigned to an exception.



151
152
153
# File 'lib/nexpose/vuln_exception.rb', line 151

def id
  @id
end

#portObject

Port on a asset, if this exception applies to a specific port.



176
177
178
# File 'lib/nexpose/vuln_exception.rb', line 176

def port
  @port
end

#reasonObject

The reason for the exception status.

See Also:



163
164
165
# File 'lib/nexpose/vuln_exception.rb', line 163

def reason
  @reason
end

#review_dateObject

Date when the Review occurred [Time]



189
190
191
# File 'lib/nexpose/vuln_exception.rb', line 189

def review_date
  @review_date
end

#reviewerObject

The name of the reviewer of the exception.



157
158
159
# File 'lib/nexpose/vuln_exception.rb', line 157

def reviewer
  @reviewer
end

#reviewer_commentObject

Any comment provided by the reviewer.



187
188
189
# File 'lib/nexpose/vuln_exception.rb', line 187

def reviewer_comment
  @reviewer_comment
end

#scopeObject

The scope of the exception.

See Also:



166
167
168
# File 'lib/nexpose/vuln_exception.rb', line 166

def scope
  @scope
end

#site_idObject

Id of the site, if this exception applies to all instances on a site



172
173
174
# File 'lib/nexpose/vuln_exception.rb', line 172

def site_id
  @site_id
end

#statusObject

The state of the exception in the work flow process.

See Also:



160
161
162
# File 'lib/nexpose/vuln_exception.rb', line 160

def status
  @status
end

#submit_dateObject

Date when Submit occurred [Time]



191
192
193
# File 'lib/nexpose/vuln_exception.rb', line 191

def submit_date
  @submit_date
end

#submitterObject

The name of submitter of the exception.



155
156
157
# File 'lib/nexpose/vuln_exception.rb', line 155

def submitter
  @submitter
end

#submitter_commentObject

Any comment provided by the submitter.



185
186
187
# File 'lib/nexpose/vuln_exception.rb', line 185

def submitter_comment
  @submitter_comment
end

#vuln_idObject

Unique identifier of a vulnerability.



153
154
155
# File 'lib/nexpose/vuln_exception.rb', line 153

def vuln_id
  @vuln_id
end

#vuln_keyObject

The specific vulnerable component in a discovered instance of the vulnerability referenced by the vuln_id, such as a program, file or user account.



180
181
182
# File 'lib/nexpose/vuln_exception.rb', line 180

def vuln_key
  @vuln_key
end

Class Method Details

.parse(xml) ⇒ Object



388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
# File 'lib/nexpose/vuln_exception.rb', line 388

def self.parse(xml)
  exception = new(xml.attributes['vuln-id'],
                  xml.attributes['scope'],
                  xml.attributes['reason'],
                  xml.attributes['status'])

  exception.id = xml.attributes['exception-id']
  exception.submitter = xml.attributes['submitter']
  exception.reviewer = xml.attributes['reviewer']
  exception.asset_id = xml.attributes['device-id']
  exception.port = xml.attributes['port-no']
  exception.vuln_key = xml.attributes['vuln-key']
  # TODO: Convert to Date/Time object?
  exception.expiration = xml.attributes['expiration-date']

  submitter_comment = xml.elements['submitter-comment']
  exception.submitter_comment = submitter_comment.text if submitter_comment
  reviewer_comment = xml.elements['reviewer-comment']
  exception.reviewer_comment = reviewer_comment.text if reviewer_comment

  exception
end

Instance Method Details

#approve(connection, comment = nil) ⇒ Boolean

Approve a vulnerability exception request, update comments and expiration dates on vulnerability exceptions that are “Under Review”.

Parameters:

  • connection (Connection)

    Connection to security console.

  • comment (String) (defaults to: nil)

    Comment to accompany the approval.

Returns:

  • (Boolean)

    Whether or not the approval was accepted by the console.



271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/nexpose/vuln_exception.rb', line 271

def approve(connection, comment = nil)
  xml = connection.make_xml('VulnerabilityExceptionApproveRequest',
                            { 'exception-id' => @id })
  if comment
    cxml = REXML::Element.new('comment')
    cxml.add_text(comment)
    xml.add_element(cxml)
    @reviewer_comment = comment
  end

  connection.execute(xml, '1.2').success
end

#delete(connection) ⇒ Boolean

Deletes this vulnerability exception.

Parameters:

  • connection (Connection)

    Connection to security console.

Returns:

  • (Boolean)

    Whether or not deletion was successful.



308
309
310
# File 'lib/nexpose/vuln_exception.rb', line 308

def delete(connection)
  connection.delete_vuln_exception(@id)
end

#recall(connection) ⇒ Boolean

Recall a vulnerability exception. Recall is used by a submitter to undo an exception request that has not been approved yet.

You can only recall a vulnerability exception that has ‘Under Review’ status.

Parameters:

  • connection (Connection)

    Connection to security console.

Returns:

  • (Boolean)

    Whether or not the recall was accepted by the console.



260
261
262
# File 'lib/nexpose/vuln_exception.rb', line 260

def recall(connection)
  connection.recall_vuln_exception(id)
end

#reject(connection, comment = nil) ⇒ Boolean

Reject a vulnerability exception request and update comments for the vulnerability exception request.

Parameters:

  • connection (Connection)

    Connection to security console.

  • comment (String) (defaults to: nil)

    Comment to accompany the rejection.

Returns:

  • (Boolean)

    Whether or not the reject was accepted by the console.



291
292
293
294
295
296
297
298
299
300
301
# File 'lib/nexpose/vuln_exception.rb', line 291

def reject(connection, comment = nil)
  xml = connection.make_xml('VulnerabilityExceptionRejectRequest',
                            { 'exception-id' => @id })
  if comment
    cxml = REXML::Element.new('comment')
    cxml.add_text(comment)
    xml.add_element(cxml)
  end

  connection.execute(xml, '1.2').success
end

#resubmit(connection) ⇒ Boolean

Resubmit a vulnerability exception request with a new comment and reason after an exception has been rejected.

You can only resubmit a request that has a “Rejected” status; if an exception is “Approved” or “Under Review” you will receive an error message stating that the exception request cannot be resubmitted.

This call will use the object’s current state to resubmit.

Parameters:

  • connection (Connection)

    Connection to security console.

Returns:

  • (Boolean)

    Whether or not the resubmission was valid.

Raises:

  • (ArgumentError)


246
247
248
249
# File 'lib/nexpose/vuln_exception.rb', line 246

def resubmit(connection)
  raise ArgumentError.new('Only Rejected exceptions can be resubmitted.') unless @status == Status::REJECTED
  connection.resubmit_vuln_exception(@id, @submitter_comment, @reason)
end

#save(connection, comment = nil) ⇒ Fixnum

Submit this exception on the security console.

Parameters:

  • connection (Connection)

    Connection to security console.

Returns:

  • (Fixnum)

    Newly assigned exception ID.



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/nexpose/vuln_exception.rb', line 205

def save(connection, comment = nil)
  validate

  xml = connection.make_xml('VulnerabilityExceptionCreateRequest')
  xml.add_attributes({ 'vuln-id' => @vuln_id,
                       'scope' => @scope,
                       'reason' => @reason })
  case @scope
  when Scope::ALL_INSTANCES_ON_A_SPECIFIC_ASSET
    xml.add_attributes({ 'device-id' => @asset_id })
  when Scope::SPECIFIC_INSTANCE_OF_SPECIFIC_ASSET
    xml.add_attributes({ 'device-id' => @asset_id,
                         'port-no' => @port,
                         'vuln-key' => @vuln_key })
  when Scope::ALL_INSTANCES_IN_A_SPECIFIC_SITE
    xml.add_attributes({ 'site-id ' => @site_id })
  end

  @submitter_comment = comment if comment
  if @submitter_comment
    comment_elem = REXML::Element.new('comment')
    comment_elem.add_text(@submitter_comment)
    xml.add_element(comment_elem)
  end

  response = connection.execute(xml, '1.2')
  @id = response.attributes['exception-id'].to_i if response.success
end

#update_expiration_date(connection, new_date) ⇒ Boolean

Update the expiration date for this exception. The expiration time cannot be in the past.

Parameters:

  • connection (Connection)

    Connection to security console.

  • new_date (String)

    Date in the format “YYYY-MM-DD”.

Returns:

  • (Boolean)

    Whether the update was successfully submitted.



358
359
360
361
362
363
# File 'lib/nexpose/vuln_exception.rb', line 358

def update_expiration_date(connection, new_date)
  xml = connection.make_xml('VulnerabilityExceptionUpdateExpirationDateRequest',
                            { 'exception-id' => @id,
                              'expiration-date' => new_date })
  connection.execute(xml, '1.2').success
end

#update_reviewer_comment(connection, comment) ⇒ Boolean

Update security console with reviewer comment on this vulnerability exceptions.

Parameters:

  • connection (Connection)

    Connection to security console.

  • comment (String)

    Reviewer comment on this exception.

Returns:

  • (Boolean)

    Whether the comment was successfully submitted.



340
341
342
343
344
345
346
347
348
349
# File 'lib/nexpose/vuln_exception.rb', line 340

def update_reviewer_comment(connection, comment)
  xml = connection.make_xml('VulnerabilityExceptionUpdateCommentRequest',
                            { 'exception-id' => @id })
  cxml = REXML::Element.new('reviewer-comment')
  cxml.add_text(comment)
  xml.add_element(cxml)
  @reviewer_comment = comment

  connection.execute(xml, '1.2').success
end

#update_submitter_comment(connection, comment) ⇒ Boolean

Update security console with submitter comment on this vulnerability exceptions.

Cannot update a submit comment unless exception is under review or has expired.

Parameters:

  • connection (Connection)

    Connection to security console.

  • comment (String)

    Submitter comment on this exception.

Returns:

  • (Boolean)

    Whether the comment was successfully submitted.



322
323
324
325
326
327
328
329
330
331
# File 'lib/nexpose/vuln_exception.rb', line 322

def update_submitter_comment(connection, comment)
  xml = connection.make_xml('VulnerabilityExceptionUpdateCommentRequest',
                            { 'exception-id' => @id })
  cxml = REXML::Element.new('submitter-comment')
  cxml.add_text(comment)
  xml.add_element(cxml)
  @submitter_comment = comment

  connection.execute(xml, '1.2').success
end

#validateObject

Validate that this exception meets to requires for the assigned scope.

Raises:

  • (ArgumentError)


367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
# File 'lib/nexpose/vuln_exception.rb', line 367

def validate
  raise ArgumentError.new('No vuln_id.') unless @vuln_id
  raise ArgumentError.new('No scope.') unless @scope
  raise ArgumentError.new('No reason.') unless @reason

  case @scope
  when Scope::ALL_INSTANCES
    @asset_id = @port = @vuln_key = nil
  when Scope::ALL_INSTANCES_ON_A_SPECIFIC_ASSET
    raise ArgumentError.new('No asset_id.') unless @asset_id
    @port = @vuln_key = nil
  when Scope::SPECIFIC_INSTANCE_OF_SPECIFIC_ASSET
    raise ArgumentError.new('No asset_id.') unless @asset_id
    raise ArgumentError.new('Port or vuln_key is required.') unless @port || @vuln_key
  when Scope::ALL_INSTANCES_IN_A_SPECIFIC_SITE
    raise ArgumentError.new('No site_id.') unless @site_id
  else
    raise ArgumentError.new("Invalid scope: #{@scope}")
  end
end