Class: Dawn::Kb::VersionCheck
- Inherits:
-
Object
- Object
- Dawn::Kb::VersionCheck
- Includes:
- BasicCheck
- Defined in:
- lib/dawn/kb/version_check.rb
Constant Summary
Constants included from BasicCheck
Instance Attribute Summary collapse
-
#deprecated ⇒ Object
Returns the value of attribute deprecated.
-
#detected ⇒ Object
Returns the value of attribute detected.
-
#enable_warning ⇒ Object
Returns the value of attribute enable_warning.
-
#excluded ⇒ Object
Returns the value of attribute excluded.
-
#safe ⇒ Object
Returns the value of attribute safe.
-
#save_major ⇒ Object
Returns the value of attribute save_major.
-
#save_minor ⇒ Object
Returns the value of attribute save_minor.
-
#status ⇒ Object
readonly
Returns the value of attribute status.
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
-
#initialize(options = {}) ⇒ VersionCheck
constructor
A new instance of VersionCheck.
-
#is_beta_check?(safe_version_beta, detected_version_beta) ⇒ Boolean
Beta version handling.
- #is_deprecated?(detected_version) ⇒ Boolean
- #is_detected_deprecated? ⇒ Boolean
- #is_detected_excluded? ⇒ Boolean
- #is_detected_highest? ⇒ Boolean
- #is_detected_in_safe? ⇒ Boolean
- #is_excluded?(detected_version) ⇒ Boolean
- #is_good_parameter?(array) ⇒ Boolean
-
#is_higher?(a, b) ⇒ Boolean
Public: tells if a version is higher than another.
- #is_higher_major?(s, d) ⇒ Boolean
-
#is_pre_check?(safe_version_pre, detected_version_pre) ⇒ Boolean
pre version handling.
-
#is_rc_check?(safe_version_rc, detected_version_rc) ⇒ Boolean
Rc version handling.
-
#is_same_major?(array_a, array_b) ⇒ Boolean
It checks if the first digit of a version array is the same.
- #is_same_minor?(array_a, array_b) ⇒ Boolean
- #is_same_patch?(array_a, array_b) ⇒ Boolean
- #is_same_version?(safe_version_array, detected_version_array, limit = false) ⇒ Boolean
-
#is_there_an_higher_major_version? ⇒ Boolean
checks in the array if there is another string with higher major version.
-
#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).
- #is_vulnerable_aux_patch?(safe_version, detected_version) ⇒ Boolean
- #is_vulnerable_beta?(safe_version_beta, detected_version_beta) ⇒ Boolean
- #is_vulnerable_major?(safe_version, detected_version) ⇒ Boolean
- #is_vulnerable_minor?(safe_version, detected_version) ⇒ Boolean
- #is_vulnerable_patch?(safe_version, detected_version) ⇒ Boolean
- #is_vulnerable_pre?(safe_version_pre, detected_version_pre) ⇒ Boolean
- #is_vulnerable_rc?(safe_version_rc, detected_version_rc) ⇒ Boolean
- #is_vulnerable_version?(safe_version, detected_version) ⇒ Boolean
- #save_major_fix ⇒ Object
-
#save_minor_fix ⇒ Object
This functions handles an hack to save a detected version even if a safe version with an higher minor version number has been found.
-
#version_string_to_array(string) ⇒ Object
It takes a string representing a version and it splits it in an Hash.
- #vuln? ⇒ Boolean
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(={}) super() @safe ||= [:safe] @deprecated ||= [:deprecated] @excluded ||= [:excluded] @detected ||= [:detected] @save_minor ||= [:save_minor] @save_major ||= [:save_major] @debug ||= [:debug] @enable_warning ||= [:enable_warning] debug_me "VersionCheck initialized" end |
Instance Attribute Details
#deprecated ⇒ Object
Returns the value of attribute deprecated.
7 8 9 |
# File 'lib/dawn/kb/version_check.rb', line 7 def deprecated @deprecated end |
#detected ⇒ Object
Returns the value of attribute detected.
9 10 11 |
# File 'lib/dawn/kb/version_check.rb', line 9 def detected @detected end |
#enable_warning ⇒ Object
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 |
#excluded ⇒ Object
Returns the value of attribute excluded.
8 9 10 |
# File 'lib/dawn/kb/version_check.rb', line 8 def excluded @excluded end |
#safe ⇒ Object
Returns the value of attribute safe.
6 7 8 |
# File 'lib/dawn/kb/version_check.rb', line 6 def safe @safe end |
#save_major ⇒ Object
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_minor ⇒ Object
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 |
#status ⇒ Object (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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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
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
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
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
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
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_fix ⇒ Object
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_fix ⇒ Object
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
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 |