dawnscanner 1.2.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,36 @@
|
|
|
1
|
+
Feature: dawn reports security issues
|
|
2
|
+
When it scans a sinatra application that it is not updated and it has XSS
|
|
3
|
+
|
|
4
|
+
Scenario: dawn detects the sinatra version
|
|
5
|
+
Given a vulnerable sinatra application exists
|
|
6
|
+
When I run `bundle exec dawn /tmp/sinatra-vulnerable`
|
|
7
|
+
Then the stdout should contain "1.2.6"
|
|
8
|
+
|
|
9
|
+
Scenario: dawn tells there are no vulnerabilities
|
|
10
|
+
Given a vulnerable sinatra application exists
|
|
11
|
+
When I run `bundle exec dawn /tmp/sinatra-vulnerable`
|
|
12
|
+
Then the stdout should contain "4 vulnerabilities found"
|
|
13
|
+
And the stdout should contain "Not revised code failed"
|
|
14
|
+
And the stdout should contain "CVE-2013-0269 failed"
|
|
15
|
+
And the stdout should contain "CVE-2013-1800 failed"
|
|
16
|
+
And the stdout should contain "1 reflected XSS found"
|
|
17
|
+
And the stdout should contain "request parameter \"name\""
|
|
18
|
+
|
|
19
|
+
# Test for --output json
|
|
20
|
+
Scenario: dawn can give a brief json output as well
|
|
21
|
+
Given a vulnerable sinatra application exists
|
|
22
|
+
When I run `bundle exec dawn -s /tmp/sinatra-vulnerable --output json`
|
|
23
|
+
Then the stdout should contain "{\"status\":"OK",\"target\":"/tmp/sinatra-vulnerable",\"mvc\":"sinatra",\"mvc_version\":"1.2.6",\"vulnerabilities_count\":4,\"vulnerabilities\":["Not revised code","CVE-2013-0269","CVE-2013-1800"],\"mitigated_vuln_count\":0,\"mitigated_vuln\":[],\"reflected_xss\":["request parameter \"name\""]}"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Tests for --count-only option
|
|
27
|
+
Scenario: dawn can give just the number of issues found as output
|
|
28
|
+
Given a vulnerable sinatra application exists
|
|
29
|
+
When I run `bundle exec dawn --count-only -s /tmp/sinatra-vulnerable`
|
|
30
|
+
Then the stdout should contain "4"
|
|
31
|
+
|
|
32
|
+
Scenario: dawn can give just the number of issues found as output
|
|
33
|
+
Given a vulnerable sinatra application exists
|
|
34
|
+
When I run `bundle exec dawn --count-only -s /tmp/sinatra-vulnerable --output json`
|
|
35
|
+
Then the stdout should contain "{\"status\":"OK",\"vulnerabilities_count\":4}"
|
|
36
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Given /^the generic project "(.*?)" doesn't exist$/ do |file|
|
|
2
|
+
FileUtils.rm(file) if File.exists?(file)
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
Given /^the hello world rails project does exist$/ do
|
|
6
|
+
system("rm -rf /tmp/hello_world_3.2.13")
|
|
7
|
+
system("cp -a ./spec/support/hello_world_3.2.13 /tmp")
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
Given /^a safe sinatra application exists$/ do
|
|
11
|
+
system("rm -rf /tmp/sinatra-safe")
|
|
12
|
+
system("cp -a ./spec/support/sinatra-safe /tmp")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
Given /^a vulnerable sinatra application exists$/ do
|
|
16
|
+
system("rm -rf /tmp/sinatra-vulnerable")
|
|
17
|
+
system("cp -a ./spec/support/sinatra-vulnerable /tmp")
|
|
18
|
+
end
|
|
19
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'aruba/cucumber'
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require "codesake/dawn/utils"
|
|
2
|
+
require "codesake/dawn/core"
|
|
3
|
+
require "codesake/dawn/version"
|
|
4
|
+
require "codesake/dawn/knowledge_base"
|
|
5
|
+
require "codesake/dawn/rails"
|
|
6
|
+
require "codesake/dawn/sinatra"
|
|
7
|
+
require "codesake/dawn/padrino"
|
|
8
|
+
require "codesake/dawn/gemfile_lock"
|
|
9
|
+
require "codesake/dawn/reporter"
|
|
10
|
+
require "codesake-commons"
|
|
11
|
+
|
|
12
|
+
require "date"
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
require "yaml"
|
|
2
|
+
|
|
3
|
+
module Codesake
|
|
4
|
+
module Dawn
|
|
5
|
+
class Core
|
|
6
|
+
|
|
7
|
+
# TODO.20140326
|
|
8
|
+
# All those methods must moved from here to Util class and a
|
|
9
|
+
# Codesake::Dawn::Core namespace must be created.
|
|
10
|
+
def self.help
|
|
11
|
+
puts "Usage: dawn [options] target_directory"
|
|
12
|
+
printf "\nExamples:\n"
|
|
13
|
+
puts "\t$ dawn a_sinatra_webapp_directory"
|
|
14
|
+
puts "\t$ dawn -C the_rails_blog_engine"
|
|
15
|
+
puts "\t$ dawn -C --json a_sinatra_webapp_directory"
|
|
16
|
+
puts "\t$ dawn --ascii-tabular-report my_rails_blog_ecommerce"
|
|
17
|
+
puts "\t$ dawn --html -F my_report.html my_rails_blog_ecommerce"
|
|
18
|
+
printf "\n -r, --rails\t\t\t\t\tforce dawn to consider the target a rails application"
|
|
19
|
+
printf "\n -s, --sinatra\t\t\t\tforce dawn to consider the target a sinatra application"
|
|
20
|
+
printf "\n -p, --padrino\t\t\t\tforce dawn to consider the target a padrino application"
|
|
21
|
+
printf "\n -G, --gem-lock\t\t\t\tforce dawn to scan only for vulnerabilities affecting dependencies in Gemfile.lock"
|
|
22
|
+
printf "\n -a, --ascii-tabular-report\t\t\tcause dawn to format findings using table in ascii art"
|
|
23
|
+
printf "\n -j, --json\t\t\t\t\tcause dawn to format findings using json"
|
|
24
|
+
printf "\n -C, --count-only\t\t\t\tdawn will only count vulnerabilities (useful for scripts)"
|
|
25
|
+
printf "\n -z, --exit-on-warn\t\t\t\tdawn will return number of found vulnerabilities as exit code"
|
|
26
|
+
printf "\n -F, --file filename\t\t\t\ttells dawn to write output to filename"
|
|
27
|
+
printf "\n -c, --config-file filename\t\t\ttells dawn to load configuration from filename"
|
|
28
|
+
printf "\n\nDisable security check family\n"
|
|
29
|
+
printf "\n --disable-cve-bulletins\t\t\tdisable all CVE security checks"
|
|
30
|
+
printf "\n --disable-code-quality\t\t\tdisable all code quality checks"
|
|
31
|
+
printf "\n --disable-code-style\t\t\tdisable all code style checks"
|
|
32
|
+
printf "\n --disable-owasp-ror-cheatsheet\t\tdisable all Owasp Ruby on Rails cheatsheet checks"
|
|
33
|
+
printf "\n --disable-owasp-top-10\t\t\tdisable all Owasp Top 10 checks"
|
|
34
|
+
printf "\n\nFlags useful to query Codesake::Dawn\n"
|
|
35
|
+
printf "\n -S, --search-knowledge-base [check_name]\tsearch check_name in the knowledge base"
|
|
36
|
+
printf "\n --list-knowledge-base\t\t\tlist knowledge-base content"
|
|
37
|
+
printf "\n --list-known-families\t\t\tlist security check families contained in dawn's knowledge base"
|
|
38
|
+
printf "\n --list-known-framework\t\t\tlist ruby MVC frameworks supported by dawn"
|
|
39
|
+
printf "\n\nService flags\n"
|
|
40
|
+
printf "\n -D, --debug\t\t\t\t\tenters dawn debug mode"
|
|
41
|
+
printf "\n -V, --verbose\t\t\t\tthe output will be more verbose"
|
|
42
|
+
printf "\n -v, --version\t\t\t\tshow version information"
|
|
43
|
+
printf "\n -h, --help\t\t\t\t\tshow this help\n"
|
|
44
|
+
|
|
45
|
+
true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.dump_knowledge_base(verbose = false)
|
|
49
|
+
kb = Codesake::Dawn::KnowledgeBase.new
|
|
50
|
+
lines = []
|
|
51
|
+
lines << "Security checks currently supported:\n"
|
|
52
|
+
|
|
53
|
+
kb.all.each do |check|
|
|
54
|
+
if verbose
|
|
55
|
+
lines << "Name: #{check.name}\tCVSS: #{check.cvss_score}\tReleased: #{check.release_date}"
|
|
56
|
+
lines << "Description\n#{check.message}"
|
|
57
|
+
lines << "Remediation\n#{check.remediation}\n\n"
|
|
58
|
+
else
|
|
59
|
+
lines << "#{check.name}"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
lines << "-----\nTotal: #{kb.all.count}"
|
|
63
|
+
|
|
64
|
+
lines.empty? ? 0 : lines.compact.join("\n")
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# guess_mvc is very close to detect_mvc despite it accepts a
|
|
69
|
+
# filename as input and it tries to guess the mvc framework used from the
|
|
70
|
+
# gems it founds in Gemfile.lock without creating an engine.
|
|
71
|
+
|
|
72
|
+
def self.guess_mvc(gemfile_lock)
|
|
73
|
+
ret = {:name=>"", :version=>"", :connected_gems=>[]}
|
|
74
|
+
|
|
75
|
+
a = []
|
|
76
|
+
my_dir = Dir.pwd
|
|
77
|
+
Dir.chdir(File.dirname(gemfile_lock))
|
|
78
|
+
raise ArgumentError.new("can't read #{gemfile_lock}") unless File.readable?(File.basename(gemfile_lock))
|
|
79
|
+
|
|
80
|
+
lockfile = Bundler::LockfileParser.new(Bundler.read_file(File.basename(gemfile_lock)))
|
|
81
|
+
Dir.chdir(my_dir)
|
|
82
|
+
lockfile.specs.each do |s|
|
|
83
|
+
ret = {:name=>s.name, :version=>s.version.to_s} if s.name == "rails" || s.name == "sinatra"
|
|
84
|
+
a << {:name=>s.name, :version=>s.version.to_s}
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
ret[:connected_gems]=a
|
|
88
|
+
ret
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def self.detect_mvc(target)
|
|
93
|
+
|
|
94
|
+
raise ArgumentError.new("you must set target directory") if target.nil?
|
|
95
|
+
|
|
96
|
+
my_dir = Dir.pwd
|
|
97
|
+
Dir.chdir(target)
|
|
98
|
+
raise ArgumentError.new("no Gemfile.lock in #{target}") unless File.exist?("Gemfile.lock")
|
|
99
|
+
|
|
100
|
+
lockfile = Bundler::LockfileParser.new(Bundler.read_file("Gemfile.lock"))
|
|
101
|
+
Dir.chdir(my_dir)
|
|
102
|
+
lockfile.specs.each do |s|
|
|
103
|
+
return Codesake::Dawn::Rails.new(target) if s.name == "rails"
|
|
104
|
+
return Codesake::Dawn::Padrino.new(target) if s.name == "padrino"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
return Codesake::Dawn::Sinatra.new(target)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def self.is_good_target?(target)
|
|
111
|
+
(File.exist?(target) and File.directory?(target))
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def self.find_conf(create_if_none = false)
|
|
115
|
+
conf_name = 'codesake-dawn.yaml'
|
|
116
|
+
path_order = [
|
|
117
|
+
'./',
|
|
118
|
+
'~/',
|
|
119
|
+
'/usr/local/etc/',
|
|
120
|
+
]
|
|
121
|
+
path_order.each do |p|
|
|
122
|
+
fn = p + conf_name if p.start_with?('/')
|
|
123
|
+
# if outside $HOME the config file must be hidden
|
|
124
|
+
fn = File.expand_path(p) + '/.'+conf_name if ! p.start_with?('/')
|
|
125
|
+
return fn if File.exist?(fn)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Codesake::Dawn didn't find a config file.
|
|
129
|
+
# If create_if_none flag is set to false, than I'll return nil so the
|
|
130
|
+
# read_conf method will return the default configuration
|
|
131
|
+
return nil unless create_if_none
|
|
132
|
+
|
|
133
|
+
# If create_if_none flag is set to true, than I'll create a config file
|
|
134
|
+
# on the current directory with the default configuration.
|
|
135
|
+
conf = {"config"=>{:verbose=>false, :output=>"console", :mvc=>"", :gemfile_scan=>false, :gemfile_name=>"", :filename=>nil, :debug=>false, :exit_on_warn => false, :enabled_checks=> Codesake::Dawn::Kb::BasicCheck::ALLOWED_FAMILIES}}
|
|
136
|
+
|
|
137
|
+
# Calculate the conf file path
|
|
138
|
+
conf_path = File.expand_path('~') +'/.'+conf_name
|
|
139
|
+
|
|
140
|
+
# Open the conf file and write our default config to it
|
|
141
|
+
File.open(conf_path, 'w') do |f|
|
|
142
|
+
rv = f.write(YAML.dump(conf))
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
conf_path
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def self.read_conf(file=nil)
|
|
149
|
+
conf = {:verbose=>false, :output=>"console", :mvc=>"", :gemfile_scan=>false, :gemfile_name=>"", :filename=>nil, :debug=>false, :exit_on_warn => false, :enabled_checks=> Codesake::Dawn::Kb::BasicCheck::ALLOWED_FAMILIES}
|
|
150
|
+
begin
|
|
151
|
+
return conf if file.nil?
|
|
152
|
+
file = file.chop if (not file.nil? and file.end_with? '/')
|
|
153
|
+
return conf if ! File.exist?(file)
|
|
154
|
+
rescue => e
|
|
155
|
+
$logger.err "it seems you've found a bug in core.rb@#{__LINE__}: #{e.message}"
|
|
156
|
+
return conf
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
c = YAML.load_file(file)
|
|
160
|
+
|
|
161
|
+
cf = c["config"]
|
|
162
|
+
cc = cf[:enabled_checks]
|
|
163
|
+
|
|
164
|
+
# TODO
|
|
165
|
+
# I must add some sanity check here
|
|
166
|
+
conf[:verbose] = cf["verbose"] unless cf["verbose"].nil?
|
|
167
|
+
conf[:debug] = cf["debug"] unless cf["debug"].nil?
|
|
168
|
+
conf[:output] = cf["output"] unless cf["output"].nil?
|
|
169
|
+
conf[:enabled_checks] = cc unless cc.nil?
|
|
170
|
+
|
|
171
|
+
return conf
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
require 'bundler'
|
|
2
|
+
|
|
3
|
+
module Codesake
|
|
4
|
+
module Dawn
|
|
5
|
+
module Engine
|
|
6
|
+
include Codesake::Dawn::Utils
|
|
7
|
+
|
|
8
|
+
attr_reader :target
|
|
9
|
+
attr_reader :name
|
|
10
|
+
attr_reader :scan_start
|
|
11
|
+
attr_reader :scan_stop
|
|
12
|
+
# This attribute is used when @name == "Gemfile.lock" to force the
|
|
13
|
+
# loading of specific MVC checks
|
|
14
|
+
attr_reader :force
|
|
15
|
+
attr_reader :gemfile_lock
|
|
16
|
+
attr_reader :mvc_version
|
|
17
|
+
attr_reader :connected_gems
|
|
18
|
+
attr_reader :checks
|
|
19
|
+
attr_reader :vulnerabilities
|
|
20
|
+
attr_reader :mitigated_issues
|
|
21
|
+
attr_reader :ruby_version
|
|
22
|
+
|
|
23
|
+
attr_reader :engine_error
|
|
24
|
+
|
|
25
|
+
attr_reader :reflected_xss
|
|
26
|
+
|
|
27
|
+
# Typical MVC elements here
|
|
28
|
+
|
|
29
|
+
# Each view will be something like {:filename=>"target/views/index.haml", :language=>:haml}
|
|
30
|
+
attr_reader :views
|
|
31
|
+
|
|
32
|
+
# Each controller will be a little bit more complex. Of course for
|
|
33
|
+
# Sinatra, the controller filename will be the sole web application ruby
|
|
34
|
+
# file.
|
|
35
|
+
# {:filename=>"target/controllers/this_controller.rb", :actions=>[{:name=>"index", :method=>:get, :map=>"/"]}
|
|
36
|
+
attr_reader :controllers
|
|
37
|
+
|
|
38
|
+
# Models I don't know right now. Let them initialized as Array... we
|
|
39
|
+
# will see later
|
|
40
|
+
attr_reader :models
|
|
41
|
+
|
|
42
|
+
attr_accessor :debug
|
|
43
|
+
|
|
44
|
+
attr_reader :applied_checks
|
|
45
|
+
attr_reader :skipped_checks
|
|
46
|
+
|
|
47
|
+
def initialize(dir=nil, name="", options={})
|
|
48
|
+
@name = name
|
|
49
|
+
@scan_start = Time.now
|
|
50
|
+
@scan_stop = @scan_start
|
|
51
|
+
@mvc_version = ""
|
|
52
|
+
@gemfile_lock = ""
|
|
53
|
+
@force = ""
|
|
54
|
+
@connected_gems = []
|
|
55
|
+
@checks = []
|
|
56
|
+
@vulnerabilities = []
|
|
57
|
+
@mitigated_issues = []
|
|
58
|
+
@applied = []
|
|
59
|
+
@reflected_xss = []
|
|
60
|
+
@engine_error = false
|
|
61
|
+
@debug = false
|
|
62
|
+
@debug = options[:debug] unless options[:debug].nil?
|
|
63
|
+
@applied_checks = 0
|
|
64
|
+
@skipped_checks = 0
|
|
65
|
+
@gemfile_lock_sudo = false
|
|
66
|
+
|
|
67
|
+
set_target(dir) unless dir.nil?
|
|
68
|
+
@ruby_version = get_ruby_version if dir.nil?
|
|
69
|
+
@gemfile_lock = options[:gemfile_name] unless options[:gemfile_name].nil?
|
|
70
|
+
|
|
71
|
+
@views = detect_views
|
|
72
|
+
@controllers = detect_controllers
|
|
73
|
+
@models = detect_models
|
|
74
|
+
|
|
75
|
+
if $logger.nil?
|
|
76
|
+
$logger = Codesake::Commons::Logging.instance
|
|
77
|
+
$logger.helo "dawn-engine", Codesake::Dawn::VERSION
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
$logger.warn "pattern matching security checks are disabled for Gemfile.lock scan" if @name == "Gemfile.lock"
|
|
81
|
+
$logger.warn "combo security checks are disabled for Gemfile.lock scan" if @name == "Gemfile.lock"
|
|
82
|
+
debug_me "engine is in debug mode"
|
|
83
|
+
|
|
84
|
+
if @name == "Gemfile.lock" && ! options[:guessed_mvc].nil?
|
|
85
|
+
# since all checks relies on @name a Gemfile.lock engine must
|
|
86
|
+
# impersonificate the engine for the mvc it was detected
|
|
87
|
+
debug_me "now I'm switching my name from #{@name} to #{options[:guessed_mvc][:name]}"
|
|
88
|
+
$logger.err "there are no connected gems... it seems Gemfile.lock parsing failed" if options[:guessed_mvc][:connected_gems].empty?
|
|
89
|
+
@name = options[:guessed_mvc][:name]
|
|
90
|
+
@mvc_version = options[:guessed_mvc][:version]
|
|
91
|
+
@connected_gems = options[:guessed_mvc][:connected_gems]
|
|
92
|
+
@gemfile_lock_sudo = true
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# FIXME.20140325
|
|
96
|
+
#
|
|
97
|
+
# I comment out this call. knowledge base must be called explicitly
|
|
98
|
+
# since it's now possible to pass an array saying check families to be
|
|
99
|
+
# loaded.
|
|
100
|
+
#
|
|
101
|
+
# load_knowledge_base
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def detect_views
|
|
105
|
+
[]
|
|
106
|
+
end
|
|
107
|
+
def error!
|
|
108
|
+
@error = true
|
|
109
|
+
end
|
|
110
|
+
def error?
|
|
111
|
+
@error
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def build_view_array(dir)
|
|
115
|
+
|
|
116
|
+
return [] unless File.exist?(dir) and File.directory?(dir)
|
|
117
|
+
|
|
118
|
+
ret = []
|
|
119
|
+
Dir.glob(File.join("#{dir}", "*")).each do |filename|
|
|
120
|
+
ret << {:filename=>filename, :language=>:haml} if File.extname(filename) == ".haml"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
ret
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def detect_controllers
|
|
127
|
+
[]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def detect_models
|
|
131
|
+
[]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def get_ruby_version
|
|
135
|
+
unless @target.nil?
|
|
136
|
+
|
|
137
|
+
# does target use rbenv?
|
|
138
|
+
ver = get_rbenv_ruby_ver
|
|
139
|
+
# does the target use rvm?
|
|
140
|
+
ver = get_rvm_ruby_ver if ver[:version].empty? && ver[:patchlevel].empty?
|
|
141
|
+
# take the running ruby otherwise
|
|
142
|
+
ver = {:engine=>RUBY_ENGINE, :version=>RUBY_VERSION, :patchlevel=>"p#{RUBY_PATCHLEVEL}"} if ver[:version].empty? && ver[:patchlevel].empty?
|
|
143
|
+
else
|
|
144
|
+
ver = {:engine=>RUBY_ENGINE, :version=>RUBY_VERSION, :patchlevel=>"p#{RUBY_PATCHLEVEL}"}
|
|
145
|
+
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
ver
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def set_target(dir)
|
|
152
|
+
@target = dir
|
|
153
|
+
@gemfile_lock = File.join(@target, "Gemfile.lock")
|
|
154
|
+
@mvc_version = set_mvc_version
|
|
155
|
+
@ruby_version = get_ruby_version
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def target_is_dir?
|
|
159
|
+
File.directory?(@target)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def load_knowledge_base(enabled_checks=[])
|
|
163
|
+
debug_me("load_knowledge_base called. Enabled checks are: #{enabled_checks}")
|
|
164
|
+
if @name == "Gemfile.lock"
|
|
165
|
+
@checks = Codesake::Dawn::KnowledgeBase.new({:enabled_checks=>enabled_checks}).all if @force.empty?
|
|
166
|
+
@checks = Codesake::Dawn::KnowledgeBase.new({:enabled_checks=>enabled_checks}).all_by_mvc(@force) unless @force.empty?
|
|
167
|
+
else
|
|
168
|
+
@checks = Codesake::Dawn::KnowledgeBase.new({:enabled_checks=>enabled_checks}).all_by_mvc(@name)
|
|
169
|
+
|
|
170
|
+
end
|
|
171
|
+
debug_me("#{@checks.count} checks loaded")
|
|
172
|
+
@checks
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def set_mvc_version
|
|
178
|
+
ver = ""
|
|
179
|
+
return ver unless target_is_dir?
|
|
180
|
+
return ver unless has_gemfile_lock?
|
|
181
|
+
|
|
182
|
+
my_dir = Dir.pwd
|
|
183
|
+
Dir.chdir(@target)
|
|
184
|
+
lockfile = Bundler::LockfileParser.new(Bundler.read_file("Gemfile.lock"))
|
|
185
|
+
lockfile.specs.each do |s|
|
|
186
|
+
# detecting MVC version using @name in case of sinatra, padrino or rails engine
|
|
187
|
+
ver= s.version.to_s if s.name == @name && @name != "Gemfile.lock"
|
|
188
|
+
# detecting MVC version using @force in case of Gemfile.lock engine
|
|
189
|
+
ver= s.version.to_s if s.name == @force.to_s && @name == "Gemfile.lock"
|
|
190
|
+
@connected_gems << {:name=>s.name, :version=>s.version.to_s}
|
|
191
|
+
end
|
|
192
|
+
Dir.chdir(my_dir)
|
|
193
|
+
return ver
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def has_gemfile_lock?
|
|
197
|
+
File.exist?(@gemfile_lock)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def is_good_mvc?
|
|
201
|
+
(@mvc_version != "")
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def can_apply?
|
|
205
|
+
target_is_dir? && is_good_mvc?
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def get_mvc_version
|
|
209
|
+
"#{@mvc_version}" if is_good_mvc?
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
## Security stuff applies here
|
|
213
|
+
#
|
|
214
|
+
# Public it applies a single security check given by its name
|
|
215
|
+
#
|
|
216
|
+
# name - the security check to be applied
|
|
217
|
+
#
|
|
218
|
+
# Examples
|
|
219
|
+
#
|
|
220
|
+
# engine.apply("CVE-2013-1800")
|
|
221
|
+
# # => boolean
|
|
222
|
+
#
|
|
223
|
+
# Returns a true value if the security check was successfully applied or false
|
|
224
|
+
# otherwise
|
|
225
|
+
def apply(name)
|
|
226
|
+
|
|
227
|
+
# FIXME.20140325
|
|
228
|
+
# Now if no checks are loaded because knowledge base was not previously called, apply and apply_all proudly refuse to run.
|
|
229
|
+
# Reason is simple, load_knowledge_base now needs enabled check array
|
|
230
|
+
# and I don't want to pollute engine API to propagate this value. It's
|
|
231
|
+
# a param to load_knowledge_base and then bin/dawn calls it
|
|
232
|
+
# accordingly.
|
|
233
|
+
# load_knowledge_base if @checks.nil?
|
|
234
|
+
if @checks.nil?
|
|
235
|
+
$logger.err "you must load knowledge base before trying to apply security checks"
|
|
236
|
+
return false
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
return false if @checks.empty?
|
|
240
|
+
|
|
241
|
+
@checks.each do |check|
|
|
242
|
+
if check.name == name
|
|
243
|
+
unless ((check.kind == Codesake::Dawn::KnowledgeBase::PATTERN_MATCH_CHECK || check.kind == Codesake::Dawn::KnowledgeBase::COMBO_CHECK ) && @name == "Gemfile.lock")
|
|
244
|
+
debug_me "applying check #{check.name}"
|
|
245
|
+
@applied_checks += 1
|
|
246
|
+
@applied << { :name=>name }
|
|
247
|
+
check.ruby_version = @ruby_version[:version]
|
|
248
|
+
check.detected_ruby = @ruby_version if check.kind == Codesake::Dawn::KnowledgeBase::RUBY_VERSION_CHECK
|
|
249
|
+
check.dependencies = self.connected_gems if check.kind == Codesake::Dawn::KnowledgeBase::DEPENDENCY_CHECK
|
|
250
|
+
check.root_dir = self.target if check.kind == Codesake::Dawn::KnowledgeBase::PATTERN_MATCH_CHECK
|
|
251
|
+
check.options = {:detected_ruby => self.ruby_version, :dependencies => self.connected_gems, :root_dir => self.target } if check.kind == Codesake::Dawn::KnowledgeBase::COMBO_CHECK
|
|
252
|
+
|
|
253
|
+
check_vuln = check.vuln?
|
|
254
|
+
|
|
255
|
+
@vulnerabilities << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>nil} if check_vuln && check.kind != Codesake::Dawn::KnowledgeBase::COMBO_CHECK
|
|
256
|
+
|
|
257
|
+
@vulnerabilities << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>check.vulnerable_checks} if check_vuln && check.kind == Codesake::Dawn::KnowledgeBase::COMBO_CHECK
|
|
258
|
+
|
|
259
|
+
@mitigated_issues << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>nil} if check.mitigated?
|
|
260
|
+
return true
|
|
261
|
+
else
|
|
262
|
+
debug_me "skipping check #{check.name}"
|
|
263
|
+
@skipped_checks += 1
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
false
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def apply_all
|
|
272
|
+
@scan_start = Time.now
|
|
273
|
+
debug_me("SCAN STARTED: #{@scan_start}")
|
|
274
|
+
# FIXME.20140325
|
|
275
|
+
# Now if no checks are loaded because knowledge base was not previously called, apply and apply_all proudly refuse to run.
|
|
276
|
+
# Reason is simple, load_knowledge_base now needs enabled check array
|
|
277
|
+
# and I don't want to pollute engine API to propagate this value. It's
|
|
278
|
+
# a param to load_knowledge_base and then bin/dawn calls it
|
|
279
|
+
# accordingly.
|
|
280
|
+
# load_knowledge_base if @checks.nil?
|
|
281
|
+
if @checks.nil?
|
|
282
|
+
$logger.err "you must load knowledge base before trying to apply security checks"
|
|
283
|
+
@scan_stop = Time.now
|
|
284
|
+
debug_me("SCAN STOPPED: #{@scan_stop}")
|
|
285
|
+
return false
|
|
286
|
+
end
|
|
287
|
+
if @checks.empty?
|
|
288
|
+
@scan_stop = Time.now
|
|
289
|
+
debug_me("SCAN STOPPED: #{@scan_stop}")
|
|
290
|
+
return false
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
@checks.each do |check|
|
|
294
|
+
unless ((check.kind == Codesake::Dawn::KnowledgeBase::PATTERN_MATCH_CHECK || check.kind == Codesake::Dawn::KnowledgeBase::COMBO_CHECK ) && @gemfile_lock_sudo)
|
|
295
|
+
|
|
296
|
+
@applied << { :name => name }
|
|
297
|
+
debug_me "applying check #{check.name}"
|
|
298
|
+
@applied_checks += 1
|
|
299
|
+
|
|
300
|
+
check.ruby_version = @ruby_version[:version]
|
|
301
|
+
check.detected_ruby = @ruby_version if check.kind == Codesake::Dawn::KnowledgeBase::RUBY_VERSION_CHECK
|
|
302
|
+
check.dependencies = self.connected_gems if check.kind == Codesake::Dawn::KnowledgeBase::DEPENDENCY_CHECK
|
|
303
|
+
check.root_dir = self.target if check.kind == Codesake::Dawn::KnowledgeBase::PATTERN_MATCH_CHECK
|
|
304
|
+
check.options = {:detected_ruby => self.ruby_version, :dependencies => self.connected_gems, :root_dir => self.target } if check.kind == Codesake::Dawn::KnowledgeBase::COMBO_CHECK
|
|
305
|
+
check_vuln = check.vuln?
|
|
306
|
+
|
|
307
|
+
@vulnerabilities << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>nil} if check_vuln && check.kind != Codesake::Dawn::KnowledgeBase::COMBO_CHECK
|
|
308
|
+
|
|
309
|
+
@vulnerabilities << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>check.vulnerable_checks} if check_vuln && check.kind == Codesake::Dawn::KnowledgeBase::COMBO_CHECK
|
|
310
|
+
|
|
311
|
+
@mitigated_issues << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>nil} if check.mitigated?
|
|
312
|
+
else
|
|
313
|
+
debug_me "skipping check #{check.name}"
|
|
314
|
+
@skipped_checks += 1
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
@scan_stop = Time.now
|
|
318
|
+
debug_me("SCAN STOPPED: #{@scan_stop}")
|
|
319
|
+
|
|
320
|
+
true
|
|
321
|
+
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def scan_time
|
|
325
|
+
@scan_stop - @scan_start
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def is_applied?(name)
|
|
329
|
+
@applied.each do |a|
|
|
330
|
+
return true if a[:name] == name
|
|
331
|
+
end
|
|
332
|
+
return false
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def vulnerabilities
|
|
336
|
+
apply_all if @applied.empty?
|
|
337
|
+
@vulnerabilities
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
def find_vulnerability_by_name(name)
|
|
341
|
+
apply(name) unless is_applied?(name)
|
|
342
|
+
@vulnerabilities.each do |v|
|
|
343
|
+
return v if v[:name] == name
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
nil
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
def is_vulnerable_to?(name)
|
|
350
|
+
return (find_vulnerability_by_name(name) != nil)
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def has_reflected_xss?
|
|
355
|
+
(@reflected_xss.count != 0) unless @reflected_xss.nil?
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def count_vulnerabilities
|
|
359
|
+
ret = 0
|
|
360
|
+
ret = @vulnerabilities.count unless @vulnerabilities.nil?
|
|
361
|
+
ret += @reflected_xss.count unless @reflected_xss.nil?
|
|
362
|
+
|
|
363
|
+
ret
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
private
|
|
367
|
+
def get_rbenv_ruby_ver
|
|
368
|
+
return {:version=>"", :patchlevel=>""} unless File.exist?(File.join(@target, ".rbenv-version"))
|
|
369
|
+
hash = File.read(File.join(@target, '.rbenv-version')).split('-')
|
|
370
|
+
return {:version=>hash[0], :patchlevel=>hash[1]}
|
|
371
|
+
end
|
|
372
|
+
def get_rvm_ruby_ver
|
|
373
|
+
return {:version=>"", :patchlevel=>""} unless File.exist?(File.join(@target, ".ruby-version"))
|
|
374
|
+
hash = File.read(File.join(@target, '.ruby-version')).split('-')
|
|
375
|
+
return {:version=>hash[0], :patchlevel=>hash[1]}
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
end
|