brakeman 7.1.2 → 8.0.6
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 +4 -4
- data/CHANGES.md +48 -0
- data/README.md +1 -1
- data/bundle/load.rb +7 -7
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/NEWS.md +39 -1
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/README.md +1 -1
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/lib/csv/parser.rb +7 -2
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/lib/csv/row.rb +26 -2
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/lib/csv/version.rb +1 -1
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/lib/csv.rb +30 -58
- data/bundle/ruby/3.2.0/gems/erubi-1.13.1/CHANGELOG +111 -0
- data/bundle/ruby/3.2.0/gems/{erubis-2.7.0 → erubi-1.13.1}/MIT-LICENSE +1 -0
- data/bundle/ruby/3.2.0/gems/erubi-1.13.1/README.rdoc +151 -0
- data/bundle/ruby/3.2.0/gems/erubi-1.13.1/lib/erubi/capture_block.rb +91 -0
- data/bundle/ruby/3.2.0/gems/erubi-1.13.1/lib/erubi/capture_end.rb +58 -0
- data/bundle/ruby/3.2.0/gems/erubi-1.13.1/lib/erubi.rb +299 -0
- data/bundle/ruby/3.2.0/gems/parallel-1.28.0/lib/parallel/version.rb +4 -0
- data/bundle/ruby/3.2.0/gems/{parallel-1.27.0 → parallel-1.28.0}/lib/parallel.rb +11 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/io/ansi.rb +6 -4
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/io/windows.rb +49 -23
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/io.rb +8 -2
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/line_editor.rb +49 -21
- data/bundle/ruby/3.2.0/gems/reline-0.7.0/lib/reline/version.rb +3 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline.rb +10 -9
- data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/CHANGES +8 -2
- data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/Gemfile +5 -2
- data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/LICENSE +1 -1
- data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/README.jp.md +10 -12
- data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/README.md +21 -26
- data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/embedded.rb +1 -1
- data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/logic_less/context.rb +4 -3
- data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/splat/builder.rb +18 -19
- data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/version.rb +1 -1
- data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/CHANGES +8 -0
- data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/README.md +1 -1
- data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/static_analyzer.rb +1 -1
- data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/string_splitter.rb +61 -5
- data/bundle/ruby/3.2.0/gems/temple-0.10.6/lib/temple/parser_engine.rb +34 -0
- data/bundle/ruby/3.2.0/gems/temple-0.10.6/lib/temple/static_analyzer.rb +148 -0
- data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/version.rb +1 -1
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/COPYING +1 -1
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/asciidoc.rb +12 -5
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/babel.rb +5 -0
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/builder.rb +4 -0
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/coffee.rb +14 -4
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/commonmarker.rb +65 -0
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/csv.rb +63 -0
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/erb.rb +130 -0
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/erubi.rb +41 -8
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/etanni.rb +7 -0
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/haml.rb +67 -1
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/kramdown.rb +59 -0
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/liquid.rb +93 -0
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/livescript.rb +11 -4
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/mapping.rb +8 -8
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/markaby.rb +11 -2
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/nokogiri.rb +13 -2
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/pandoc.rb +81 -0
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/pipeline.rb +6 -1
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/plain.rb +5 -1
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/prawn.rb +17 -6
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/radius.rb +96 -0
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/rdiscount.rb +82 -0
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/rdoc.rb +41 -0
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/redcarpet.rb +73 -0
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/redcloth.rb +40 -0
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/rst-pandoc.rb +33 -0
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/sass.rb +16 -3
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/slim.rb +18 -0
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/string.rb +10 -2
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/template.rb +5 -5
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/typescript.rb +5 -0
- data/bundle/ruby/3.2.0/gems/tilt-2.8.0/lib/tilt/yajl.rb +91 -0
- data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt.rb +1 -2
- data/lib/brakeman/app_tree.rb +7 -2
- data/lib/brakeman/checks/check_eol_rails.rb +2 -1
- data/lib/brakeman/checks/check_eol_ruby.rb +1 -0
- data/lib/brakeman/checks/check_execute.rb +23 -19
- data/lib/brakeman/checks/check_model_attributes.rb +1 -1
- data/lib/brakeman/checks/check_render.rb +1 -27
- data/lib/brakeman/checks/check_render_rce.rb +43 -0
- data/lib/brakeman/checks/check_session_settings.rb +1 -1
- data/lib/brakeman/checks/check_sql.rb +4 -3
- data/lib/brakeman/checks.rb +31 -25
- data/lib/brakeman/commandline.rb +17 -5
- data/lib/brakeman/file_parser.rb +3 -2
- data/lib/brakeman/logger.rb +265 -0
- data/lib/brakeman/options.rb +6 -11
- data/lib/brakeman/parsers/rails_erubi.rb +82 -0
- data/lib/brakeman/parsers/template_parser.rb +7 -15
- data/lib/brakeman/processor.rb +2 -2
- data/lib/brakeman/processors/base_processor.rb +13 -6
- data/lib/brakeman/processors/controller_alias_processor.rb +1 -1
- data/lib/brakeman/processors/controller_processor.rb +3 -3
- data/lib/brakeman/processors/{erubis_template_processor.rb → erubi_template_procesor.rb} +3 -3
- data/lib/brakeman/processors/gem_processor.rb +1 -1
- data/lib/brakeman/processors/haml_template_processor.rb +3 -1
- data/lib/brakeman/processors/lib/rails2_config_processor.rb +4 -3
- data/lib/brakeman/processors/lib/rails2_route_processor.rb +1 -1
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +10 -1
- data/lib/brakeman/processors/lib/render_helper.rb +4 -2
- data/lib/brakeman/processors/lib/render_path.rb +1 -1
- data/lib/brakeman/processors/model_processor.rb +1 -1
- data/lib/brakeman/report/ignore/config.rb +1 -1
- data/lib/brakeman/scanner.rb +33 -51
- data/lib/brakeman/tracker/collection.rb +12 -2
- data/lib/brakeman/tracker/config.rb +17 -13
- data/lib/brakeman/tracker/constants.rb +17 -2
- data/lib/brakeman/tracker/controller.rb +1 -1
- data/lib/brakeman/tracker.rb +7 -15
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman.rb +109 -55
- metadata +182 -210
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/CHANGES.txt +0 -828
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/README.txt +0 -102
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/contrib/erubis +0 -3468
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/contrib/erubis-run.rb +0 -132
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/contrib/inline-require +0 -179
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/context.rb +0 -83
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/converter.rb +0 -357
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/engine/ec.rb +0 -117
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/engine/ecpp.rb +0 -113
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/engine/ejava.rb +0 -110
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/engine/ejavascript.rb +0 -119
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/engine/enhanced.rb +0 -126
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/engine/eperl.rb +0 -95
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/engine/ephp.rb +0 -99
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/engine/eruby.rb +0 -125
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/engine/escheme.rb +0 -114
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/engine/optimized.rb +0 -127
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/engine.rb +0 -120
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/enhancer.rb +0 -723
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/error.rb +0 -23
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/evaluator.rb +0 -88
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/generator.rb +0 -85
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/helper.rb +0 -47
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/helpers/rails_form_helper.rb +0 -197
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/helpers/rails_helper.rb +0 -353
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/local-setting.rb +0 -9
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/main.rb +0 -516
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/preprocessing.rb +0 -58
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/tiny.rb +0 -144
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis/util.rb +0 -22
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/lib/erubis.rb +0 -73
- data/bundle/ruby/3.2.0/gems/erubis-2.7.0/setup.rb +0 -1331
- data/bundle/ruby/3.2.0/gems/parallel-1.27.0/lib/parallel/version.rb +0 -4
- data/bundle/ruby/3.2.0/gems/reline-0.6.3/lib/reline/version.rb +0 -3
- data/bundle/ruby/3.2.0/gems/temple-0.10.4/lib/temple/static_analyzer.rb +0 -78
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/creole.rb +0 -16
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/csv.rb +0 -53
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/erb.rb +0 -65
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/kramdown.rb +0 -13
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/liquid.rb +0 -37
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/pandoc.rb +0 -39
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/radius.rb +0 -41
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/rdiscount.rb +0 -23
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/rdoc.rb +0 -11
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/redcarpet.rb +0 -31
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/redcloth.rb +0 -13
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/rst-pandoc.rb +0 -10
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/slim.rb +0 -5
- data/bundle/ruby/3.2.0/gems/tilt-2.6.1/lib/tilt/yajl.rb +0 -81
- data/lib/brakeman/parsers/erubis_patch.rb +0 -11
- data/lib/brakeman/parsers/rails2_erubis.rb +0 -9
- data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +0 -52
- data/lib/brakeman/parsers/rails3_erubis.rb +0 -85
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/LICENSE.txt +0 -0
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/lib/csv/core_ext/array.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/lib/csv/core_ext/string.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/lib/csv/fields_converter.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/lib/csv/input_record_separator.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/lib/csv/table.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{csv-3.3.5 → csv-3.3.6}/lib/csv/writer.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{parallel-1.27.0 → parallel-1.28.0}/MIT-LICENSE.txt +0 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/BSDL +0 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/COPYING +0 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/README.md +0 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/config.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/face.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/history.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/io/dumb.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/key_actor/base.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/key_actor/composite.rb +0 -0
- data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/key_actor/emacs.rb +2 -2
- /data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/key_actor/vi_command.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/key_actor/vi_insert.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/key_actor.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/key_stroke.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/kill_ring.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/unicode/east_asian_width.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/lib/reline/unicode.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{reline-0.6.3 → reline-0.7.0}/license_of_rb-readline +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/code_attributes.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/command.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/controls.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/do_inserter.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/end_inserter.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/engine.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/erb_converter.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/filter.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/grammar.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/include.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/interpolation.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/logic_less/filter.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/logic_less.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/parser.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/railtie.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/smart/escaper.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/smart/filter.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/smart/parser.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/smart.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/splat/filter.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/template.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim/translator.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/lib/slim.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{slim-5.2.1 → slim-5.2.2}/slim.gemspec +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/EXPRESSIONS.md +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/Gemfile +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/LICENSE +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/engine.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/erb/engine.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/erb/parser.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/erb/template.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/erb/trimming.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/exceptions.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filter.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/ambles.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/code_merger.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/control_flow.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/dynamic_inliner.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/dynamic_merger.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/encoding.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/eraser.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/escapable.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/multi_flattener.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/remove_bom.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/static_merger.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/filters/validator.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/generator.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/generators/array.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/generators/array_buffer.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/generators/erb.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/generators/rails_output_buffer.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/generators/string_buffer.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/grammar.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/html/attribute_merger.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/html/attribute_remover.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/html/attribute_sorter.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/html/dispatcher.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/html/fast.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/html/filter.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/html/pretty.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/html/safe.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/map.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/mixins/dispatcher.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/mixins/engine_dsl.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/mixins/grammar_dsl.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/mixins/options.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/mixins/template.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/parser.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/templates/rails.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/templates/tilt.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/templates.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple/utils.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/lib/temple.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{temple-0.10.4 → temple-0.10.6}/temple.gemspec +0 -0
- /data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/_emacs_org.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/_handlebars.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/_jbuilder.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/_org.rb +0 -0
- /data/bundle/ruby/3.2.0/gems/{tilt-2.6.1 → tilt-2.8.0}/lib/tilt/cli.rb +0 -0
|
@@ -55,6 +55,13 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
55
55
|
first_arg = call.first_arg
|
|
56
56
|
failure = nil
|
|
57
57
|
|
|
58
|
+
# All spawn-family methods optionally accept an env hash as the first
|
|
59
|
+
# argument. Strip it so first_arg always points to the command name.
|
|
60
|
+
if hash?(first_arg)
|
|
61
|
+
args.delete_at(1)
|
|
62
|
+
first_arg = args[1]
|
|
63
|
+
end
|
|
64
|
+
|
|
58
65
|
case call.method
|
|
59
66
|
when :popen
|
|
60
67
|
# Normally, if we're in a `popen` call, we only are worried about shell
|
|
@@ -99,14 +106,17 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
99
106
|
|
|
100
107
|
break if failure
|
|
101
108
|
end
|
|
102
|
-
when :system, :exec
|
|
103
|
-
|
|
104
|
-
#
|
|
105
|
-
#
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
#
|
|
109
|
-
|
|
109
|
+
when :system, :exec, :spawn, :capture2, :capture2e, :capture3,
|
|
110
|
+
:popen2, :popen2e, :popen3
|
|
111
|
+
# Comma-separated arguments are passed directly to execve without a
|
|
112
|
+
# shell, so only the first argument (the command name) needs checking.
|
|
113
|
+
# Exception: `bash -c <script>` — the script is the injection vector.
|
|
114
|
+
#
|
|
115
|
+
# All of these methods accept an optional trailing options hash
|
|
116
|
+
# (e.g. stdin_data:, chdir:); strip it before checking.
|
|
117
|
+
args.pop if hash?(args.last) && args.length > 2
|
|
118
|
+
|
|
119
|
+
if dash_c_shell_command?(first_arg, args[2])
|
|
110
120
|
failure = include_user_input?(args[3]) ||
|
|
111
121
|
dangerous_interp?(args[3]) ||
|
|
112
122
|
dangerous_string_building?(args[3])
|
|
@@ -115,16 +125,6 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
115
125
|
dangerous_interp?(first_arg) ||
|
|
116
126
|
dangerous_string_building?(first_arg)
|
|
117
127
|
end
|
|
118
|
-
when :capture2, :capture2e, :capture3
|
|
119
|
-
# Open3 capture methods can take a :stdin_data argument which is used as the
|
|
120
|
-
# the input to the called command so it is not succeptable to command injection.
|
|
121
|
-
# As such if the last argument is a hash (and therefore execution options) it
|
|
122
|
-
# should be ignored
|
|
123
|
-
|
|
124
|
-
args.pop if hash?(args.last) && args.length > 2
|
|
125
|
-
failure = include_user_input?(args) ||
|
|
126
|
-
dangerous_interp?(args) ||
|
|
127
|
-
dangerous_string_building?(args)
|
|
128
128
|
else
|
|
129
129
|
failure = include_user_input?(args) ||
|
|
130
130
|
dangerous_interp?(args) ||
|
|
@@ -176,6 +176,8 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
176
176
|
def include_user_input? exp
|
|
177
177
|
if node_type? exp, :arglist, :dstr, :evstr, :dxstr
|
|
178
178
|
exp.each_sexp do |e|
|
|
179
|
+
next if shell_escape? e
|
|
180
|
+
|
|
179
181
|
if res = include_user_input?(e)
|
|
180
182
|
return res
|
|
181
183
|
end
|
|
@@ -196,7 +198,7 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
196
198
|
# Check for input at start of string
|
|
197
199
|
exp[1] == "" and
|
|
198
200
|
node_type? exp[2], :evstr and
|
|
199
|
-
|
|
201
|
+
dangerous? exp[2]
|
|
200
202
|
else
|
|
201
203
|
has_immediate_user_input? exp
|
|
202
204
|
end
|
|
@@ -266,6 +268,8 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
266
268
|
end
|
|
267
269
|
|
|
268
270
|
def dangerous_interp? exp
|
|
271
|
+
return if shell_escape? exp
|
|
272
|
+
|
|
269
273
|
match = include_interp? exp
|
|
270
274
|
return unless match
|
|
271
275
|
interp = match.match
|
|
@@ -12,7 +12,7 @@ class Brakeman::CheckModelAttributes < Brakeman::BaseCheck
|
|
|
12
12
|
|
|
13
13
|
#Roll warnings into one warning for all models
|
|
14
14
|
if tracker.options[:collapse_mass_assignment]
|
|
15
|
-
Brakeman.
|
|
15
|
+
Brakeman.alert "The `collapse_mass_assignment` option has been removed."
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
check_models do |name, model|
|
|
@@ -17,8 +17,7 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
|
|
|
17
17
|
|
|
18
18
|
case result[:call].render_type
|
|
19
19
|
when :partial, :template, :action, :file
|
|
20
|
-
|
|
21
|
-
check_for_dynamic_path(result)
|
|
20
|
+
check_for_dynamic_path(result)
|
|
22
21
|
when :inline
|
|
23
22
|
when :js
|
|
24
23
|
when :json
|
|
@@ -41,8 +40,6 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
|
|
|
41
40
|
else
|
|
42
41
|
confidence = :high
|
|
43
42
|
end
|
|
44
|
-
elsif input = include_user_input?(view)
|
|
45
|
-
confidence = :weak
|
|
46
43
|
else
|
|
47
44
|
return
|
|
48
45
|
end
|
|
@@ -62,29 +59,6 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
|
|
|
62
59
|
end
|
|
63
60
|
end
|
|
64
61
|
|
|
65
|
-
def check_for_rce result
|
|
66
|
-
return unless version_between? "0.0.0", "3.2.22" or
|
|
67
|
-
version_between? "4.0.0", "4.1.14" or
|
|
68
|
-
version_between? "4.2.0", "4.2.5"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
view = result[:call][2]
|
|
72
|
-
if sexp? view and not duplicate? result
|
|
73
|
-
if params? view
|
|
74
|
-
add_result result
|
|
75
|
-
return if safe_param? view
|
|
76
|
-
|
|
77
|
-
warn :result => result,
|
|
78
|
-
:warning_type => "Remote Code Execution",
|
|
79
|
-
:warning_code => :dynamic_render_path_rce,
|
|
80
|
-
:message => msg("Passing query parameters to ", msg_code("render"), " is vulnerable in ", msg_version(rails_version), " ", msg_cve("CVE-2016-0752")),
|
|
81
|
-
:user_input => view,
|
|
82
|
-
:confidence => :high,
|
|
83
|
-
:cwe_id => [22]
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
62
|
def safe_param? exp
|
|
89
63
|
if params? exp and call? exp
|
|
90
64
|
method_name = exp.method
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'brakeman/checks/check_render'
|
|
2
|
+
|
|
3
|
+
class Brakeman::CheckRenderRCE < Brakeman::CheckRender
|
|
4
|
+
Brakeman::Checks.add self
|
|
5
|
+
|
|
6
|
+
@description = "Finds calls to render that might be vulnerable to CVE-2016-0752"
|
|
7
|
+
|
|
8
|
+
def run_check
|
|
9
|
+
tracker.find_call(:target => nil, :method => :render).each do |result|
|
|
10
|
+
process_render_result result
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def process_render_result result
|
|
15
|
+
return unless node_type? result[:call], :render
|
|
16
|
+
|
|
17
|
+
case result[:call].render_type
|
|
18
|
+
when :partial, :template, :action, :file
|
|
19
|
+
check_for_rce(result)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def check_for_rce result
|
|
24
|
+
return unless version_between? "0.0.0", "3.2.22" or
|
|
25
|
+
version_between? "4.0.0", "4.1.14" or
|
|
26
|
+
version_between? "4.2.0", "4.2.5"
|
|
27
|
+
|
|
28
|
+
view = result[:call][2]
|
|
29
|
+
if sexp? view and not duplicate? result
|
|
30
|
+
if params? view and not safe_param? view
|
|
31
|
+
add_result result
|
|
32
|
+
|
|
33
|
+
warn :result => result,
|
|
34
|
+
:warning_type => "Remote Code Execution",
|
|
35
|
+
:warning_code => :dynamic_render_path_rce,
|
|
36
|
+
:message => msg("Passing query parameters to ", msg_code("render"), " is vulnerable in ", msg_version(rails_version), " ", msg_cve("CVE-2016-0752")),
|
|
37
|
+
:user_input => view,
|
|
38
|
+
:confidence => :high,
|
|
39
|
+
:cwe_id => [22]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -120,7 +120,7 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
|
120
120
|
begin
|
|
121
121
|
secrets = YAML.safe_load yaml, aliases: true
|
|
122
122
|
rescue Psych::SyntaxError, RuntimeError => e
|
|
123
|
-
Brakeman.
|
|
123
|
+
Brakeman.alert "#{self.class}: Unable to parse `#{secrets_file}`"
|
|
124
124
|
Brakeman.debug "Failed to parse #{secrets_file}: #{e.inspect}"
|
|
125
125
|
return
|
|
126
126
|
end
|
|
@@ -311,7 +311,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
|
311
311
|
end
|
|
312
312
|
|
|
313
313
|
if request_value? arg
|
|
314
|
-
unless call? arg and params? arg.target and [:permit, :slice, :to_h, :to_hash, :symbolize_keys].include? arg.method
|
|
314
|
+
unless call? arg and params? arg.target and [:permit, :slice, :to_h, :to_hash, :symbolize_keys, :compact, :compact_blank].include? arg.method
|
|
315
315
|
# Model.where(params[:where])
|
|
316
316
|
arg
|
|
317
317
|
end
|
|
@@ -600,7 +600,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
|
600
600
|
:sanitize_sql_for_assignment, :sanitize_sql_for_conditions, :sanitize_sql_hash,
|
|
601
601
|
:sanitize_sql_hash_for_assignment, :sanitize_sql_hash_for_conditions,
|
|
602
602
|
:to_sql, :sanitize, :primary_key, :table_name_prefix, :table_name_suffix,
|
|
603
|
-
:where_values_hash, :foreign_key, :uuid, :escape, :escape_string
|
|
603
|
+
:where_values_hash, :foreign_key, :uuid, :escape, :escape_string,
|
|
604
|
+
:polymorphic_name
|
|
604
605
|
]
|
|
605
606
|
|
|
606
607
|
def ignore_methods_in_sql
|
|
@@ -644,7 +645,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
|
644
645
|
locale_call? exp
|
|
645
646
|
end
|
|
646
647
|
|
|
647
|
-
QUOTE_METHODS = [:quote, :quote_column_name, :quoted_date, :quote_string, :quote_table_name]
|
|
648
|
+
QUOTE_METHODS = [:quote, :quote_column_name, :quoted_date, :quote_string, :quote_table_name, :quote_schema_name]
|
|
648
649
|
|
|
649
650
|
def quote_call? exp
|
|
650
651
|
if call? exp.target
|
data/lib/brakeman/checks.rb
CHANGED
|
@@ -121,37 +121,43 @@ class Brakeman::Checks
|
|
|
121
121
|
parallel = tracker.options[:parallel_checks]
|
|
122
122
|
error_mutex = Mutex.new
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
message = if parallel
|
|
125
|
+
"Running #{checks.length} checks in parallel"
|
|
126
|
+
else
|
|
127
|
+
"Running #{checks.length} checks"
|
|
128
|
+
end
|
|
127
129
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
Brakeman.process_step(message) do
|
|
131
|
+
checks.each do |c|
|
|
132
|
+
check_name = get_check_name c
|
|
133
|
+
Brakeman.debug " - #{check_name}"
|
|
134
|
+
|
|
135
|
+
if parallel
|
|
136
|
+
threads << Thread.new do
|
|
137
|
+
self.run_a_check(c, error_mutex, tracker)
|
|
138
|
+
end
|
|
139
|
+
else
|
|
140
|
+
results << self.run_a_check(c, error_mutex, tracker)
|
|
131
141
|
end
|
|
132
|
-
else
|
|
133
|
-
results << self.run_a_check(c, error_mutex, tracker)
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
#Maintain list of which checks were run
|
|
137
|
-
#mainly for reporting purposes
|
|
138
|
-
check_runner.checks_run << check_name[5..-1]
|
|
139
|
-
end
|
|
140
142
|
|
|
141
|
-
|
|
143
|
+
#Maintain list of which checks were run
|
|
144
|
+
#mainly for reporting purposes
|
|
145
|
+
check_runner.checks_run << check_name[5..-1]
|
|
146
|
+
end
|
|
142
147
|
|
|
143
|
-
|
|
148
|
+
threads.each { |t| t.join }
|
|
144
149
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
150
|
+
if parallel
|
|
151
|
+
threads.each do |thread|
|
|
152
|
+
thread.value.each do |warning|
|
|
153
|
+
check_runner.add_warning warning
|
|
154
|
+
end
|
|
149
155
|
end
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
156
|
+
else
|
|
157
|
+
results.each do |warnings|
|
|
158
|
+
warnings.each do |warning|
|
|
159
|
+
check_runner.add_warning warning
|
|
160
|
+
end
|
|
155
161
|
end
|
|
156
162
|
end
|
|
157
163
|
end
|
data/lib/brakeman/commandline.rb
CHANGED
|
@@ -31,15 +31,22 @@ module Brakeman
|
|
|
31
31
|
set_interrupt_handler options
|
|
32
32
|
early_exit_options options
|
|
33
33
|
set_options options, default_app_path
|
|
34
|
-
check_latest if options[:ensure_latest]
|
|
34
|
+
check_latest(options[:ensure_latest]) if options[:ensure_latest]
|
|
35
35
|
run_report options
|
|
36
|
+
|
|
37
|
+
quit
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
# Check for the latest version.
|
|
39
41
|
#
|
|
40
|
-
# If the latest version is newer
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
# If the latest version is newer than the current version
|
|
43
|
+
# and age, exit.
|
|
44
|
+
def check_latest(days_old = 0)
|
|
45
|
+
if days_old == true
|
|
46
|
+
days_old = 0
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if error = Brakeman.ensure_latest(days_old:)
|
|
43
50
|
quit Brakeman::Not_Latest_Version_Exit_Code, error
|
|
44
51
|
end
|
|
45
52
|
end
|
|
@@ -54,11 +61,13 @@ module Brakeman
|
|
|
54
61
|
f.puts JSON.pretty_generate(vulns)
|
|
55
62
|
end
|
|
56
63
|
|
|
57
|
-
Brakeman.
|
|
64
|
+
Brakeman.announce "Comparison saved in '#{options[:comparison_output_file]}'"
|
|
58
65
|
else
|
|
59
66
|
puts JSON.pretty_generate(vulns)
|
|
60
67
|
end
|
|
61
68
|
|
|
69
|
+
Brakeman.cleanup(false)
|
|
70
|
+
|
|
62
71
|
if options[:exit_on_warn] && vulns[:new].count > 0
|
|
63
72
|
quit Brakeman::Warnings_Found_Exit_Code
|
|
64
73
|
end
|
|
@@ -117,6 +126,7 @@ module Brakeman
|
|
|
117
126
|
# Override this method for different behavior.
|
|
118
127
|
def quit exit_code = 0, message = nil
|
|
119
128
|
warn message if message
|
|
129
|
+
Brakeman.cleanup
|
|
120
130
|
exit exit_code
|
|
121
131
|
end
|
|
122
132
|
|
|
@@ -186,6 +196,8 @@ module Brakeman
|
|
|
186
196
|
warn caller
|
|
187
197
|
end
|
|
188
198
|
|
|
199
|
+
Brakeman.cleanup
|
|
200
|
+
|
|
189
201
|
exit!
|
|
190
202
|
end
|
|
191
203
|
end
|
data/lib/brakeman/file_parser.rb
CHANGED
|
@@ -13,9 +13,9 @@ module Brakeman
|
|
|
13
13
|
if @use_prism
|
|
14
14
|
begin
|
|
15
15
|
require 'prism'
|
|
16
|
-
Brakeman.debug '
|
|
16
|
+
Brakeman.debug 'Using Prism parser'
|
|
17
17
|
rescue LoadError => e
|
|
18
|
-
Brakeman.debug "
|
|
18
|
+
Brakeman.debug "Asked to use Prism, but failed to load: #{e}"
|
|
19
19
|
@use_prism = false
|
|
20
20
|
end
|
|
21
21
|
end
|
|
@@ -46,6 +46,7 @@ module Brakeman
|
|
|
46
46
|
#
|
|
47
47
|
# Note this method no longer uses read_files
|
|
48
48
|
@file_list, new_errors = Parallel.map(list, parallel_options) do |file_name|
|
|
49
|
+
Brakeman.logger.spin
|
|
49
50
|
file_path = @app_tree.file_path(file_name)
|
|
50
51
|
contents = file_path.read
|
|
51
52
|
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
module Brakeman
|
|
2
|
+
module Logger
|
|
3
|
+
def self.get_logger options, dest = $stderr
|
|
4
|
+
case
|
|
5
|
+
when options[:debug]
|
|
6
|
+
Debug.new(options, dest)
|
|
7
|
+
when options[:quiet]
|
|
8
|
+
Quiet.new(options, dest)
|
|
9
|
+
when options[:report_progress] == false
|
|
10
|
+
Plain.new(options, dest)
|
|
11
|
+
when dest.tty?
|
|
12
|
+
Console.new(options, dest)
|
|
13
|
+
else
|
|
14
|
+
Plain.new(options, dest)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Base
|
|
19
|
+
def initialize(options, log_destination = $stderr)
|
|
20
|
+
@dest = log_destination
|
|
21
|
+
@show_timing = options[:debug] || options[:show_timing]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Output a message to the log.
|
|
25
|
+
# If newline is `false`, does not output a newline after message.
|
|
26
|
+
def log(message, newline: true)
|
|
27
|
+
if newline
|
|
28
|
+
@dest.puts message
|
|
29
|
+
else
|
|
30
|
+
@dest.write message
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Notify about important information - use sparingly
|
|
35
|
+
def announce(message); end
|
|
36
|
+
|
|
37
|
+
# Notify regarding errors - use sparingly
|
|
38
|
+
def alert(message); end
|
|
39
|
+
|
|
40
|
+
# Output debug information
|
|
41
|
+
def debug(message); end
|
|
42
|
+
|
|
43
|
+
# Wraps a step in the scanning process
|
|
44
|
+
def context(description, &)
|
|
45
|
+
yield self
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Wraps a substep (e.g. processing one file)
|
|
49
|
+
def single_context(description, &)
|
|
50
|
+
yield
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Update progress towards a known total
|
|
54
|
+
def update_progress(current, total, type = 'files'); end
|
|
55
|
+
|
|
56
|
+
# Show a spinner
|
|
57
|
+
def spin; end
|
|
58
|
+
|
|
59
|
+
# Called on exit
|
|
60
|
+
def cleanup(newline = true); end
|
|
61
|
+
|
|
62
|
+
def show_timing? = @show_timing
|
|
63
|
+
|
|
64
|
+
# Use ANSI codes to color a string
|
|
65
|
+
def color(message, *)
|
|
66
|
+
if @highline
|
|
67
|
+
@highline.color(message, *)
|
|
68
|
+
else
|
|
69
|
+
message
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def color?
|
|
74
|
+
@highline and @highline.use_color?
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
def load_highline(output_color)
|
|
80
|
+
if @dest.tty? or output_color == :force
|
|
81
|
+
Brakeman.load_brakeman_dependency 'highline'
|
|
82
|
+
@highline = HighLine.new
|
|
83
|
+
@highline.use_color = !!output_color
|
|
84
|
+
else
|
|
85
|
+
@highline = nil
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
class Plain < Base
|
|
91
|
+
def initialize(options, *)
|
|
92
|
+
super
|
|
93
|
+
|
|
94
|
+
load_highline(options[:output_color])
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def announce(message)
|
|
98
|
+
log color(message, :bold, :green)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def alert(message)
|
|
102
|
+
log color(message, :red)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def context(description, &)
|
|
106
|
+
log "#{color(description, :green)}..."
|
|
107
|
+
|
|
108
|
+
if show_timing?
|
|
109
|
+
time_step(description, &)
|
|
110
|
+
else
|
|
111
|
+
yield
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def time_step(description, &)
|
|
116
|
+
start_t = Time.now
|
|
117
|
+
yield
|
|
118
|
+
duration = Time.now - start_t
|
|
119
|
+
|
|
120
|
+
log color(("Completed #{description.to_s.downcase} in %0.2fs" % duration), :gray)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
class Quiet < Base
|
|
125
|
+
def initialize(*)
|
|
126
|
+
super
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
class Debug < Plain
|
|
131
|
+
def debug(message)
|
|
132
|
+
log color(message, :gray)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def context(description, &)
|
|
136
|
+
log "#{description}..."
|
|
137
|
+
|
|
138
|
+
time_step(description, &)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def single_context(description, &)
|
|
142
|
+
debug "Processing #{description}"
|
|
143
|
+
|
|
144
|
+
if show_timing?
|
|
145
|
+
# Even in debug, only show timing for each file if asked
|
|
146
|
+
time_step(description, &)
|
|
147
|
+
else
|
|
148
|
+
yield
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
class Console < Base
|
|
154
|
+
attr_reader :prefix
|
|
155
|
+
|
|
156
|
+
def initialize(options, *)
|
|
157
|
+
super
|
|
158
|
+
|
|
159
|
+
load_highline(options[:output_color])
|
|
160
|
+
require 'reline'
|
|
161
|
+
require 'reline/io/ansi'
|
|
162
|
+
|
|
163
|
+
@prefix = ''
|
|
164
|
+
@post_fix_pos = 0
|
|
165
|
+
@reline = Reline::ANSI.new
|
|
166
|
+
@reline.output = @dest
|
|
167
|
+
@report_progress = options[:report_progress]
|
|
168
|
+
@spinner = ["⣀", "⣄", "⣤", "⣦", "⣶", "⣷", "⣿"]
|
|
169
|
+
@percenter = ["⣀", "⣤", "⣶", "⣿"]
|
|
170
|
+
@spindex = 0
|
|
171
|
+
@last_spin = Time.now
|
|
172
|
+
@reline.hide_cursor
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def announce message
|
|
176
|
+
clear_line
|
|
177
|
+
log color(message, :bold, :green)
|
|
178
|
+
rewrite_prefix
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def alert message
|
|
182
|
+
clear_line
|
|
183
|
+
log color(message, :red)
|
|
184
|
+
rewrite_prefix
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def context(description, &)
|
|
188
|
+
write_prefix description
|
|
189
|
+
|
|
190
|
+
time_step(description, &)
|
|
191
|
+
ensure
|
|
192
|
+
clear_prefix
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def time_step(description, &)
|
|
196
|
+
if show_timing?
|
|
197
|
+
start_t = Time.now
|
|
198
|
+
yield
|
|
199
|
+
duration = Time.now - start_t
|
|
200
|
+
|
|
201
|
+
write_after color(('%0.2fs' % duration), :gray)
|
|
202
|
+
log ''
|
|
203
|
+
else
|
|
204
|
+
yield
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def update_progress current, total, type = 'files'
|
|
209
|
+
percent = ((current / total.to_f) * 100).to_i
|
|
210
|
+
tenths = [(percent / 10), 0].max
|
|
211
|
+
|
|
212
|
+
lead = color(@percenter[percent % 10 / 3], :bold, :red)
|
|
213
|
+
done_blocks = color("⣿" * tenths, :red)
|
|
214
|
+
remaining = color("⣀" * (9 - tenths), :gray)
|
|
215
|
+
write_after "#{done_blocks}#{lead}#{remaining}"
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def write_prefix pref
|
|
219
|
+
set_prefix pref
|
|
220
|
+
rewrite_prefix
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# If an alert was written, redo prefix on next line
|
|
224
|
+
def rewrite_prefix
|
|
225
|
+
log(@prefix, newline: false)
|
|
226
|
+
@reline.erase_after_cursor
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def write_after message
|
|
230
|
+
@reline.move_cursor_column(@post_fix_pos)
|
|
231
|
+
log(message, newline: false)
|
|
232
|
+
@reline.erase_after_cursor
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def set_prefix message
|
|
236
|
+
@prefix = "#{color('»', :bold, :cyan)} #{color(message, :green)}"
|
|
237
|
+
@post_fix_pos = HighLine::Wrapper.actual_length(@prefix) + 1
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def clear_prefix
|
|
241
|
+
@prefix = ''
|
|
242
|
+
@post_fix_pos = 0
|
|
243
|
+
clear_line
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def clear_line
|
|
247
|
+
@reline.move_cursor_column(0)
|
|
248
|
+
@reline.erase_after_cursor
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def spin
|
|
252
|
+
return unless (Time.now - @last_spin) > 0.2
|
|
253
|
+
|
|
254
|
+
write_after color(@spinner[@spindex], :bold, :red)
|
|
255
|
+
@spindex = (@spindex + 1) % @spinner.length
|
|
256
|
+
@last_spin = Time.now
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def cleanup(newline = true)
|
|
260
|
+
@reline.show_cursor
|
|
261
|
+
log('') if newline
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|
data/lib/brakeman/options.rb
CHANGED
|
@@ -63,8 +63,12 @@ module Brakeman::Options
|
|
|
63
63
|
options[:exit_on_error] = exit_on_error
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
opts.on "--ensure-latest", "Fail when Brakeman is outdated" do
|
|
67
|
-
|
|
66
|
+
opts.on "--ensure-latest [DAYS]", Integer, "Fail when Brakeman is outdated. Optionally set minimum age in days." do |days|
|
|
67
|
+
if days and not (1..15).include? days
|
|
68
|
+
raise OptionParser::InvalidArgument
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
options[:ensure_latest] = days || true
|
|
68
72
|
end
|
|
69
73
|
|
|
70
74
|
opts.on "--ensure-ignore-notes", "Fail when an ignored warnings does not include a note" do
|
|
@@ -131,7 +135,6 @@ module Brakeman::Options
|
|
|
131
135
|
|
|
132
136
|
opts.on "--faster", "Faster, but less accurate scan" do
|
|
133
137
|
options[:ignore_ifs] = true
|
|
134
|
-
options[:skip_libs] = true
|
|
135
138
|
options[:disable_constant_tracking] = true
|
|
136
139
|
end
|
|
137
140
|
|
|
@@ -143,10 +146,6 @@ module Brakeman::Options
|
|
|
143
146
|
options[:ignore_attr_protected] = true
|
|
144
147
|
end
|
|
145
148
|
|
|
146
|
-
opts.on "--[no-]index-libs", "Add libraries to call index (Default)" do |index|
|
|
147
|
-
options[:index_libs] = index
|
|
148
|
-
end
|
|
149
|
-
|
|
150
149
|
opts.on "--interprocedural", "Process method calls to known methods" do
|
|
151
150
|
options[:interprocedural] = true
|
|
152
151
|
end
|
|
@@ -212,10 +211,6 @@ module Brakeman::Options
|
|
|
212
211
|
options[:skip_vendor] = skip
|
|
213
212
|
end
|
|
214
213
|
|
|
215
|
-
opts.on "--skip-libs", "Skip processing lib directory" do
|
|
216
|
-
options[:skip_libs] = true
|
|
217
|
-
end
|
|
218
|
-
|
|
219
214
|
opts.on "--add-libs-path path1,path2,etc", Array, "An application relative lib directory (ex. app/mailers) to process" do |paths|
|
|
220
215
|
options[:additional_libs_path] ||= Set.new
|
|
221
216
|
options[:additional_libs_path].merge paths
|