dawnscanner 1.2.99

Sign up to get free protection for your applications and to get access to all the features.
Files changed (306) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +4 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +19 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +8 -0
  8. data/Changelog.md +412 -0
  9. data/Gemfile +4 -0
  10. data/KnowledgeBase.md +213 -0
  11. data/LICENSE.txt +22 -0
  12. data/README.md +354 -0
  13. data/Rakefile +250 -0
  14. data/Roadmap.md +59 -0
  15. data/bin/dawn +210 -0
  16. data/certs/paolo_at_codesake_dot_com.pem +21 -0
  17. data/checksum/.placeholder +0 -0
  18. data/checksum/codesake-dawn-1.1.0.gem.sha512 +1 -0
  19. data/checksum/codesake-dawn-1.1.0.rc1.gem.sha512 +1 -0
  20. data/checksum/codesake-dawn-1.1.1.gem.sha512 +1 -0
  21. data/checksum/codesake-dawn-1.1.2.gem.sha512 +1 -0
  22. data/checksum/codesake-dawn-1.1.3.gem.sha512 +1 -0
  23. data/checksum/codesake-dawn-1.2.0.gem.sha512 +1 -0
  24. data/checksum/codesake-dawn-1.2.99.gem.sha512 +1 -0
  25. data/dawnscanner.gemspec +43 -0
  26. data/doc/codesake-dawn.yaml.sample +26 -0
  27. data/doc/dawn_1_0_announcement.md +139 -0
  28. data/doc/dawn_1_1_announcement.md +67 -0
  29. data/doc/dawn_1_2_announcement.md +69 -0
  30. data/features/dawn_complains_about_an_incorrect_command_line.feature.disabled +21 -0
  31. data/features/dawn_scan_a_secure_sinatra_app.feature.disabled +31 -0
  32. data/features/dawn_scan_a_vulnerable_sinatra_app.feature.disabled +36 -0
  33. data/features/step_definition/dawn_steps.rb +19 -0
  34. data/features/support/env.rb +1 -0
  35. data/lib/codesake-dawn.rb +12 -0
  36. data/lib/codesake/dawn/core.rb +175 -0
  37. data/lib/codesake/dawn/engine.rb +380 -0
  38. data/lib/codesake/dawn/gemfile_lock.rb +12 -0
  39. data/lib/codesake/dawn/kb/basic_check.rb +228 -0
  40. data/lib/codesake/dawn/kb/combo_check.rb +64 -0
  41. data/lib/codesake/dawn/kb/cve_2004_0755.rb +32 -0
  42. data/lib/codesake/dawn/kb/cve_2004_0983.rb +30 -0
  43. data/lib/codesake/dawn/kb/cve_2005_1992.rb +30 -0
  44. data/lib/codesake/dawn/kb/cve_2005_2337.rb +32 -0
  45. data/lib/codesake/dawn/kb/cve_2006_1931.rb +32 -0
  46. data/lib/codesake/dawn/kb/cve_2006_2582.rb +30 -0
  47. data/lib/codesake/dawn/kb/cve_2006_3694.rb +31 -0
  48. data/lib/codesake/dawn/kb/cve_2006_4112.rb +29 -0
  49. data/lib/codesake/dawn/kb/cve_2006_5467.rb +30 -0
  50. data/lib/codesake/dawn/kb/cve_2006_6303.rb +30 -0
  51. data/lib/codesake/dawn/kb/cve_2006_6852.rb +29 -0
  52. data/lib/codesake/dawn/kb/cve_2006_6979.rb +31 -0
  53. data/lib/codesake/dawn/kb/cve_2007_0469.rb +29 -0
  54. data/lib/codesake/dawn/kb/cve_2007_5162.rb +30 -0
  55. data/lib/codesake/dawn/kb/cve_2007_5379.rb +29 -0
  56. data/lib/codesake/dawn/kb/cve_2007_5380.rb +29 -0
  57. data/lib/codesake/dawn/kb/cve_2007_5770.rb +32 -0
  58. data/lib/codesake/dawn/kb/cve_2007_6077.rb +31 -0
  59. data/lib/codesake/dawn/kb/cve_2007_6612.rb +30 -0
  60. data/lib/codesake/dawn/kb/cve_2008_1145.rb +40 -0
  61. data/lib/codesake/dawn/kb/cve_2008_1891.rb +40 -0
  62. data/lib/codesake/dawn/kb/cve_2008_2376.rb +32 -0
  63. data/lib/codesake/dawn/kb/cve_2008_2662.rb +35 -0
  64. data/lib/codesake/dawn/kb/cve_2008_2663.rb +34 -0
  65. data/lib/codesake/dawn/kb/cve_2008_2664.rb +35 -0
  66. data/lib/codesake/dawn/kb/cve_2008_2725.rb +33 -0
  67. data/lib/codesake/dawn/kb/cve_2008_3655.rb +39 -0
  68. data/lib/codesake/dawn/kb/cve_2008_3657.rb +39 -0
  69. data/lib/codesake/dawn/kb/cve_2008_3790.rb +32 -0
  70. data/lib/codesake/dawn/kb/cve_2008_3905.rb +38 -0
  71. data/lib/codesake/dawn/kb/cve_2008_4094.rb +29 -0
  72. data/lib/codesake/dawn/kb/cve_2008_4310.rb +103 -0
  73. data/lib/codesake/dawn/kb/cve_2008_5189.rb +29 -0
  74. data/lib/codesake/dawn/kb/cve_2008_7248.rb +29 -0
  75. data/lib/codesake/dawn/kb/cve_2009_4078.rb +31 -0
  76. data/lib/codesake/dawn/kb/cve_2009_4124.rb +32 -0
  77. data/lib/codesake/dawn/kb/cve_2009_4214.rb +29 -0
  78. data/lib/codesake/dawn/kb/cve_2010_1330.rb +30 -0
  79. data/lib/codesake/dawn/kb/cve_2010_2489.rb +62 -0
  80. data/lib/codesake/dawn/kb/cve_2010_3933.rb +29 -0
  81. data/lib/codesake/dawn/kb/cve_2011_0188.rb +69 -0
  82. data/lib/codesake/dawn/kb/cve_2011_0446.rb +30 -0
  83. data/lib/codesake/dawn/kb/cve_2011_0447.rb +30 -0
  84. data/lib/codesake/dawn/kb/cve_2011_0739.rb +30 -0
  85. data/lib/codesake/dawn/kb/cve_2011_0995.rb +63 -0
  86. data/lib/codesake/dawn/kb/cve_2011_1004.rb +36 -0
  87. data/lib/codesake/dawn/kb/cve_2011_1005.rb +33 -0
  88. data/lib/codesake/dawn/kb/cve_2011_2197.rb +29 -0
  89. data/lib/codesake/dawn/kb/cve_2011_2686.rb +31 -0
  90. data/lib/codesake/dawn/kb/cve_2011_2705.rb +34 -0
  91. data/lib/codesake/dawn/kb/cve_2011_2929.rb +29 -0
  92. data/lib/codesake/dawn/kb/cve_2011_2930.rb +30 -0
  93. data/lib/codesake/dawn/kb/cve_2011_2931.rb +32 -0
  94. data/lib/codesake/dawn/kb/cve_2011_2932.rb +29 -0
  95. data/lib/codesake/dawn/kb/cve_2011_3009.rb +30 -0
  96. data/lib/codesake/dawn/kb/cve_2011_3186.rb +31 -0
  97. data/lib/codesake/dawn/kb/cve_2011_3187.rb +31 -0
  98. data/lib/codesake/dawn/kb/cve_2011_4319.rb +31 -0
  99. data/lib/codesake/dawn/kb/cve_2011_4815.rb +30 -0
  100. data/lib/codesake/dawn/kb/cve_2011_5036.rb +28 -0
  101. data/lib/codesake/dawn/kb/cve_2012_1098.rb +32 -0
  102. data/lib/codesake/dawn/kb/cve_2012_1099.rb +29 -0
  103. data/lib/codesake/dawn/kb/cve_2012_1241.rb +29 -0
  104. data/lib/codesake/dawn/kb/cve_2012_2139.rb +28 -0
  105. data/lib/codesake/dawn/kb/cve_2012_2140.rb +29 -0
  106. data/lib/codesake/dawn/kb/cve_2012_2660.rb +30 -0
  107. data/lib/codesake/dawn/kb/cve_2012_2661.rb +29 -0
  108. data/lib/codesake/dawn/kb/cve_2012_2671.rb +30 -0
  109. data/lib/codesake/dawn/kb/cve_2012_2694.rb +32 -0
  110. data/lib/codesake/dawn/kb/cve_2012_2695.rb +29 -0
  111. data/lib/codesake/dawn/kb/cve_2012_3424.rb +31 -0
  112. data/lib/codesake/dawn/kb/cve_2012_3463.rb +29 -0
  113. data/lib/codesake/dawn/kb/cve_2012_3464.rb +29 -0
  114. data/lib/codesake/dawn/kb/cve_2012_3465.rb +28 -0
  115. data/lib/codesake/dawn/kb/cve_2012_4464.rb +29 -0
  116. data/lib/codesake/dawn/kb/cve_2012_4466.rb +29 -0
  117. data/lib/codesake/dawn/kb/cve_2012_4481.rb +28 -0
  118. data/lib/codesake/dawn/kb/cve_2012_4522.rb +29 -0
  119. data/lib/codesake/dawn/kb/cve_2012_5370.rb +29 -0
  120. data/lib/codesake/dawn/kb/cve_2012_5371.rb +29 -0
  121. data/lib/codesake/dawn/kb/cve_2012_5380.rb +30 -0
  122. data/lib/codesake/dawn/kb/cve_2012_6109.rb +27 -0
  123. data/lib/codesake/dawn/kb/cve_2012_6134.rb +29 -0
  124. data/lib/codesake/dawn/kb/cve_2012_6496.rb +30 -0
  125. data/lib/codesake/dawn/kb/cve_2012_6497.rb +30 -0
  126. data/lib/codesake/dawn/kb/cve_2013_0155.rb +31 -0
  127. data/lib/codesake/dawn/kb/cve_2013_0156.rb +29 -0
  128. data/lib/codesake/dawn/kb/cve_2013_0162.rb +30 -0
  129. data/lib/codesake/dawn/kb/cve_2013_0175.rb +29 -0
  130. data/lib/codesake/dawn/kb/cve_2013_0183.rb +27 -0
  131. data/lib/codesake/dawn/kb/cve_2013_0184.rb +27 -0
  132. data/lib/codesake/dawn/kb/cve_2013_0233.rb +28 -0
  133. data/lib/codesake/dawn/kb/cve_2013_0256.rb +61 -0
  134. data/lib/codesake/dawn/kb/cve_2013_0262.rb +28 -0
  135. data/lib/codesake/dawn/kb/cve_2013_0263.rb +28 -0
  136. data/lib/codesake/dawn/kb/cve_2013_0269.rb +29 -0
  137. data/lib/codesake/dawn/kb/cve_2013_0276.rb +30 -0
  138. data/lib/codesake/dawn/kb/cve_2013_0277.rb +27 -0
  139. data/lib/codesake/dawn/kb/cve_2013_0284.rb +29 -0
  140. data/lib/codesake/dawn/kb/cve_2013_0285.rb +29 -0
  141. data/lib/codesake/dawn/kb/cve_2013_0333.rb +30 -0
  142. data/lib/codesake/dawn/kb/cve_2013_1607.rb +27 -0
  143. data/lib/codesake/dawn/kb/cve_2013_1655.rb +67 -0
  144. data/lib/codesake/dawn/kb/cve_2013_1656.rb +30 -0
  145. data/lib/codesake/dawn/kb/cve_2013_1756.rb +28 -0
  146. data/lib/codesake/dawn/kb/cve_2013_1800.rb +28 -0
  147. data/lib/codesake/dawn/kb/cve_2013_1801.rb +29 -0
  148. data/lib/codesake/dawn/kb/cve_2013_1802.rb +29 -0
  149. data/lib/codesake/dawn/kb/cve_2013_1812.rb +29 -0
  150. data/lib/codesake/dawn/kb/cve_2013_1821.rb +30 -0
  151. data/lib/codesake/dawn/kb/cve_2013_1854.rb +28 -0
  152. data/lib/codesake/dawn/kb/cve_2013_1855.rb +27 -0
  153. data/lib/codesake/dawn/kb/cve_2013_1856.rb +28 -0
  154. data/lib/codesake/dawn/kb/cve_2013_1857.rb +29 -0
  155. data/lib/codesake/dawn/kb/cve_2013_1875.rb +29 -0
  156. data/lib/codesake/dawn/kb/cve_2013_1898.rb +29 -0
  157. data/lib/codesake/dawn/kb/cve_2013_1911.rb +30 -0
  158. data/lib/codesake/dawn/kb/cve_2013_1933.rb +29 -0
  159. data/lib/codesake/dawn/kb/cve_2013_1947.rb +29 -0
  160. data/lib/codesake/dawn/kb/cve_2013_1948.rb +29 -0
  161. data/lib/codesake/dawn/kb/cve_2013_2065.rb +31 -0
  162. data/lib/codesake/dawn/kb/cve_2013_2090.rb +30 -0
  163. data/lib/codesake/dawn/kb/cve_2013_2105.rb +28 -0
  164. data/lib/codesake/dawn/kb/cve_2013_2119.rb +29 -0
  165. data/lib/codesake/dawn/kb/cve_2013_2512.rb +28 -0
  166. data/lib/codesake/dawn/kb/cve_2013_2513.rb +27 -0
  167. data/lib/codesake/dawn/kb/cve_2013_2516.rb +28 -0
  168. data/lib/codesake/dawn/kb/cve_2013_2615.rb +29 -0
  169. data/lib/codesake/dawn/kb/cve_2013_2616.rb +29 -0
  170. data/lib/codesake/dawn/kb/cve_2013_2617.rb +30 -0
  171. data/lib/codesake/dawn/kb/cve_2013_3221.rb +29 -0
  172. data/lib/codesake/dawn/kb/cve_2013_4164.rb +32 -0
  173. data/lib/codesake/dawn/kb/cve_2013_4203.rb +27 -0
  174. data/lib/codesake/dawn/kb/cve_2013_4389.rb +28 -0
  175. data/lib/codesake/dawn/kb/cve_2013_4413.rb +29 -0
  176. data/lib/codesake/dawn/kb/cve_2013_4457.rb +31 -0
  177. data/lib/codesake/dawn/kb/cve_2013_4478.rb +28 -0
  178. data/lib/codesake/dawn/kb/cve_2013_4479.rb +28 -0
  179. data/lib/codesake/dawn/kb/cve_2013_4489.rb +30 -0
  180. data/lib/codesake/dawn/kb/cve_2013_4491.rb +30 -0
  181. data/lib/codesake/dawn/kb/cve_2013_4492.rb +31 -0
  182. data/lib/codesake/dawn/kb/cve_2013_4562.rb +29 -0
  183. data/lib/codesake/dawn/kb/cve_2013_4593.rb +29 -0
  184. data/lib/codesake/dawn/kb/cve_2013_5647.rb +31 -0
  185. data/lib/codesake/dawn/kb/cve_2013_5671.rb +28 -0
  186. data/lib/codesake/dawn/kb/cve_2013_6414.rb +31 -0
  187. data/lib/codesake/dawn/kb/cve_2013_6415.rb +30 -0
  188. data/lib/codesake/dawn/kb/cve_2013_6416.rb +31 -0
  189. data/lib/codesake/dawn/kb/cve_2013_6417.rb +31 -0
  190. data/lib/codesake/dawn/kb/cve_2013_6421.rb +30 -0
  191. data/lib/codesake/dawn/kb/cve_2013_6459.rb +30 -0
  192. data/lib/codesake/dawn/kb/cve_2013_6460.rb +55 -0
  193. data/lib/codesake/dawn/kb/cve_2013_6461.rb +59 -0
  194. data/lib/codesake/dawn/kb/cve_2013_7086.rb +29 -0
  195. data/lib/codesake/dawn/kb/cve_2014_0036.rb +29 -0
  196. data/lib/codesake/dawn/kb/cve_2014_0080.rb +30 -0
  197. data/lib/codesake/dawn/kb/cve_2014_0081.rb +28 -0
  198. data/lib/codesake/dawn/kb/cve_2014_0082.rb +29 -0
  199. data/lib/codesake/dawn/kb/cve_2014_0130.rb +28 -0
  200. data/lib/codesake/dawn/kb/cve_2014_1233.rb +29 -0
  201. data/lib/codesake/dawn/kb/cve_2014_1234.rb +28 -0
  202. data/lib/codesake/dawn/kb/cve_2014_2322.rb +30 -0
  203. data/lib/codesake/dawn/kb/cve_2014_2525.rb +61 -0
  204. data/lib/codesake/dawn/kb/cve_2014_2538.rb +28 -0
  205. data/lib/codesake/dawn/kb/cve_2014_3482.rb +30 -0
  206. data/lib/codesake/dawn/kb/cve_2014_3483.rb +29 -0
  207. data/lib/codesake/dawn/kb/dependency_check.rb +86 -0
  208. data/lib/codesake/dawn/kb/deprecation_check.rb +40 -0
  209. data/lib/codesake/dawn/kb/not_revised_code.rb +24 -0
  210. data/lib/codesake/dawn/kb/operating_system_check.rb +98 -0
  211. data/lib/codesake/dawn/kb/osvdb_105971.rb +31 -0
  212. data/lib/codesake/dawn/kb/osvdb_108530.rb +29 -0
  213. data/lib/codesake/dawn/kb/osvdb_108563.rb +30 -0
  214. data/lib/codesake/dawn/kb/osvdb_108569.rb +30 -0
  215. data/lib/codesake/dawn/kb/osvdb_108570.rb +29 -0
  216. data/lib/codesake/dawn/kb/owasp_ror_cheatsheet.rb +41 -0
  217. data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/check_for_backup_files.rb +22 -0
  218. data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/check_for_safe_redirect_and_forward.rb +59 -0
  219. data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/command_injection.rb +30 -0
  220. data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/csrf.rb +31 -0
  221. data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/mass_assignment_in_model.rb +35 -0
  222. data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/security_related_headers.rb +38 -0
  223. data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/sensitive_files.rb +31 -0
  224. data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/session_stored_in_database.rb +33 -0
  225. data/lib/codesake/dawn/kb/pattern_match_check.rb +129 -0
  226. data/lib/codesake/dawn/kb/ruby_version_check.rb +91 -0
  227. data/lib/codesake/dawn/kb/simpleform_xss_20131129.rb +30 -0
  228. data/lib/codesake/dawn/kb/version_check.rb +418 -0
  229. data/lib/codesake/dawn/knowledge_base.rb +513 -0
  230. data/lib/codesake/dawn/padrino.rb +82 -0
  231. data/lib/codesake/dawn/rails.rb +17 -0
  232. data/lib/codesake/dawn/railtie.rb +9 -0
  233. data/lib/codesake/dawn/reporter.rb +280 -0
  234. data/lib/codesake/dawn/sinatra.rb +129 -0
  235. data/lib/codesake/dawn/tasks.rb +27 -0
  236. data/lib/codesake/dawn/utils.rb +21 -0
  237. data/lib/codesake/dawn/version.rb +28 -0
  238. data/lib/tasks/codesake-dawn_tasks.rake +1 -0
  239. data/spec/lib/dawn/codesake_core_spec.rb +9 -0
  240. data/spec/lib/dawn/codesake_knowledgebase_spec.rb +940 -0
  241. data/spec/lib/dawn/codesake_padrino_engine_disabled.rb +45 -0
  242. data/spec/lib/dawn/codesake_rails_engine_disabled.rb +12 -0
  243. data/spec/lib/dawn/codesake_sinatra_engine_disabled.rb +128 -0
  244. data/spec/lib/kb/codesake_cve_2013_0175_spec.rb +35 -0
  245. data/spec/lib/kb/codesake_cve_2013_4457_spec.rb +41 -0
  246. data/spec/lib/kb/codesake_dependency_version_check_spec.rb +76 -0
  247. data/spec/lib/kb/codesake_deprecation_check_spec.rb +56 -0
  248. data/spec/lib/kb/codesake_ruby_version_check_spec.rb +40 -0
  249. data/spec/lib/kb/codesake_version_check_spec.rb +165 -0
  250. data/spec/lib/kb/cve_2011_2705_spec.rb +35 -0
  251. data/spec/lib/kb/cve_2011_2930_spec.rb +31 -0
  252. data/spec/lib/kb/cve_2011_3009_spec.rb +25 -0
  253. data/spec/lib/kb/cve_2011_3187_spec.rb +24 -0
  254. data/spec/lib/kb/cve_2011_4319_spec.rb +44 -0
  255. data/spec/lib/kb/cve_2011_5036_spec.rb +95 -0
  256. data/spec/lib/kb/cve_2012_1098_spec.rb +36 -0
  257. data/spec/lib/kb/cve_2012_2139_spec.rb +20 -0
  258. data/spec/lib/kb/cve_2012_2671_spec.rb +23 -0
  259. data/spec/lib/kb/cve_2012_6109_spec.rb +112 -0
  260. data/spec/lib/kb/cve_2013_0162_spec.rb +23 -0
  261. data/spec/lib/kb/cve_2013_0183_spec.rb +54 -0
  262. data/spec/lib/kb/cve_2013_0184_spec.rb +115 -0
  263. data/spec/lib/kb/cve_2013_0256_spec.rb +34 -0
  264. data/spec/lib/kb/cve_2013_0262_spec.rb +44 -0
  265. data/spec/lib/kb/cve_2013_0263_spec.rb +11 -0
  266. data/spec/lib/kb/cve_2013_1607_spec.rb +15 -0
  267. data/spec/lib/kb/cve_2013_1655_spec.rb +31 -0
  268. data/spec/lib/kb/cve_2013_1756_spec.rb +23 -0
  269. data/spec/lib/kb/cve_2013_2090_spec.rb +15 -0
  270. data/spec/lib/kb/cve_2013_2105_spec.rb +11 -0
  271. data/spec/lib/kb/cve_2013_2119_spec.rb +27 -0
  272. data/spec/lib/kb/cve_2013_2512_spec.rb +15 -0
  273. data/spec/lib/kb/cve_2013_2513_spec.rb +15 -0
  274. data/spec/lib/kb/cve_2013_2516_spec.rb +15 -0
  275. data/spec/lib/kb/cve_2013_4203_spec.rb +15 -0
  276. data/spec/lib/kb/cve_2013_4413_spec.rb +16 -0
  277. data/spec/lib/kb/cve_2013_4489_spec.rb +63 -0
  278. data/spec/lib/kb/cve_2013_4593_spec.rb +16 -0
  279. data/spec/lib/kb/cve_2013_5647_spec.rb +19 -0
  280. data/spec/lib/kb/cve_2013_5671_spec.rb +27 -0
  281. data/spec/lib/kb/cve_2013_6416_spec.rb +31 -0
  282. data/spec/lib/kb/cve_2013_6459_spec.rb +15 -0
  283. data/spec/lib/kb/cve_2013_7086_spec.rb +22 -0
  284. data/spec/lib/kb/cve_2014_0036_spec.rb +15 -0
  285. data/spec/lib/kb/cve_2014_0080_spec.rb +28 -0
  286. data/spec/lib/kb/cve_2014_0081_spec.rb +68 -0
  287. data/spec/lib/kb/cve_2014_0082_spec.rb +52 -0
  288. data/spec/lib/kb/cve_2014_0130_spec.rb +19 -0
  289. data/spec/lib/kb/cve_2014_1233_spec.rb +15 -0
  290. data/spec/lib/kb/cve_2014_1234_spec.rb +16 -0
  291. data/spec/lib/kb/cve_2014_2322_spec.rb +15 -0
  292. data/spec/lib/kb/cve_2014_2538_spec.rb +15 -0
  293. data/spec/lib/kb/cve_2014_3482_spec.rb +15 -0
  294. data/spec/lib/kb/cve_2014_3483_spec.rb +23 -0
  295. data/spec/lib/kb/osvdb_105971_spec.rb +15 -0
  296. data/spec/lib/kb/osvdb_108530_spec.rb +22 -0
  297. data/spec/lib/kb/osvdb_108563_spec.rb +18 -0
  298. data/spec/lib/kb/osvdb_108569_spec.rb +17 -0
  299. data/spec/lib/kb/osvdb_108570_spec.rb +17 -0
  300. data/spec/lib/kb/owasp_ror_cheatsheet_disabled.rb +56 -0
  301. data/spec/spec_helper.rb +11 -0
  302. data/support/bootstrap.js +2027 -0
  303. data/support/bootstrap.min.css +9 -0
  304. data/support/codesake.css +63 -0
  305. metadata +659 -0
  306. metadata.gz.sig +0 -0
@@ -0,0 +1,33 @@
1
+ module Codesake
2
+ module Dawn
3
+ module Kb
4
+ module OwaspRorCheatSheet
5
+
6
+ class SessionStoredInDatabase
7
+ include PatternMatchCheck
8
+
9
+ def initialize
10
+ message = "By default, Ruby on Rails uses a Cookie based session store. What that means is that unless you change something, the session will not expire on the server. That means that some default applications may be vulnerable to replay attacks. It also means that sensitive information should never be put in the session."
11
+
12
+ super({
13
+ :name=>"Owasp Ror CheatSheet: Session management",
14
+ :kind=>Codesake::Dawn::KnowledgeBase::PATTERN_MATCH_CHECK,
15
+ :applies=>["rails"],
16
+ :glob=>"session_store.rb",
17
+ :aux_links=>["https://www.owasp.org/index.php/Ruby_on_Rails_Cheatsheet"],
18
+ :message=>message,
19
+ :attack_pattern => ["Application.config.session_store :active_record_store"],
20
+ :negative_search=>true,
21
+ :avoid_comments=>true,
22
+ :check_family=>:owasp_ror_cheatsheet,
23
+ :severity=>:info,
24
+ :evidences=>["In your session_store.rb file you are not using ActiveRercord to store session data. This will let rails to use a cookie based session and it can expose your web application to a session replay attack."],
25
+ :mitigation=>"Use ActiveRecord or the ORM you love most to handle your code session_store. Add \"Application.config.session_store :active_record_store\" to your session_store.rb file."
26
+ })
27
+ # @debug = true
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,129 @@
1
+ require 'ptools'
2
+
3
+ module Codesake
4
+ module Dawn
5
+ module Kb
6
+ module PatternMatchCheck
7
+ include BasicCheck
8
+
9
+
10
+ attr_reader :attack_pattern
11
+ attr_accessor :root_dir
12
+
13
+ # This attribute is false by default. If true, the vuln? method check
14
+ # if pattern attack is nor present.
15
+ attr_reader :negative_search
16
+
17
+ # This attribute is false by default. If true, it tells pattern
18
+ # matching check to ignore strings starting with the ruby single line
19
+ # comment separator, '#'.
20
+ attr_reader :avoid_comments
21
+
22
+ # This attribute is false by default. If true, it tells pattern
23
+ # matching check that the attack pattern is already a regular
24
+ # expression.
25
+ attr_reader :attack_pattern_is_regex
26
+
27
+ EXCLUSION_LIST = [
28
+ "tags",
29
+ "vendor/bundle",
30
+ "features",
31
+ "specs",
32
+ "test"
33
+ ]
34
+
35
+ def initialize(options={})
36
+ super(options)
37
+ @negative_search = false
38
+ @avoid_comments = false
39
+ @attack_pattern_is_regex = false
40
+ @glob = "**"
41
+ @attack_pattern = options[:attack_pattern] unless options[:attack_pattern].nil?
42
+ @negative_search = options[:negative_search] unless options[:negative_search].nil?
43
+ @avoid_comments = options[:avoid_comments] unless options[:avoid_comments].nil?
44
+ @evidences = options[:evidences] unless options[:evidences].nil?
45
+ @attack_pattern_is_regex = options[:attack_pattern_is_regex] unless options[:attack_pattern_is_regex].nil?
46
+ @glob = File.join(@glob, options[:glob]) unless options[:glob].nil?
47
+ debug_me("EVIDENCES ARE #{@evidences.inspect}")
48
+ end
49
+
50
+ def must_exclude?(filename)
51
+ EXCLUSION_LIST.each do |ex|
52
+ debug_me "skipping #{filename}" if filename.start_with?(ex)
53
+ return true if filename.start_with?(ex)
54
+ end
55
+ return false
56
+ end
57
+
58
+ def vuln?
59
+ found = false
60
+ matches = nil
61
+ Dir.glob(File.join("#{root_dir}", @glob)).each do |filename|
62
+ debug_me("#{File.basename(__FILE__)}@#{__LINE__}: analyzing #{filename}: search is #{@negative_search}")
63
+ matches = []
64
+ begin
65
+ matches = run(load_file(filename)) if File.exists?(filename) && File.file?(filename) && ! File.binary?(filename) && ! must_exclude?(filename)
66
+ found = ! matches.empty?
67
+ rescue ArgumentError => e
68
+ puts "Skipping pattern match check for #{filename}: #{e.message}"
69
+ end
70
+ @evidences << {:filename=>filename, :matches=>matches} unless found
71
+ end
72
+
73
+ debug_me("FOUND IS: #{found}")
74
+ debug_me("EVIDENCES ARE: #{@evidences.inspect}")
75
+ debug_me("MATCHES: #{matches}")
76
+
77
+ ret_value = found unless @negative_search
78
+ ret_value = ! found if @negative_search
79
+
80
+ debug_me("#{File.basename(__FILE__)}@#{__LINE__}: evidences #=> #{@evidences}")
81
+ debug_me("#{File.basename(__FILE__)}@#{__LINE__}: ret_value #=> #{ret_value}")
82
+
83
+ @status = ret_value
84
+
85
+ return ret_value
86
+ end
87
+
88
+ private
89
+ def string_to_array(par)
90
+ return par if par.class == Array
91
+ %w(par)
92
+ end
93
+
94
+ def load_file(filename)
95
+
96
+ f = File.open(filename)
97
+ lines = f.readlines
98
+ f.close
99
+
100
+ lines
101
+ end
102
+
103
+ def run(lines)
104
+ hits = []
105
+
106
+ patterns = string_to_array(@attack_pattern)
107
+
108
+ patterns.each do |pat|
109
+
110
+ regex=/#{pat}/
111
+
112
+ debug_me "regex is #{regex}"
113
+ debug_me "@avoid_comments is #{@avoid_comments}"
114
+
115
+ lines.each_with_index do |line,i|
116
+ debug_me("LINE IS: #{line}")
117
+ line = "" if line.strip.start_with?('#') && @avoid_comments
118
+ hits << {:match=>line, :line=>i} unless (regex =~ line).nil?
119
+ end
120
+ end
121
+
122
+ debug_me("HITS IS: #{hits}")
123
+ hits
124
+ end
125
+
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,91 @@
1
+ module Codesake
2
+ module Dawn
3
+ module Kb
4
+ module RubyVersionCheck
5
+ include BasicCheck
6
+ # Array of hashes in the {:engine=>"ruby", :version=>"1.9.3", :patchlevel=>"p342"} form
7
+ attr_accessor :safe_rubies
8
+ # Hash in the {:engine=>"ruby", :version=>"1.9.3", :patchlevel=>"p342"} form
9
+ attr_accessor :detected_ruby
10
+
11
+ def vuln?
12
+ vv_a = []
13
+ vv_p = []
14
+ vv_e = []
15
+ vp = false
16
+ ve = false
17
+
18
+
19
+ @safe_rubies.each do |ss|
20
+ vv_e << ss[:engine]
21
+ vv_a << ss[:version]
22
+ vv_p << ss[:patchlevel].split("p")[1].to_i
23
+ end
24
+
25
+ version_check = Codesake::Dawn::Kb::VersionCheck.new(:safe=>vv_a,:detected=>detected_ruby[:version], :debug=>@debug, :save_major=>true)
26
+
27
+ vengine = self.is_vulnerable_engine?(detected_ruby[:engine], vv_e)
28
+ vv = version_check.vuln?
29
+
30
+ ve = self.is_same_version?(detected_ruby[:version], vv_a)
31
+ vp = is_vulnerable_patchlevel?(detected_ruby[:version], detected_ruby[:patchlevel])
32
+
33
+ debug_me("#{__FILE__}@#{__LINE__}: check: #{self.name}, engine is vulnerable?=#{vengine}, version is vulnerable?=#{vv}, is same version?=#{ve}, is_vulnerable_patchlevel?=#{vp}->#{vv && vengine}, #{(ve && vp && vengine )}")
34
+ debug_me("#{__FILE__}@#{__LINE__}: safe ruby is: #{@safe_rubies}")
35
+ debug_me("#{__FILE__}@#{__LINE__}: detected ruby is: #{@detected_ruby}")
36
+
37
+
38
+
39
+ if ( vv && vengine)
40
+ @status = vp if ve
41
+ @status = true unless ve
42
+ else
43
+ @status = (ve && vp && vengine )
44
+ end
45
+
46
+ debug_me("STATUS:#{@status}")
47
+ self.evidences << "#{@detected_ruby[:engine]} v#{@detected_ruby[:version]}-#{@detected_ruby[:patchlevel]} detected" if @status
48
+ return @status
49
+
50
+ # return true if ( vv && vengine )
51
+ # return (ve && vp && vengine )
52
+ end
53
+ def is_vulnerable_engine?(target, fixes = [])
54
+ fixes.each do |f|
55
+ return true if f == target
56
+ end
57
+ false
58
+ end
59
+
60
+ def is_same_version?(target, fixes = [])
61
+ fixes.each do |f|
62
+ debug_me("F=#{f}, TARGET=#{target}")
63
+ return true if f == target
64
+ end
65
+ false
66
+ end
67
+
68
+ def is_vulnerable_patchlevel?(version, patchlevel)
69
+ fixes = []
70
+ debug_me "is_vulnerable_patchlevel? called with VERSION=#{version} and PLEVEL=#{patchlevel}"
71
+ @safe_rubies.each do |ss|
72
+ fixes << ss[:patchlevel].split("p")[1].to_i if ss[:version] == version
73
+ end
74
+
75
+ debug_me "FIXES IS EMPTY" if fixes.empty?
76
+ debug_me "FIXES LIST IS #{fixes}" unless fixes.empty?
77
+ return true if fixes.empty?
78
+
79
+ t = patchlevel.split("p")[1].to_i if patchlevel.include? 'p'
80
+ t = patchlevel.to_i unless patchlevel.include? 'p'
81
+ fixes.each do |f|
82
+ debug_me "PATCHLEVEL FIXES = #{f}, PATCHLEVEL TARGET = #{t}"
83
+ return true if f > t
84
+ end
85
+ false
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+
@@ -0,0 +1,30 @@
1
+ module Codesake
2
+ module Dawn
3
+ module Kb
4
+ # Automatically created with rake on 2013-12-11
5
+ class SimpleForm_Xss_20131129
6
+ include DependencyCheck
7
+
8
+ def initialize
9
+ message = "There is a XSS vulnerability on Simple Form's label, hint and error options. When Simple Form creates a label, hint or error message it marks the text as being HTML safe, even though it may contain HTML tags. In applications where the text of these helpers can be provided by the users, malicious values can be provided and Simple Form will mark it as safe."
10
+
11
+ super({
12
+ :name=>"Simple Form XSS - 20131129",
13
+ :cvss=>"none",
14
+ :release_date => Date.new(2013, 11, 29),
15
+ :cwe=>"",
16
+ :owasp=>"A9",
17
+ :applies=>["rails", "padrino", "sinatra"],
18
+ :kind=>Codesake::Dawn::KnowledgeBase::DEPENDENCY_CHECK,
19
+ :message=>message,
20
+ :mitigation=>"Please upgrade Simple Form the 3.0.1 and 2.1.1 releases are available at the normal locations.",
21
+ :aux_links=>["https://groups.google.com/forum/#!topic/ruby-security-ann/flHbLMb07tE"]
22
+ })
23
+
24
+ self.safe_dependencies = [{:name=>"simple_form", :version=>['3.0.1', '2.1.1']}]
25
+
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,418 @@
1
+ module Codesake
2
+ module Dawn
3
+ module Kb
4
+ class VersionCheck
5
+ include BasicCheck
6
+
7
+ attr_accessor :safe
8
+ attr_accessor :deprecated
9
+ attr_accessor :excluded
10
+ attr_accessor :detected
11
+ attr_accessor :save_minor
12
+ attr_accessor :save_major
13
+ attr_reader :status
14
+ attr_accessor :enable_warning
15
+
16
+
17
+ def initialize(options={})
18
+ super(options)
19
+ @safe ||= options[:safe]
20
+ @deprecated ||= options[:deprecated]
21
+ @excluded ||= options[:excluded]
22
+ @detected ||= options[:detected]
23
+ @save_minor ||= options[:save_minor]
24
+ @save_major ||= options[:save_major]
25
+ @debug ||= options[:debug]
26
+ @enable_warning ||= options[:enable_warning]
27
+ debug_me "VersionCheck initialized"
28
+ end
29
+
30
+ def vuln?
31
+ debug_me "Detected version is #{@detected}"
32
+ debug_me "Safe versions array is #{@safe}"
33
+ debug_me "Deprecated versions array is #{@deprecated}. I'll mark them as vulnerable" unless @deprecated.nil?
34
+ debug_me "Excluded versions array is #{@excluded}. I'll mark them as not vulnerable" unless @excluded.nil?
35
+
36
+ @status = :deprecated if is_detected_deprecated?
37
+ return debug_me_and_return_false("detected version #{detected} is marked to be excluded for vulnerable ones") if is_detected_excluded?
38
+
39
+ # is the detected version in the safe array?
40
+ return debug_me_and_return_false("detected version #{@detected} found as is in safe array") if is_detected_in_safe?
41
+ return debug_me_and_return_false("detected version #{@detected} is higher than all version marked safe") if is_detected_highest?
42
+
43
+ @safe.sort.each do |s|
44
+
45
+ @save_minor_fix = save_minor_fix
46
+ @save_major_fix = save_major_fix
47
+
48
+
49
+ vuln = is_vulnerable_version?(s, @detected)
50
+
51
+ debug_me "VULN=#{vuln} SAVE_MINOR=#{@save_minor_fix} SAVE_MAJOR=#{@save_major_fix}"
52
+ return true if vuln
53
+ end
54
+
55
+ return false
56
+ end
57
+
58
+ def is_detected_in_safe?
59
+ @safe.each do |s|
60
+ return true if @detected == s
61
+ end
62
+ return false
63
+ end
64
+
65
+ def is_detected_highest?
66
+ higher= @detected
67
+ @safe.sort.each do |s|
68
+ debug_me("higher is #{higher}")
69
+ higher=s if is_higher?(s, higher)
70
+ end
71
+ return (higher == @detected)
72
+ end
73
+ def is_detected_deprecated?
74
+ return is_deprecated?(@detected)
75
+ end
76
+ def is_detected_excluded?
77
+ return is_excluded?(@detected)
78
+ end
79
+
80
+ def is_higher_major?(s,d)
81
+ sa = version_string_to_array(s)[:version]
82
+ da = version_string_to_array(d)[:version]
83
+ return (sa[0] > da[0])
84
+ end
85
+
86
+ # Public: tells if a version is higher than another
87
+ #
88
+ # e.g.
89
+ # is_higher?('2.3.2', '2.4.2') => true
90
+ # is_higher?('2.3.2', '2.3.2') => true
91
+ def is_higher?(a, b)
92
+ aa = version_string_to_array(a)
93
+ ba = version_string_to_array(b)
94
+
95
+ ver = false
96
+ beta = false
97
+ rc = false
98
+ same = false
99
+
100
+ # Version arrays are just major.minor version. Let's assume
101
+ # patchlevel is 0 for sake of comparison.
102
+ aa[:version] << 0 if aa[:version].count == 2
103
+ ba[:version] << 0 if ba[:version].count == 2
104
+ ver = true if aa[:version][0] > ba[:version][0]
105
+ ver = true if aa[:version][0] == ba[:version][0] && aa[:version][1] > ba[:version][1]
106
+ 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]
107
+ 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]
108
+ 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]
109
+ same = is_same_version?(aa[:version], ba[:version])
110
+ beta = true if aa[:beta] >= ba[:beta]
111
+ rc = true if aa[:rc] >= ba[:rc]
112
+
113
+ ret = false
114
+ ret = ver && beta && rc unless same
115
+ ret = beta && rc if same
116
+
117
+ debug_me("is_higher? a=#{a}, b=#{b} VER=#{ver} - BETA=#{beta} - RC=#{rc} - SAME=#{same} - a>b? = (#{ret})")
118
+ return ret
119
+ end
120
+
121
+ # checks in the array if there is another string with higher major version
122
+ def is_there_an_higher_major_version?
123
+ dva = version_string_to_array(@detected)[:version]
124
+ @safe.sort.each do |s|
125
+ sva = version_string_to_array(s)[:version]
126
+ debug_me "is_there_an_higher_major_version? DVA=#{dva} - SVA=#{sva}"
127
+ return debug_me_and_return_true("is_there_an_higher_major_version? is returning true for #{@detected}") if dva[0] < sva[0]
128
+ end
129
+ return debug_me_and_return_false("is_there_an_higher_major_version? is returning false")
130
+ end
131
+
132
+ # checks in the array if there is another string with higher minor version but the same major as the parameter element)
133
+ def is_there_an_higher_minor_version?
134
+ dva = version_string_to_array(@detected)[:version]
135
+ @safe.sort.each do |s|
136
+ sva = version_string_to_array(s)[:version]
137
+ return true if dva[0] == sva[0] && dva[1] < sva[1]
138
+ end
139
+ return false
140
+ end
141
+
142
+ def save_major_fix
143
+ return false unless @save_major
144
+ return is_there_an_higher_major_version?
145
+ end
146
+ ##
147
+ # This functions handles an hack to save a detected version even if a
148
+ # safe version with an higher minor version number has been found.
149
+ #
150
+ # This is mostly used in rails where there are different versions and
151
+ # if a 3.2.12 is safe it should not marked as vulnerable just because
152
+ # you can either use 3.3.x that is a different branch.
153
+ #
154
+ # It returns true when the detected version must be saved, false otherwise.
155
+ def save_minor_fix
156
+ return false unless @save_minor
157
+ hm = is_there_an_higher_minor_version?
158
+
159
+ # This is the save minor version workaround.
160
+ # fixes is something like ['2.2.2', '3.1.1', '3.2.2']
161
+ # target is '3.1.1' and save_minor_fixes is true
162
+ # I don't want that check for 3.2.2 marks this as vulnerable, so I will save it
163
+ dva = version_string_to_array(@detected)[:version]
164
+ @safe.sort.each do |s|
165
+ sva = version_string_to_array(s)[:version]
166
+ return true if is_same_major?(sva, dva) && is_same_minor?(sva, dva) && dva[2] >= sva[2] && hm
167
+ end
168
+ return false
169
+ end
170
+
171
+ def is_good_parameter?(array)
172
+ return false if array.nil?
173
+ return false if array.empty?
174
+ return true
175
+ end
176
+ ##
177
+ # It checks if the first digit of a version array is the same
178
+ #
179
+ # e.g.
180
+ # has_same_major?([2,3,3], [1,2,2]) #=> false
181
+ # has_same_major?([2,3,3], [2,2,2]) #=> true
182
+ def is_same_major?(array_a, array_b)
183
+ return false if ! is_good_parameter?(array_a) || ! is_good_parameter?(array_b)
184
+ return (array_a[0] == array_b[0])
185
+ end
186
+ def is_same_minor?(array_a, array_b)
187
+ return false if ! is_good_parameter?(array_a) || ! is_good_parameter?(array_b)
188
+ return (array_a[1] == array_b[1])
189
+ end
190
+ def is_same_patch?(array_a, array_b)
191
+ return false if ! is_good_parameter?(array_a) || ! is_good_parameter?(array_b)
192
+ return (array_a[2] == array_b[2])
193
+ end
194
+
195
+ def is_vulnerable_major?(safe_version, detected_version)
196
+ return (safe_version[0] > detected_version[0])
197
+ end
198
+
199
+ def is_vulnerable_patch?(safe_version, detected_version)
200
+ return false if safe_version[2].nil? || detected_version[2].nil?
201
+ return (safe_version[2] > detected_version[2])
202
+ end
203
+ def is_vulnerable_aux_patch?(safe_version, detected_version)
204
+ return false if safe_version[3].nil? || detected_version[3].nil?
205
+ return (safe_version[3] > detected_version[3])
206
+ end
207
+
208
+
209
+ def is_vulnerable_minor?(safe_version, detected_version)
210
+ if safe_version.length < detected_version.length
211
+ # safe version is just the major number e.g. 2
212
+ # detected version is kinda more complex e.g. 2.3.2 or 1.2.3
213
+ # we relay on major here
214
+ return is_vulnerable_major?(safe_version, detected_version)
215
+ end
216
+ if safe_version.length > detected_version.length
217
+ # detected version is just the major number e.g. 2
218
+ # safe version is kinda more complex e.g. 2.3.2
219
+ # in this case we return the version is vulnerable if the
220
+ # detected_version major is less or equal the safe one.
221
+ return (safe_version[0] <= detected_version[0])
222
+ end
223
+
224
+ # support for x as safe minor version
225
+ return false if is_same_major?(safe_version, detected_version) && safe_version[1] == 'x'
226
+ return false if safe_version[0] <= detected_version[0] && safe_version[1] == 'x'
227
+ return true if safe_version[0] > detected_version[0] && safe_version[1] == 'x'
228
+ return true if safe_version[1] > detected_version[1]
229
+ return false if safe_version[1] <= detected_version[1]
230
+ end
231
+
232
+ def is_same_version?(safe_version_array, detected_version_array)
233
+ ret = false
234
+
235
+ ret = true if (safe_version_array[0] == detected_version_array[0]) if (safe_version_array[1] == 'x')
236
+ 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)
237
+ 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)
238
+ 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)
239
+
240
+ debug_me "is_same_version? SVA=#{safe_version_array} DVA=#{detected_version_array} RET=#{ret}"
241
+
242
+ return ret
243
+ end
244
+ #########################
245
+ # Beta version handling
246
+ #
247
+ #########################
248
+
249
+ def is_beta_check?(safe_version_beta, detected_version_beta)
250
+ ( safe_version_beta != 0 || detected_version_beta != 0)
251
+ end
252
+
253
+ def is_vulnerable_beta?(safe_version_beta, detected_version_beta)
254
+ # if the safe_version_beta is 0 then the detected_version_beta is
255
+ # vulnerable by design, since the safe version is a stable and we
256
+ # detected a beta.
257
+ return true if safe_version_beta == 0 && detected_version_beta != 0
258
+ return false if safe_version_beta <= detected_version_beta
259
+ return true if safe_version_beta > detected_version_beta
260
+
261
+ # fallback
262
+ return false
263
+ end
264
+
265
+ #########################
266
+ # Rc version handling
267
+ #
268
+ #########################
269
+
270
+ def is_rc_check?(safe_version_rc, detected_version_rc)
271
+ ( safe_version_rc != 0 || detected_version_rc != 0)
272
+ end
273
+
274
+ def is_vulnerable_rc?(safe_version_rc, detected_version_rc)
275
+ # if the safe_version_rc is 0 then the detected_version_rc is
276
+ # vulnerable by design, since the safe version is a stable and we
277
+ # detected a rc.
278
+ debug_me "entering is_vulnerable_rc?: s=#{safe_version_rc}, d=#{detected_version_rc}"
279
+ return true if safe_version_rc == 0 && detected_version_rc != 0
280
+ return false if safe_version_rc != 0 && detected_version_rc == 0
281
+ return false if safe_version_rc <= detected_version_rc
282
+ return true if safe_version_rc > detected_version_rc
283
+
284
+ # fallback
285
+ return false
286
+ end
287
+
288
+ #########################
289
+ # pre version handling
290
+ #
291
+ #########################
292
+
293
+ def is_pre_check?(safe_version_pre, detected_version_pre)
294
+ ( safe_version_pre != 0 || detected_version_pre != 0)
295
+ end
296
+
297
+ def is_vulnerable_pre?(safe_version_pre, detected_version_pre)
298
+ # if the safe_version_pre is 0 then the detected_version_pre is
299
+ # vulnerable by design, since the safe version is a stable and we
300
+ # detected a pre.
301
+ return true if safe_version_pre == 0 && detected_version_pre != 0
302
+ return false if safe_version_pre <= detected_version_pre
303
+ return true if safe_version_pre > detected_version_pre
304
+
305
+ # fallback
306
+ return false
307
+ end
308
+
309
+ def is_vulnerable_version?(safe_version, detected_version)
310
+ sva = version_string_to_array(safe_version)
311
+ dva = version_string_to_array(detected_version)
312
+ safe_version_array = sva[:version]
313
+ detected_version_array = dva[:version]
314
+
315
+ safe_version_array << 0 if safe_version_array.count == 2
316
+ detected_version_array << 0 if detected_version_array.count == 2
317
+
318
+ major = is_vulnerable_major?(safe_version_array, detected_version_array)
319
+ minor = is_vulnerable_minor?(safe_version_array, detected_version_array)
320
+ patch = is_vulnerable_patch?(safe_version_array, detected_version_array)
321
+ aux_patch = is_vulnerable_aux_patch?(safe_version_array, detected_version_array)
322
+
323
+ debug_me "is_vulnerable_version? S=#{safe_version},D=#{detected_version} -> MAJOR=#{major} MINOR=#{minor} PATCH=#{patch} AUX_PATCH=#{aux_patch} SAVE_MINOR=#{@save_minor_fix} SAVE_MAJOR=#{@save_major_fix}"
324
+
325
+ return is_vulnerable_beta?(sva[:beta], dva[:beta]) if is_same_version?(safe_version_array, detected_version_array) && is_beta_check?(sva[:beta], dva[:beta])
326
+ return is_vulnerable_rc?(sva[:rc], dva[:rc]) if is_same_version?(safe_version_array, detected_version_array) && is_rc_check?(sva[:rc], dva[:rc])
327
+ return is_vulnerable_pre?(sva[:pre], dva[:pre]) if is_same_version?(safe_version_array, detected_version_array) && is_pre_check?(sva[:pre], dva[:pre])
328
+
329
+ # we have a non vulnerable major, but the minor is and there is an higher version in array
330
+ # eg. we detected v1.3.2, safe version is 1.3.3 and there is also a safe 2.x.x
331
+ return debug_me_and_return_false("#{detected_version} has a major version vulnerable but honoring save_major_fix") if major && @save_major_fix
332
+ return debug_me_and_return_false("#{detected_version} has a minor version vulnerable but honoring save_minor_fix") if minor && @save_minor_fix
333
+ return true if major && minor
334
+ return true if ! major && minor && patch && ! @save_major_fix && ! @save_minor_fix
335
+ return true if major && !@save_major_fix
336
+ return true if !major && minor && @save_major_fix
337
+ return patch if is_same_major?(safe_version_array, detected_version_array) && is_same_minor?(safe_version_array, detected_version_array) && !aux_patch
338
+ 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)
339
+ return true if is_same_major?(safe_version_array, detected_version_array) && is_same_minor?(safe_version_array, detected_version_array) && patch && aux_patch
340
+ return true if is_same_major?(safe_version_array, detected_version_array) && minor
341
+
342
+ return false
343
+ end
344
+
345
+ def is_excluded?(detected_version)
346
+ return false if detected_version.nil?
347
+ return false if @excluded.nil?
348
+ @excluded.each do |exc|
349
+ exc_v = version_string_to_array(exc)[:version]
350
+ det_v = version_string_to_array(detected_version)[:version]
351
+ return true if is_same_version?(exc_v, det_v)
352
+ end
353
+ return false
354
+ end
355
+ def is_deprecated?(detected_version)
356
+ return false if detected_version.nil?
357
+ return false if @deprecated.nil?
358
+ @deprecated.each do |dep|
359
+ dep_v = version_string_to_array(dep)[:version]
360
+ det_v = version_string_to_array(detected_version)[:version]
361
+ return true if is_same_version?(dep_v, det_v)
362
+ if dep_v[0] == 'x'
363
+ # deprecation version is something like 'x.0.0'. This is a
364
+ # nonsense since it means all versions are deprecated. However
365
+ # I'll support also nonsense checks.
366
+
367
+ $logger.warn "Setting the predicate #{dep} will mark all versions as deprecated" unless self.enable_warning.nil?
368
+ debug_me "You kindly mark #{detected_version} as deprecated with this predicate #{dep}"
369
+ return true
370
+ end
371
+
372
+ if dep_v[1] == 'x'
373
+ # deprecation version is something like 1.x
374
+ # detected version is deprecated if major == 1. If 0 not
375
+ return true if det_v[0] == dep_v[0]
376
+ end
377
+
378
+ if dep_v[2] == 'x'
379
+ # deprecation version is something like 1.2.x
380
+ # detected version is deprecated if major == 1 and minor == 2.
381
+ return true if det_v[0] == dep_v[0] && det_v[1] == dep_v[1]
382
+
383
+ end
384
+ end
385
+ false
386
+ end
387
+
388
+
389
+ ##
390
+ # It takes a string representing a version and it splits it in an Hash.
391
+ #
392
+ # e.g.
393
+ # version_string_to_array("3.2.3") #=> {:version=>[3,2,3], :beta=>0, :rc=>0}
394
+ # version_string_to_array("3.2.2.beta1") #=> {:version=>[3,2,2], :beta=>1, :rc=>0}
395
+ def version_string_to_array(string)
396
+ # I can't use this nice onliner... stays here until I finish writing new code.
397
+ # return string.split(".").map! { |n| (n=='x')? n : n.to_i }
398
+ ver = []
399
+ beta = 0
400
+ rc = 0
401
+ pre = 0
402
+
403
+ string.split(".").each do |x|
404
+ ver << x.to_i unless x == 'x' || x.start_with?('beta') || x.start_with?('rc') || x.start_with?('pre')
405
+ ver << x if x == 'x'
406
+
407
+ beta = x.split("beta")[1].to_i if x.class == String && x.start_with?('beta') && beta == 0
408
+ rc = x.split("rc")[1].to_i if x.class == String && x.start_with?('rc') && rc == 0
409
+ pre = x.split("pre")[1].to_i if x.class == String && x.start_with?('pre') && pre == 0
410
+
411
+ end
412
+ {:version=>ver, :beta=>beta, :rc=>rc, :pre=>pre}
413
+ end
414
+
415
+ end
416
+ end
417
+ end
418
+ end