dawnscanner 1.2.99
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +4 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +19 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +8 -0
- data/Changelog.md +412 -0
- data/Gemfile +4 -0
- data/KnowledgeBase.md +213 -0
- data/LICENSE.txt +22 -0
- data/README.md +354 -0
- data/Rakefile +250 -0
- data/Roadmap.md +59 -0
- data/bin/dawn +210 -0
- data/certs/paolo_at_codesake_dot_com.pem +21 -0
- data/checksum/.placeholder +0 -0
- data/checksum/codesake-dawn-1.1.0.gem.sha512 +1 -0
- data/checksum/codesake-dawn-1.1.0.rc1.gem.sha512 +1 -0
- data/checksum/codesake-dawn-1.1.1.gem.sha512 +1 -0
- data/checksum/codesake-dawn-1.1.2.gem.sha512 +1 -0
- data/checksum/codesake-dawn-1.1.3.gem.sha512 +1 -0
- data/checksum/codesake-dawn-1.2.0.gem.sha512 +1 -0
- data/checksum/codesake-dawn-1.2.99.gem.sha512 +1 -0
- data/dawnscanner.gemspec +43 -0
- data/doc/codesake-dawn.yaml.sample +26 -0
- data/doc/dawn_1_0_announcement.md +139 -0
- data/doc/dawn_1_1_announcement.md +67 -0
- data/doc/dawn_1_2_announcement.md +69 -0
- data/features/dawn_complains_about_an_incorrect_command_line.feature.disabled +21 -0
- data/features/dawn_scan_a_secure_sinatra_app.feature.disabled +31 -0
- data/features/dawn_scan_a_vulnerable_sinatra_app.feature.disabled +36 -0
- data/features/step_definition/dawn_steps.rb +19 -0
- data/features/support/env.rb +1 -0
- data/lib/codesake-dawn.rb +12 -0
- data/lib/codesake/dawn/core.rb +175 -0
- data/lib/codesake/dawn/engine.rb +380 -0
- data/lib/codesake/dawn/gemfile_lock.rb +12 -0
- data/lib/codesake/dawn/kb/basic_check.rb +228 -0
- data/lib/codesake/dawn/kb/combo_check.rb +64 -0
- data/lib/codesake/dawn/kb/cve_2004_0755.rb +32 -0
- data/lib/codesake/dawn/kb/cve_2004_0983.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2005_1992.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2005_2337.rb +32 -0
- data/lib/codesake/dawn/kb/cve_2006_1931.rb +32 -0
- data/lib/codesake/dawn/kb/cve_2006_2582.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2006_3694.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2006_4112.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2006_5467.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2006_6303.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2006_6852.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2006_6979.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2007_0469.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2007_5162.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2007_5379.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2007_5380.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2007_5770.rb +32 -0
- data/lib/codesake/dawn/kb/cve_2007_6077.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2007_6612.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2008_1145.rb +40 -0
- data/lib/codesake/dawn/kb/cve_2008_1891.rb +40 -0
- data/lib/codesake/dawn/kb/cve_2008_2376.rb +32 -0
- data/lib/codesake/dawn/kb/cve_2008_2662.rb +35 -0
- data/lib/codesake/dawn/kb/cve_2008_2663.rb +34 -0
- data/lib/codesake/dawn/kb/cve_2008_2664.rb +35 -0
- data/lib/codesake/dawn/kb/cve_2008_2725.rb +33 -0
- data/lib/codesake/dawn/kb/cve_2008_3655.rb +39 -0
- data/lib/codesake/dawn/kb/cve_2008_3657.rb +39 -0
- data/lib/codesake/dawn/kb/cve_2008_3790.rb +32 -0
- data/lib/codesake/dawn/kb/cve_2008_3905.rb +38 -0
- data/lib/codesake/dawn/kb/cve_2008_4094.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2008_4310.rb +103 -0
- data/lib/codesake/dawn/kb/cve_2008_5189.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2008_7248.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2009_4078.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2009_4124.rb +32 -0
- data/lib/codesake/dawn/kb/cve_2009_4214.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2010_1330.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2010_2489.rb +62 -0
- data/lib/codesake/dawn/kb/cve_2010_3933.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2011_0188.rb +69 -0
- data/lib/codesake/dawn/kb/cve_2011_0446.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2011_0447.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2011_0739.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2011_0995.rb +63 -0
- data/lib/codesake/dawn/kb/cve_2011_1004.rb +36 -0
- data/lib/codesake/dawn/kb/cve_2011_1005.rb +33 -0
- data/lib/codesake/dawn/kb/cve_2011_2197.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2011_2686.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2011_2705.rb +34 -0
- data/lib/codesake/dawn/kb/cve_2011_2929.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2011_2930.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2011_2931.rb +32 -0
- data/lib/codesake/dawn/kb/cve_2011_2932.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2011_3009.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2011_3186.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2011_3187.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2011_4319.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2011_4815.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2011_5036.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2012_1098.rb +32 -0
- data/lib/codesake/dawn/kb/cve_2012_1099.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_1241.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_2139.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2012_2140.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_2660.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2012_2661.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_2671.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2012_2694.rb +32 -0
- data/lib/codesake/dawn/kb/cve_2012_2695.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_3424.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2012_3463.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_3464.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_3465.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2012_4464.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_4466.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_4481.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2012_4522.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_5370.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_5371.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_5380.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2012_6109.rb +27 -0
- data/lib/codesake/dawn/kb/cve_2012_6134.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_6496.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2012_6497.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_0155.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2013_0156.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_0162.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_0175.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_0183.rb +27 -0
- data/lib/codesake/dawn/kb/cve_2013_0184.rb +27 -0
- data/lib/codesake/dawn/kb/cve_2013_0233.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_0256.rb +61 -0
- data/lib/codesake/dawn/kb/cve_2013_0262.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_0263.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_0269.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_0276.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_0277.rb +27 -0
- data/lib/codesake/dawn/kb/cve_2013_0284.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_0285.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_0333.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_1607.rb +27 -0
- data/lib/codesake/dawn/kb/cve_2013_1655.rb +67 -0
- data/lib/codesake/dawn/kb/cve_2013_1656.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_1756.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_1800.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_1801.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_1802.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_1812.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_1821.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_1854.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_1855.rb +27 -0
- data/lib/codesake/dawn/kb/cve_2013_1856.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_1857.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_1875.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_1898.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_1911.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_1933.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_1947.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_1948.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_2065.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2013_2090.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_2105.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_2119.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_2512.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_2513.rb +27 -0
- data/lib/codesake/dawn/kb/cve_2013_2516.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_2615.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_2616.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_2617.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_3221.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_4164.rb +32 -0
- data/lib/codesake/dawn/kb/cve_2013_4203.rb +27 -0
- data/lib/codesake/dawn/kb/cve_2013_4389.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_4413.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_4457.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2013_4478.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_4479.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_4489.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_4491.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_4492.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2013_4562.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_4593.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_5647.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2013_5671.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2013_6414.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2013_6415.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_6416.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2013_6417.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2013_6421.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_6459.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2013_6460.rb +55 -0
- data/lib/codesake/dawn/kb/cve_2013_6461.rb +59 -0
- data/lib/codesake/dawn/kb/cve_2013_7086.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2014_0036.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2014_0080.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2014_0081.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2014_0082.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2014_0130.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2014_1233.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2014_1234.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2014_2322.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2014_2525.rb +61 -0
- data/lib/codesake/dawn/kb/cve_2014_2538.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2014_3482.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2014_3483.rb +29 -0
- data/lib/codesake/dawn/kb/dependency_check.rb +86 -0
- data/lib/codesake/dawn/kb/deprecation_check.rb +40 -0
- data/lib/codesake/dawn/kb/not_revised_code.rb +24 -0
- data/lib/codesake/dawn/kb/operating_system_check.rb +98 -0
- data/lib/codesake/dawn/kb/osvdb_105971.rb +31 -0
- data/lib/codesake/dawn/kb/osvdb_108530.rb +29 -0
- data/lib/codesake/dawn/kb/osvdb_108563.rb +30 -0
- data/lib/codesake/dawn/kb/osvdb_108569.rb +30 -0
- data/lib/codesake/dawn/kb/osvdb_108570.rb +29 -0
- data/lib/codesake/dawn/kb/owasp_ror_cheatsheet.rb +41 -0
- data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/check_for_backup_files.rb +22 -0
- data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/check_for_safe_redirect_and_forward.rb +59 -0
- data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/command_injection.rb +30 -0
- data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/csrf.rb +31 -0
- data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/mass_assignment_in_model.rb +35 -0
- data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/security_related_headers.rb +38 -0
- data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/sensitive_files.rb +31 -0
- data/lib/codesake/dawn/kb/owasp_ror_cheatsheet/session_stored_in_database.rb +33 -0
- data/lib/codesake/dawn/kb/pattern_match_check.rb +129 -0
- data/lib/codesake/dawn/kb/ruby_version_check.rb +91 -0
- data/lib/codesake/dawn/kb/simpleform_xss_20131129.rb +30 -0
- data/lib/codesake/dawn/kb/version_check.rb +418 -0
- data/lib/codesake/dawn/knowledge_base.rb +513 -0
- data/lib/codesake/dawn/padrino.rb +82 -0
- data/lib/codesake/dawn/rails.rb +17 -0
- data/lib/codesake/dawn/railtie.rb +9 -0
- data/lib/codesake/dawn/reporter.rb +280 -0
- data/lib/codesake/dawn/sinatra.rb +129 -0
- data/lib/codesake/dawn/tasks.rb +27 -0
- data/lib/codesake/dawn/utils.rb +21 -0
- data/lib/codesake/dawn/version.rb +28 -0
- data/lib/tasks/codesake-dawn_tasks.rake +1 -0
- data/spec/lib/dawn/codesake_core_spec.rb +9 -0
- data/spec/lib/dawn/codesake_knowledgebase_spec.rb +940 -0
- data/spec/lib/dawn/codesake_padrino_engine_disabled.rb +45 -0
- data/spec/lib/dawn/codesake_rails_engine_disabled.rb +12 -0
- data/spec/lib/dawn/codesake_sinatra_engine_disabled.rb +128 -0
- data/spec/lib/kb/codesake_cve_2013_0175_spec.rb +35 -0
- data/spec/lib/kb/codesake_cve_2013_4457_spec.rb +41 -0
- data/spec/lib/kb/codesake_dependency_version_check_spec.rb +76 -0
- data/spec/lib/kb/codesake_deprecation_check_spec.rb +56 -0
- data/spec/lib/kb/codesake_ruby_version_check_spec.rb +40 -0
- data/spec/lib/kb/codesake_version_check_spec.rb +165 -0
- data/spec/lib/kb/cve_2011_2705_spec.rb +35 -0
- data/spec/lib/kb/cve_2011_2930_spec.rb +31 -0
- data/spec/lib/kb/cve_2011_3009_spec.rb +25 -0
- data/spec/lib/kb/cve_2011_3187_spec.rb +24 -0
- data/spec/lib/kb/cve_2011_4319_spec.rb +44 -0
- data/spec/lib/kb/cve_2011_5036_spec.rb +95 -0
- data/spec/lib/kb/cve_2012_1098_spec.rb +36 -0
- data/spec/lib/kb/cve_2012_2139_spec.rb +20 -0
- data/spec/lib/kb/cve_2012_2671_spec.rb +23 -0
- data/spec/lib/kb/cve_2012_6109_spec.rb +112 -0
- data/spec/lib/kb/cve_2013_0162_spec.rb +23 -0
- data/spec/lib/kb/cve_2013_0183_spec.rb +54 -0
- data/spec/lib/kb/cve_2013_0184_spec.rb +115 -0
- data/spec/lib/kb/cve_2013_0256_spec.rb +34 -0
- data/spec/lib/kb/cve_2013_0262_spec.rb +44 -0
- data/spec/lib/kb/cve_2013_0263_spec.rb +11 -0
- data/spec/lib/kb/cve_2013_1607_spec.rb +15 -0
- data/spec/lib/kb/cve_2013_1655_spec.rb +31 -0
- data/spec/lib/kb/cve_2013_1756_spec.rb +23 -0
- data/spec/lib/kb/cve_2013_2090_spec.rb +15 -0
- data/spec/lib/kb/cve_2013_2105_spec.rb +11 -0
- data/spec/lib/kb/cve_2013_2119_spec.rb +27 -0
- data/spec/lib/kb/cve_2013_2512_spec.rb +15 -0
- data/spec/lib/kb/cve_2013_2513_spec.rb +15 -0
- data/spec/lib/kb/cve_2013_2516_spec.rb +15 -0
- data/spec/lib/kb/cve_2013_4203_spec.rb +15 -0
- data/spec/lib/kb/cve_2013_4413_spec.rb +16 -0
- data/spec/lib/kb/cve_2013_4489_spec.rb +63 -0
- data/spec/lib/kb/cve_2013_4593_spec.rb +16 -0
- data/spec/lib/kb/cve_2013_5647_spec.rb +19 -0
- data/spec/lib/kb/cve_2013_5671_spec.rb +27 -0
- data/spec/lib/kb/cve_2013_6416_spec.rb +31 -0
- data/spec/lib/kb/cve_2013_6459_spec.rb +15 -0
- data/spec/lib/kb/cve_2013_7086_spec.rb +22 -0
- data/spec/lib/kb/cve_2014_0036_spec.rb +15 -0
- data/spec/lib/kb/cve_2014_0080_spec.rb +28 -0
- data/spec/lib/kb/cve_2014_0081_spec.rb +68 -0
- data/spec/lib/kb/cve_2014_0082_spec.rb +52 -0
- data/spec/lib/kb/cve_2014_0130_spec.rb +19 -0
- data/spec/lib/kb/cve_2014_1233_spec.rb +15 -0
- data/spec/lib/kb/cve_2014_1234_spec.rb +16 -0
- data/spec/lib/kb/cve_2014_2322_spec.rb +15 -0
- data/spec/lib/kb/cve_2014_2538_spec.rb +15 -0
- data/spec/lib/kb/cve_2014_3482_spec.rb +15 -0
- data/spec/lib/kb/cve_2014_3483_spec.rb +23 -0
- data/spec/lib/kb/osvdb_105971_spec.rb +15 -0
- data/spec/lib/kb/osvdb_108530_spec.rb +22 -0
- data/spec/lib/kb/osvdb_108563_spec.rb +18 -0
- data/spec/lib/kb/osvdb_108569_spec.rb +17 -0
- data/spec/lib/kb/osvdb_108570_spec.rb +17 -0
- data/spec/lib/kb/owasp_ror_cheatsheet_disabled.rb +56 -0
- data/spec/spec_helper.rb +11 -0
- data/support/bootstrap.js +2027 -0
- data/support/bootstrap.min.css +9 -0
- data/support/codesake.css +63 -0
- metadata +659 -0
- 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
|