Class: Dawn::Kb::VersionCheck

Inherits:
Object
  • Object
show all
Includes:
BasicCheck
Defined in:
lib/dawn/kb/version_check.rb

Constant Summary

Constants included from BasicCheck

BasicCheck::ALLOWED_FAMILIES

Instance Attribute Summary collapse

Attributes included from BasicCheck

#applies, #aux_links, #check_family, #cve, #cvss, #cwe, #debug, #evidences, #fixes_version, #kind, #message, #mitigated, #name, #osvdb, #owasp, #priority, #release_date, #remediation, #ruby_version, #ruby_vulnerable_versions, #severity, #target_version, #title

Instance Method Summary collapse

Methods included from BasicCheck

#applies_to?, #cve_link, #cvss_score, families, #family, #family=, #lint, #mitigated?, #nvd_link, #osvdb_link, #rubysec_advisories_link

Methods included from Utils

#__debug_me_and_return, #debug_me, #debug_me_and_return_false, #debug_me_and_return_true

Constructor Details

#initialize(options = {}) ⇒ VersionCheck

Returns a new instance of VersionCheck.



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/dawn/kb/version_check.rb', line 16

def initialize(options={})
  super(options)
  @safe       ||= options[:safe]
  @deprecated ||= options[:deprecated]
  @excluded   ||= options[:excluded]
  @detected   ||= options[:detected]
  @save_minor ||= options[:save_minor]
  @save_major ||= options[:save_major]
  @debug      ||= options[:debug]
  @enable_warning ||= options[:enable_warning]
  debug_me "VersionCheck initialized"
end

Instance Attribute Details

#deprecatedObject

Returns the value of attribute deprecated.



7
8
9
# File 'lib/dawn/kb/version_check.rb', line 7

def deprecated
  @deprecated
end

#detectedObject

Returns the value of attribute detected.



9
10
11
# File 'lib/dawn/kb/version_check.rb', line 9

def detected
  @detected
end

#enable_warningObject

Returns the value of attribute enable_warning.



13
14
15
# File 'lib/dawn/kb/version_check.rb', line 13

def enable_warning
  @enable_warning
end

#excludedObject

Returns the value of attribute excluded.



8
9
10
# File 'lib/dawn/kb/version_check.rb', line 8

def excluded
  @excluded
end

#safeObject

Returns the value of attribute safe.



6
7
8
# File 'lib/dawn/kb/version_check.rb', line 6

def safe
  @safe
end

#save_majorObject

Returns the value of attribute save_major.



11
12
13
# File 'lib/dawn/kb/version_check.rb', line 11

def save_major
  @save_major
end

#save_minorObject

Returns the value of attribute save_minor.



10
11
12
# File 'lib/dawn/kb/version_check.rb', line 10

def save_minor
  @save_minor
end

#statusObject (readonly)

Returns the value of attribute status.



12
13
14
# File 'lib/dawn/kb/version_check.rb', line 12

def status
  @status
end

Instance Method Details

#is_beta_check?(safe_version_beta, detected_version_beta) ⇒ Boolean

Beta version handling

Returns:

  • (Boolean)


288
289
290
# File 'lib/dawn/kb/version_check.rb', line 288

def is_beta_check?(safe_version_beta, detected_version_beta)
  ( safe_version_beta != -1 || detected_version_beta != -1)
end

#is_deprecated?(detected_version) ⇒ Boolean

Returns:

  • (Boolean)


407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
# File 'lib/dawn/kb/version_check.rb', line 407

def is_deprecated?(detected_version)
  return false if detected_version.nil?
  return false if @deprecated.nil?
  @deprecated.each do |dep|
    dep_v = version_string_to_array(dep)[:version]
    det_v = version_string_to_array(detected_version)[:version]
    return true if is_same_version?(dep_v, det_v)
    if dep_v[0] == 'x'
      # deprecation version is something like 'x.0.0'. This is a
      # nonsense since it means all versions are deprecated. However
      # I'll support also nonsense checks.

      $logger.warn "Setting the predicate #{dep} will mark all versions as deprecated" unless self.enable_warning.nil?
      debug_me "You kindly mark #{detected_version} as deprecated with this predicate #{dep}"
      return true
    end

    if dep_v[1] == 'x'
      # deprecation version is something like 1.x
      # detected version is deprecated if major == 1. If 0 not
      return true if det_v[0] == dep_v[0]
    end

    if dep_v[2] == 'x'
      # deprecation version is something like 1.2.x
      # detected version is deprecated if major == 1 and minor == 2.
      return true if det_v[0] == dep_v[0] && det_v[1] == dep_v[1]

    end
  end
  false
end

#is_detected_deprecated?Boolean

Returns:

  • (Boolean)


92
93
94
# File 'lib/dawn/kb/version_check.rb', line 92

def is_detected_deprecated?
  return is_deprecated?(@detected)
end

#is_detected_excluded?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/dawn/kb/version_check.rb', line 95

def is_detected_excluded?
  return is_excluded?(@detected)
end

#is_detected_highest?Boolean

Returns:

  • (Boolean)


84
85
86
87
88
89
90
91
# File 'lib/dawn/kb/version_check.rb', line 84

def is_detected_highest?
  higher= @detected
  @safe.sort.each do |s|
    debug_me("higher is #{higher}")
    higher=s if is_higher?(s, higher)
  end
  return (higher == @detected)
end

#is_detected_in_safe?Boolean

Returns:

  • (Boolean)


77
78
79
80
81
82
# File 'lib/dawn/kb/version_check.rb', line 77

def is_detected_in_safe?
  @safe.each do |s|
    return true if @detected == s
  end
  return false
end

#is_excluded?(detected_version) ⇒ Boolean

Returns:

  • (Boolean)


397
398
399
400
401
402
403
404
405
406
# File 'lib/dawn/kb/version_check.rb', line 397

def is_excluded?(detected_version)
  return false if detected_version.nil?
  return false if @excluded.nil?
  @excluded.each do |exc|
    exc_v = version_string_to_array(exc)[:version]
    det_v = version_string_to_array(detected_version)[:version]
    return true if is_same_version?(exc_v, det_v)
  end
  return false
end

#is_good_parameter?(array) ⇒ Boolean

Returns:

  • (Boolean)


199
200
201
202
203
# File 'lib/dawn/kb/version_check.rb', line 199

def is_good_parameter?(array)
  return false if array.nil?
  return false if array.empty?
  return true
end

#is_higher?(a, b) ⇒ Boolean

Public: tells if a version is higher than another

e.g.

is_higher?('2.3.2', '2.4.2') => true
is_higher?('2.3.2', '2.3.2') => true

Returns:

  • (Boolean)


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/dawn/kb/version_check.rb', line 110

def is_higher?(a, b)
  aa = version_string_to_array(a)
  ba = version_string_to_array(b)

  ver = false
  beta = false
  rc = false
  same = false

  # Version arrays are just major.minor version. Let's assume
  # patchlevel is 0 for sake of comparison.
  aa[:version] << 0 if aa[:version].count == 2
  ba[:version] << 0 if ba[:version].count == 2

  # Handling a = '1.2.3.4' and b = '1.2.3'
  ba[:version] << 0 if aa[:version].count == 4 and ba[:version].count == 3

  ver = true if aa[:version][0] > ba[:version][0]
  ver = true if aa[:version][0] == ba[:version][0] && aa[:version][1] > ba[:version][1]
  ver = true if aa[:version].count == 3 && ba[:version].count == 3 && aa[:version][0] == ba[:version][0] && aa[:version][1] == ba[:version][1] && aa[:version][2] > ba[:version][2]
  ver = true if aa[:version].count == 4 && ba[:version].count == 4 && aa[:version][0] == ba[:version][0] && aa[:version][1] == ba[:version][1] && aa[:version][2] == ba[:version][2] && aa[:version][3] > ba[:version][3]
  ver = true if aa[:version].count == 4 && ba[:version].count == 4 && aa[:version][0] == ba[:version][0] && aa[:version][1] == ba[:version][1] && aa[:version][2] > ba[:version][2]
  same = is_same_version?(aa[:version], ba[:version])
  beta = true if aa[:beta] >= ba[:beta]
  rc = true if aa[:rc] >= ba[:rc]

  ret = false
  ret = ver && beta && rc unless same
  ret = beta && rc if same

  debug_me("is_higher? a=#{a}, b=#{b} VER=#{ver} - BETA=#{beta} - RC=#{rc} - SAME=#{same} - a>b? = (#{ret})")
  return ret
end

#is_higher_major?(s, d) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
102
103
# File 'lib/dawn/kb/version_check.rb', line 99

def is_higher_major?(s,d)
  sa = version_string_to_array(s)[:version]
  da = version_string_to_array(d)[:version]
  return (sa[0] > da[0])
end

#is_pre_check?(safe_version_pre, detected_version_pre) ⇒ Boolean

pre version handling

Returns:

  • (Boolean)


338
339
340
# File 'lib/dawn/kb/version_check.rb', line 338

def is_pre_check?(safe_version_pre, detected_version_pre)
  ( safe_version_pre != -1 || detected_version_pre != -1 )
end

#is_rc_check?(safe_version_rc, detected_version_rc) ⇒ Boolean

Rc version handling

Returns:

  • (Boolean)


312
313
314
# File 'lib/dawn/kb/version_check.rb', line 312

def is_rc_check?(safe_version_rc, detected_version_rc)
  ( safe_version_rc != -1 || detected_version_rc != -1 )
end

#is_same_major?(array_a, array_b) ⇒ Boolean

It checks if the first digit of a version array is the same

e.g. has_same_major?(, [1,2,2]) #=> false has_same_major?(, [2,2,2]) #=> true

Returns:

  • (Boolean)


210
211
212
213
# File 'lib/dawn/kb/version_check.rb', line 210

def is_same_major?(array_a, array_b)
  return false if ! is_good_parameter?(array_a) || ! is_good_parameter?(array_b)
  return (array_a[0] == array_b[0])
end

#is_same_minor?(array_a, array_b) ⇒ Boolean

Returns:

  • (Boolean)


214
215
216
217
# File 'lib/dawn/kb/version_check.rb', line 214

def is_same_minor?(array_a, array_b)
  return false if ! is_good_parameter?(array_a) || ! is_good_parameter?(array_b)
  return (array_a[1] == array_b[1])
end

#is_same_patch?(array_a, array_b) ⇒ Boolean

Returns:

  • (Boolean)


218
219
220
221
# File 'lib/dawn/kb/version_check.rb', line 218

def is_same_patch?(array_a, array_b)
  return false if ! is_good_parameter?(array_a) || ! is_good_parameter?(array_b)
  return (array_a[2] == array_b[2])
end

#is_same_version?(safe_version_array, detected_version_array, limit = false) ⇒ Boolean

Returns:

  • (Boolean)


262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/dawn/kb/version_check.rb', line 262

def is_same_version?(safe_version_array, detected_version_array, limit=false)
  ret = false

  ret = true if (safe_version_array[0] == detected_version_array[0]) if (safe_version_array[1] == 'x')
  ret = true if (safe_version_array[0] == detected_version_array[0]) && (safe_version_array[1] == detected_version_array[1]) && (safe_version_array.count == 2) && (detected_version_array.count == 2)
  ret = true if (safe_version_array[0] == detected_version_array[0]) && (safe_version_array[1] == detected_version_array[1]) && (safe_version_array[2] == detected_version_array[2]) && (safe_version_array.count == 3) && (detected_version_array.count == 3)
  ret = true if (safe_version_array[0] == detected_version_array[0]) && (safe_version_array[1] == detected_version_array[1]) && (safe_version_array[2] == detected_version_array[2]) && (safe_version_array[3] == detected_version_array[3]) && (safe_version_array.count == 4) && (detected_version_array.count == 4)

  if limit
    # this if handles comparison limited to first 3 items in version arrays
    # eg. in case of a beta release, the array is [5,0,0,1] meaning
    # 5.0.0.beta1. Of course it must be handled in a different way than
    # 5.0.0.1 release that it will result in the same array
    debug_me "is_same_version? with limit=TRUE"
    ret = true if (safe_version_array[0] == detected_version_array[0]) && (safe_version_array[1] == detected_version_array[1]) && (safe_version_array[2] == detected_version_array[2])
  end

  debug_me "is_same_version? SVA=#{safe_version_array} DVA=#{detected_version_array} RET=#{ret}"

  return ret
end

#is_there_an_higher_major_version?Boolean

checks in the array if there is another string with higher major version

Returns:

  • (Boolean)


145
146
147
148
149
150
151
152
153
# File 'lib/dawn/kb/version_check.rb', line 145

def is_there_an_higher_major_version?
  dva = version_string_to_array(@detected)[:version]
  @safe.sort.each do |s|
    sva = version_string_to_array(s)[:version]
    debug_me "is_there_an_higher_major_version? DVA=#{dva} - SVA=#{sva}"
    return debug_me_and_return_true("is_there_an_higher_major_version? is returning true for #{@detected}") if dva[0] < sva[0]
  end
  return debug_me_and_return_false("is_there_an_higher_major_version? is returning false")
end

#is_there_an_higher_minor_version?Boolean

checks in the array if there is another string with higher minor version but the same major as the parameter element)

Returns:

  • (Boolean)


156
157
158
159
160
161
162
163
# File 'lib/dawn/kb/version_check.rb', line 156

def is_there_an_higher_minor_version?
  dva = version_string_to_array(@detected)[:version]
  @safe.sort.each do |s|
    sva = version_string_to_array(s)[:version]
    return true if dva[0] == sva[0] && dva[1] < sva[1]
  end
  return false
end

#is_vulnerable_aux_patch?(safe_version, detected_version) ⇒ Boolean

Returns:

  • (Boolean)


231
232
233
234
235
236
# File 'lib/dawn/kb/version_check.rb', line 231

def is_vulnerable_aux_patch?(safe_version, detected_version)
  debug_me "is_vulnerable_aux_patch?: SV[3]=#{safe_version[3]}, DV[3]=#{detected_version[3]}"
  return true if detected_version[3].nil? and ! safe_version[3].nil?
  return false if safe_version[3].nil? || detected_version[3].nil?
  return (safe_version[3] > detected_version[3])
end

#is_vulnerable_beta?(safe_version_beta, detected_version_beta) ⇒ Boolean

Returns:

  • (Boolean)


292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/dawn/kb/version_check.rb', line 292

def is_vulnerable_beta?(safe_version_beta, detected_version_beta)
  # if the safe_version_beta is 0 then the detected_version_beta is
  # vulnerable by design, since the safe version is a stable and we
  # detected a beta.
  debug_me("is_vulnerable_beta?: safe_version_beta=#{safe_version_beta} - detected_version_beta=#{detected_version_beta}")
  return debug_me_and_return_false("is_vulnerable_beta? = FALSE") if safe_version_beta != -1 and detected_version_beta == -1
  return debug_me_and_return_true("is_vulnerable_beta? = TRUE") if safe_version_beta == -1 and detected_version_beta != -1
  return debug_me_and_return_true("is_vulnerable_beta? = TRUE") if safe_version_beta == 0 && detected_version_beta != -1
  return debug_me_and_return_false("is_vulnerable_beta? = FALSE") if safe_version_beta <= detected_version_beta
  return debug_me_and_return_true("is_vulnerable_beta? = TRUE") if safe_version_beta > detected_version_beta

  # fallback
  return false
end

#is_vulnerable_major?(safe_version, detected_version) ⇒ Boolean

Returns:

  • (Boolean)


223
224
225
# File 'lib/dawn/kb/version_check.rb', line 223

def is_vulnerable_major?(safe_version, detected_version)
  return (safe_version[0] > detected_version[0])
end

#is_vulnerable_minor?(safe_version, detected_version) ⇒ Boolean

Returns:

  • (Boolean)


239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/dawn/kb/version_check.rb', line 239

def is_vulnerable_minor?(safe_version, detected_version)
  if safe_version.length < detected_version.length
    # safe version is just the major number e.g. 2
    # detected version is kinda more complex e.g. 2.3.2 or 1.2.3
    # we relay on major here
    return is_vulnerable_major?(safe_version, detected_version)
  end
  if safe_version.length > detected_version.length
    # detected version is just the major number e.g. 2
    # safe version is kinda more complex e.g. 2.3.2
    # in this case we return the version is vulnerable if the
    # detected_version major is less or equal the safe one.
    return (safe_version[0] < detected_version[0])
  end

  # support for x as safe minor version
  return false if is_same_major?(safe_version, detected_version) && safe_version[1] == 'x'
  return false if safe_version[0] <= detected_version[0] && safe_version[1] == 'x'
  return true if safe_version[0] > detected_version[0] && safe_version[1] == 'x'
  return true if safe_version[1] > detected_version[1]
  return false if safe_version[1] <= detected_version[1]
end

#is_vulnerable_patch?(safe_version, detected_version) ⇒ Boolean

Returns:

  • (Boolean)


227
228
229
230
# File 'lib/dawn/kb/version_check.rb', line 227

def is_vulnerable_patch?(safe_version, detected_version)
  return false if safe_version[2].nil? || detected_version[2].nil?
  return (safe_version[2] > detected_version[2])
end

#is_vulnerable_pre?(safe_version_pre, detected_version_pre) ⇒ Boolean

Returns:

  • (Boolean)


342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/dawn/kb/version_check.rb', line 342

def is_vulnerable_pre?(safe_version_pre, detected_version_pre)
  # if the safe_version_pre is 0 then the detected_version_pre is
  # vulnerable by design, since the safe version is a stable and we
  # detected a pre.
  return debug_me_and_return_false("is_vulnerable_pre? = FALSE") if safe_version_pre != -1 and detected_version_pre == -1
  return debug_me_and_return_true("is_vulnerable_pre? = TRUE") if safe_version_pre == -1 and detected_version_pre != -1
  return debug_me_and_return_true("is_vulnerable_pre? = TRUE") if safe_version_pre == 0 && detected_version_pre != -1
  return debug_me_and_return_false("is_vulnerable_pre? = FALSE") if safe_version_pre <= detected_version_pre
  return debug_me_and_return_true("is_vulnerable_pre? = TRUE") if safe_version_pre > detected_version_pre


  # fallback
  return false
end

#is_vulnerable_rc?(safe_version_rc, detected_version_rc) ⇒ Boolean

Returns:

  • (Boolean)


316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/dawn/kb/version_check.rb', line 316

def is_vulnerable_rc?(safe_version_rc, detected_version_rc)
  # if the safe_version_rc is 0 then the detected_version_rc is
  # vulnerable by design, since the safe version is a stable and we
  # detected a rc.
  debug_me "entering is_vulnerable_rc?: s=#{safe_version_rc}, d=#{detected_version_rc}"
  return debug_me_and_return_false("is_vulnerable_rc? = FALSE") if detected_version_rc == -1

  return debug_me_and_return_false("is_vulnerable_rc? = FALSE") if safe_version_rc != -1 and detected_version_rc == -1
  return debug_me_and_return_true("is_vulnerable_rc? = TRUE") if safe_version_rc == -1 and detected_version_rc != -1
  return debug_me_and_return_true("is_vulnerable_rc? = TRUE") if safe_version_rc == 0 && detected_version_rc != -1
  return debug_me_and_return_false("is_vulnerable_rc? = FALSE") if safe_version_rc <= detected_version_rc
  return debug_me_and_return_true("is_vulnerable_rc? = TRUE") if safe_version_rc > detected_version_rc

  # fallback
  return false
end

#is_vulnerable_version?(safe_version, detected_version) ⇒ Boolean

Returns:

  • (Boolean)


357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
# File 'lib/dawn/kb/version_check.rb', line 357

def is_vulnerable_version?(safe_version, detected_version)
  sva = version_string_to_array(safe_version)
  dva = version_string_to_array(detected_version)
  debug_me("SVA=#{sva.inspect}")
  debug_me("DVA=#{dva.inspect}")
  safe_version_array = sva[:version]
  detected_version_array = dva[:version]

  safe_version_array << 0 if safe_version_array.count == 2
  detected_version_array << 0 if detected_version_array.count == 2

  major = is_vulnerable_major?(safe_version_array, detected_version_array)
  minor = is_vulnerable_minor?(safe_version_array, detected_version_array)
  patch = is_vulnerable_patch?(safe_version_array, detected_version_array)
  aux_patch = is_vulnerable_aux_patch?(safe_version_array, detected_version_array)

  debug_me "is_vulnerable_version? SAVE_VERSION=#{safe_version},DETECTED=#{detected_version} -> IS_VULN_MAJOR?=#{major} IS_VULN_MINOR?=#{minor} IS_VULN_PATCH?=#{patch} IS_VULN_AUX_PATCH=#{aux_patch} SAVE_MINOR_FIX=#{@save_minor_fix} SAVE_MAJOR_FIX=#{@save_major_fix}"

  return debug_me_and_return_false("#{detected_version} doesn't have a vulnerable MAJOR number") if is_higher_major?(detected_version, safe_version) #and minor and patch

  return is_vulnerable_beta?(sva[:beta], dva[:beta]) if is_same_version?(safe_version_array, detected_version_array, true) && is_beta_check?(sva[:beta], dva[:beta])
  return is_vulnerable_rc?(sva[:rc], dva[:rc]) if is_same_version?(safe_version_array, detected_version_array, true) && is_rc_check?(sva[:rc], dva[:rc])
  return is_vulnerable_pre?(sva[:pre], dva[:pre]) if is_same_version?(safe_version_array, detected_version_array, true) && is_pre_check?(sva[:pre], dva[:pre])

  # we have a non vulnerable major, but the minor is and there is an higher version in array
  # eg. we detected v1.3.2, safe version is 1.3.3 and there is also a safe 2.x.x
  return debug_me_and_return_false("#{detected_version} has a major version vulnerable but honoring save_major_fix") if major && @save_major_fix
  return debug_me_and_return_false("#{detected_version} has a minor version vulnerable but honoring save_minor_fix") if minor and @save_minor_fix
  return true if major && minor
  return true if ! major && minor && patch && ! @save_major_fix && ! @save_minor_fix
  return true if major && !@save_major_fix
  return true if !major && minor && @save_major_fix
  return patch if is_same_major?(safe_version_array, detected_version_array) && is_same_minor?(safe_version_array, detected_version_array) && !aux_patch
  return aux_patch if is_same_major?(safe_version_array, detected_version_array) && is_same_minor?(safe_version_array, detected_version_array) && is_same_patch?(safe_version_array, detected_version_array)
  return true if is_same_major?(safe_version_array, detected_version_array) && is_same_minor?(safe_version_array, detected_version_array) && patch && aux_patch
  return true if is_same_major?(safe_version_array, detected_version_array) && minor

  return false
end

#save_major_fixObject



165
166
167
168
# File 'lib/dawn/kb/version_check.rb', line 165

def save_major_fix
  return false unless @save_major
  return is_there_an_higher_major_version?
end

#save_minor_fixObject

This functions handles an hack to save a detected version even if a safe version with an higher minor version number has been found.

This is mostly used in rails where there are different versions and if a 3.2.12 is safe it should not marked as vulnerable just because you can either use 3.3.x that is a different branch.

It returns true when the detected version must be saved, false otherwise.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/dawn/kb/version_check.rb', line 178

def save_minor_fix
  return false unless @save_minor
  hm = is_there_an_higher_minor_version?

  # This is the save minor version workaround.
  # fixes is something like ['2.2.2', '3.1.1', '3.2.2']
  # target is '3.1.1' and save_minor_fixes is true
  # I don't want that check for 3.2.2 marks this as vulnerable, so I will save it
  dva = version_string_to_array(@detected)[:version]
  @safe.sort.each do |s|
    sva = version_string_to_array(s)[:version]
    sM = is_same_major?(sva, dva)
    sm = is_same_minor?(sva, dva)
    debug_me("save_minor_fix: SVA=#{sva};DVA=#{dva};SAME_MAJOR? = #{sM}; SAME_MINOR?=#{sm}; ( dva[2] >= sva[2] )=#{(dva[2] >= sva[2])}")
    debug_me("save_minor_fix: is_there_higher_minor_version? = #{hm}")
    return true if sM and sm and dva[2] >= sva[2] && hm
    return true if sM and hm
  end
  return false
end

#version_string_to_array(string) ⇒ Object

It takes a string representing a version and it splits it in an Hash.

e.g. version_string_to_array(“3.2.3”) #=> href="3,2,3">version=>, :beta=>0, :rc=>0 version_string_to_array(“3.2.2.beta1”) #=> href="3,2,2">version=>, :beta=>1, :rc=>0



447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/dawn/kb/version_check.rb', line 447

def version_string_to_array(string)
  # I can't use this nice onliner... stays here until I finish writing new code.
  # return string.split(".").map! { |n| (n=='x')? n : n.to_i }
  ver   = []
  beta  = -1
  rc    = -1
  pre   = -1

  string.split(".").each do |x|
    ver << x.to_i unless x == 'x' || x.start_with?('beta') || x.start_with?('rc') || x.start_with?('pre')
    ver << x if x == 'x'

    beta = x.split("beta")[1].to_i if x.class == String && x.start_with?('beta') && beta == -1
    rc = x.split("rc")[1].to_i if x.class == String && x.start_with?('rc') && rc == -1
    pre = x.split("pre")[1].to_i if x.class == String && x.start_with?('pre') && pre == -1

  end
  {:version=>ver, :beta=>beta, :rc=>rc, :pre=>pre}
end

#vuln?Boolean

Returns:

  • (Boolean)


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/dawn/kb/version_check.rb', line 29

def vuln?
  debug_me "Detected version is #{@detected}"
  debug_me "Safe versions array is #{@safe}"
  debug_me "Deprecated versions array is #{@deprecated}. I'll mark them as vulnerable" unless @deprecated.nil?
  debug_me "Excluded versions array is #{@excluded}. I'll mark them as not vulnerable" unless @excluded.nil?
  debug_me "SAVE_MINOR FLAG = #{@save_minor}"
  debug_me "SAVE_MAJOR FLAG = #{@save_major}"

  @status = :deprecated if is_detected_deprecated?
  return debug_me_and_return_false("detected version #{detected} is marked to be excluded for vulnerable ones")   if is_detected_excluded?

  # is the detected version in the safe array?
  return debug_me_and_return_false("detected version #{@detected} found as is in safe array")      if is_detected_in_safe?
  return debug_me_and_return_false("detected version #{@detected} is higher than all version marked safe")  if is_detected_highest?

  check_versions = nil
  @safe.each do |safe_version|

    sva = version_string_to_array(safe_version)
    dva = version_string_to_array(@detected)

    next unless is_same_version?(sva[:version], dva[:version], true)
    next unless sva[:version].count == dva[:version].count || is_beta_check?(sva[:beta], dva[:beta]) || is_rc_check?(sva[:rc], dva[:rc]) || is_pre_check?(sva[:pre], dva[:pre])

    check_versions = [safe_version]
    break
  end

  debug_me "vuln?: limited check_versions: #{check_versions.inspect}"
  check_versions ||= @safe
  debug_me "vuln?: fallback check_versions: #{check_versions.inspect}"

  check_versions.sort.each do |s|
    debug_me "vuln?: evaluating #{@detected} against save version: #{s}"

    @save_minor_fix   = save_minor_fix
    @save_major_fix   = save_major_fix


    vuln  = is_vulnerable_version?(s, @detected)

    debug_me "DETECTED #{@detected} is marked VULN=#{vuln} against #{s} ( SAVE_MINOR_FIX=#{@save_minor_fix} SAVE_MAJOR_FIX=#{@save_major_fix})"
    return true if vuln
  end

  return false
end