presidentbeef / brakeman

A static analysis security vulnerability scanner for Ruby on Rails applications
https://brakemanscanner.org/
Other
7.02k stars 732 forks source link

SystemStackError crash during a run, with no report emitted. #1877

Closed xxx closed 4 weeks ago

xxx commented 1 month ago

Background

Brakeman version: 6.2.2 Rails version: 7.1.4 Ruby version: 3.2.2

Link to Rails application code: private repo, but see below for replication code.

Issue

When running brakeman over a repo, a file that includes the following method causes brakeman itself to crash. The file can otherwise be empty.

def raise_cyclic_dependency_error(root, parent_vertex, current_vertex)
  r = lambda { |node, path|
    path.unshift(node)

    if node == parent_vertex
      path.unshift(current_vertex)
      return [path, true]
    end

    node.predecessors.each do |s|
      path, cycle_found = r.call(s, path)

      return [path, true] if cycle_found
    end

    path.shift

    [path, false]
  }

  cycle, = r.call(root, [])
  cycle.pluck(:slug)
end

Other Error

Run Brakeman with --debug to see the full stack trace.

Stack trace:

Processing /home/mpd/git-sources/projectpath/l.rb
/home/mpd/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/brakeman-6.2.2/bundle/ruby/3.1.0/gems/sexp_processor-4.17.2/lib/sexp_processor.rb:425:in `block in []': stack level too deep (SystemStackError)
        from /home/mpd/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/brakeman-6.2.2/bundle/ruby/3.1.0/gems/sexp_processor-4.17.2/lib/sexp_processor.rb:425:in `each'
        from /home/mpd/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/brakeman-6.2.2/bundle/ruby/3.1.0/gems/sexp_processor-4.17.2/lib/sexp_processor.rb:425:in `find'
        from /home/mpd/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/brakeman-6.2.2/bundle/ruby/3.1.0/gems/sexp_processor-4.17.2/lib/sexp_processor.rb:425:in `[]'
        from /home/mpd/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/brakeman-6.2.2/lib/brakeman/processors/alias_processor.rb:86:in `replace'
        from /home/mpd/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/brakeman-6.2.2/lib/brakeman/processors/alias_processor.rb:76:in `process_default'
        from /home/mpd/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/brakeman-6.2.2/lib/ruby_parser/bm_sexp_processor.rb:78:in `block in process'
        from /home/mpd/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/brakeman-6.2.2/lib/ruby_parser/bm_sexp_processor.rb:113:in `in_context'
        from /home/mpd/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/brakeman-6.2.2/lib/ruby_parser/bm_sexp_processor.rb:72:in `process'
         ... 9838 levels...
        from /home/mpd/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/brakeman-6.2.2/lib/brakeman/commandline.rb:20:in `start'
        from /home/mpd/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/brakeman-6.2.2/bin/brakeman:10:in `<top (required)>'
        from /home/mpd/.asdf/installs/ruby/3.2.2/bin/brakeman:25:in `load'
        from /home/mpd/.asdf/installs/ruby/3.2.2/bin/brakeman:25:in `<main>'
presidentbeef commented 1 month ago

presidentbeef commented 1 month ago

Well, it's definitely the recursion and multi-assignment.

I've reduced it down to

def raise_cyclic_dependency_error()
  r = lambda {
    x, = r
  }

  z, = r
end

Almost there...