presidentbeef / brakeman Goto Github PK
View Code? Open in Web Editor NEWA static analysis security vulnerability scanner for Ruby on Rails applications
Home Page: https://brakemanscanner.org/
License: Other
A static analysis security vulnerability scanner for Ruby on Rails applications
Home Page: https://brakemanscanner.org/
License: Other
I am using the Migrant gem ( https://github.com/pascalh1011/migrant ) and have a line like the following in a model file:
# Migrant
structure do
...
country_code "US", :as => :string, :validates => [:presence, :inclusion => { :in => ["US"] }], :limit => 2
...
end
This causes brakeman to fail every time with the following error unless I comment this line out:
+ERRORS+
+-----------------------------------------------------------------------------------------------------------------+
| Error | Location |
+-----------------------------------------------------------------------------------------------------------------+
| parse error on value "=>" (tASSOC) | could not parse /path/to/my/app/models/address.rb |
+-----------------------------------------------------------------------------------------------------------------+
When commented out the rest of the scan seems to behave normally.
Ran into a case where I was reviewing a project and we were looking at _users.html.haml, except they were in different paths. Best practices aside, the path would be helpful.
Given a model with attributes that should be protected, if the developer opts to protect them with #attr_protected
rather than #attr_accessible
brakeman still raises an issue (See: https://gist.github.com/1699632)
While, stylistically, it is generally better to white-list via #attr_accessible
than black-list via #attr_protected
often the latter makes more sense if there are many many un-protected attributes.
External testing identified a XSS exposure:
GET /library/macros/All?s[filter_value]=<some XSS stuff here will pop up a
window>&s[filter_type]=123&s[order]=123&s[cloud_vendor]=123&s[cloud]=
123&s[advanced_search]=123&s[order]=123 HTTP/1.0
Brakeman (1.5.2) run did not flag the issue. File in question (contents shown below)
<% required_locals :url, :search %>
<div class="contentHeader" style="font: bold 1.4em Helvetica,Arial;">
<%= t("Search Results For") %>: <%= @search.params["s[filter_value]"] %>
<div style="float: right; font-size: 12px; font-weight: normal; margin-right: 10px;">
<% form_for(:s, search, :url => url, :html => { :method => :get }) do |f| %>
<%= f.hidden_field :filter_value %>
<%= f.hidden_field :filter_type %>
<%= f.hidden_field :order %>
<%= f.hidden_field :cloud_vendor %>
<%= f.hidden_field :cloud %>
<%= f.hidden_field :advanced_search %>
<%= f.label :order, t("Sort By") %>
<%# This is kind of a hack for now: we should probably have a Helper for every type. %>
<%# For now though, that overhead is not needed and the other types may later support ratings. %>
<% options = ServerTemplatesHelper::SORT_OPTIONS.map { |i| [t(i[0]), i[1]] } %>
<% options = (params[:controller] == "server_templates") ? options : options.select { |o| o.last != "rating" } %>
<%= select_tag("s[order]", options_for_select(options, @search.params["s[order]"]), :behaves => { :change => :submit_on_change }) %>
</div>
<% end -%>
</div>
Any idea as to why this was missed?
Thanks,
Phil
Is there anyway to annotate or ignore false positives? Maybe the ability to add a comment in the .rhtml and .erb files to ignore certain known false positives.
I'm getting this error when trying to scan a quite big application (8k files):
[Notice] Using Ruby 1.8.7. Please make sure this matches the one used to run your Rails application.
Processing application in /home/xxxx
Processing configuration...
Processing gems...
Processing initializers...
Processing libs...
Processing routes...
Processing templates...
Processing models...
Processing controllers...
[FATAL] failed to allocate memory
brakeman-1.5.2 doesn't consist brakeman.rake
file:
$ ls vendor/gems/ruby/1.9.1/gems/brakeman-1.5.2/lib/brakeman/
call_index.rb checks checks.rb format options.rb processor.rb processors report.rb rescanner.rb scanner.rb tracker.rb util.rb version.rb warning.rb
I get error when invoke brakeman --rake
:
$ brakeman --rake
/home/antage/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/fileutils.rb:1515:in `stat': No such file or directory - /home/antage/workspace/project/vendor/gems/ruby/1.9.1/gems/brakeman-1.5.2/lib/brakeman/brakeman.rake (Errno::ENOENT)
from /home/antage/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/fileutils.rb:1515:in `block in fu_each_src_dest'
from /home/antage/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/fileutils.rb:1531:in `fu_each_src_dest0'
from /home/antage/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/fileutils.rb:1513:in `fu_each_src_dest'
from /home/antage/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/fileutils.rb:395:in `cp'
from /home/antage/workspace/project/vendor/gems/ruby/1.9.1/gems/brakeman-1.5.2/lib/brakeman.rb:193:in `install_rake_task'
from /home/antage/workspace/project/vendor/gems/ruby/1.9.1/gems/brakeman-1.5.2/bin/brakeman:26:in `<top (required)>'
from bin/brakeman:16:in `load'
from bin/brakeman:16:in `<main>'
Oneline patch for brakeman.gemspec
can solve this issue:
- s.files = ["bin/brakeman", "WARNING_TYPES", "FEATURES", "README.md"] + Dir["lib/**/*.rb"] + Dir["lib/brakeman/format/*.css"]
+ s.files = ["bin/brakeman", "WARNING_TYPES", "FEATURES", "README.md"] + Dir["lib/**/*.rb"] + Dir["lib/**/*.rake"] + Dir["lib/brakeman/format/*.css"]
1) Failure:
test_session_cookies(Rails2Tests)
[test.rb:52:in `assert_warning'
test.rb:216:in `test_session_cookies']:
No warning found.
<0> expected to be != to
<0>.
2) Failure:
test_without_protection(Rails31Tests)
[test.rb:52:in `assert_warning'
test.rb:818:in `test_without_protection']:
No warning found.
<0> expected to be != to
<0>.
83 tests, 155 assertions, 2 failures, 0 errors
Must investigate...
Would be good to have a dead simple rake task for use with travis-ci
I assume this isn't coming from a bug in my code, but I may be wrong... just installed brakeman 1.5.1 and ran it against my app and I got exactly 168 entries in the errors table like so:
wrong number of arguments (0 for 1) | /Users/becky/.rvm/gems/ruby-1.9.3-p0/gems/brakeman-1.5.1/lib/brakeman/processors/template_alias_processor.rb:24:in `template_name'
Testing a Rails 3.1.3 app running Ruby 1.9.3.
Ran into a case where I was reviewing a project and we were looking at _users.html.haml, except they were in different paths. Best practices aside, the path would be helpful.
Whole stactrace below:
[Notice] Detected Rails 3 application
Loading scanner...
[Notice] Using Ruby 1.9.2. Please make sure this matches the one used to run your Rails application.
Processing application in /home/projects/ringadoc
Processing configuration...
[Notice] Escaping HTML by default
Processing gems...
Processing initializers...
Processing libs...
[Skipping]
Processing routes...
Processing templates...
Processing data flow in templates...
Processing models...
Processing controllers...
Processing data flow in controllers...
Indexing call sites...
/home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/processors/lib/processor_helper.rb:28:in `class_name': Error: Cannot get class name from s(:self) (RuntimeError)
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/processors/lib/processor_helper.rb:22:in `class_name'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/processors/lib/find_all_calls.rb:123:in `get_target'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/processors/lib/find_all_calls.rb:43:in `process_call'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:209:in `block (2 levels) in process'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:261:in `error_handler'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:208:in `block in process'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:326:in `in_context'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:180:in `process'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/processors/lib/find_all_calls.rb:36:in `block in process_rlist'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/processors/lib/find_all_calls.rb:35:in `each'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/processors/lib/find_all_calls.rb:35:in `process_rlist'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:209:in `block (2 levels) in process'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:261:in `error_handler'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:208:in `block in process'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:326:in `in_context'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:180:in `process'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/processors/lib/find_all_calls.rb:30:in `process_selfdef'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:209:in `block (2 levels) in process'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:261:in `error_handler'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:208:in `block in process'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:326:in `in_context'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/sexp_processor-3.0.10/lib/sexp_processor.rb:180:in `process'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/processors/lib/find_all_calls.rb:20:in `process_source'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/tracker.rb:145:in `block in index_call_sites'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/tracker.rb:75:in `block (4 levels) in each_method'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/tracker.rb:70:in `each'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/tracker.rb:70:in `block (3 levels) in each_method'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/tracker.rb:69:in `each'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/tracker.rb:69:in `block (2 levels) in each_method'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/tracker.rb:68:in `each'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/tracker.rb:68:in `block in each_method'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/tracker.rb:67:in `each'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/tracker.rb:67:in `each_method'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/tracker.rb:144:in `index_call_sites'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/scanner.rb:356:in `index_call_sites'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman/scanner.rb:71:in `process'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman.rb:241:in `scan'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/lib/brakeman.rb:55:in `run'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/gems/brakeman-1.2.2/bin/brakeman:45:in `<top (required)>'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/bin/brakeman:19:in `load'
from /home/ltackowiak/.rvm/gems/ruby-1.9.2-p290@ringadoc/bin/brakeman:19:in `<main>'
I have a rails 2.3.8 project that I wanted to run brakeman against. I would hang when it hit CheckSQL, and I went through and excluded all of the checks that it would hang on.
For me 'Hang' means it stops at CheckSQL, and does not print anything out for more than 45 mins (at which point I kill it), while it is still consuming mem and cpu.
I tried to get some log info, or see what it was doing via the verbose debug flag, but I couldn't figure out why it was hanging. I imagine it might be some crazy references in my project, if it is actually attempting to look that up, but I'd like some way of knowing what it is getting stuck on.
Is there some other flag to have it tell me what it is doing in those steps?
Ran into a case where we were getting a warning on Dynamic Render paths.
<%= render :partial => find_patial(@param) %>
def find_partial param
param == "a" ? "partial_a" : "partial_b"
end
While it is "dynamic" the values are from a finite set and are not defined by an external source.
Yay? Nay?
I've found another possible false positive in mass attribute update alerting. I have an example in my badapp user model. It is my understanding that #update_attribute
takes an explicit attribute to update so it is equivalent to setting an attribute directly thus:
def method
@attr = params[:attr]
# should be equivalent to
self.update_attribute(:attr, params[:attr])
end
The biggest worry I have regarding #update_attribute
is that it bypasses validations on the model. Am I misunderstanding the threat from this method?
[my_awesome_app (v11.44-rc)]$ brakeman .
[Notice] Detected Rails 3 application. Enabling experimental Rails 3 support.
Loading scanner...
[Notice] Using Ruby 1.9.2. Please make sure this matches the one used to run your Rails application.
Processing application in /my_awesome_app
Processing configuration...
[Notice] Escaping HTML by default
Processing gems...
Processing initializers...
Processing libs...
Processing routes...
/Users/somedude/.rvm/gems/ruby-1.9.2-p290/gems/brakeman-0.8.0/lib/processors/lib/rails3_route_processor.rb:130:in process_verb': undefined method
<<' for nil:NilClass (NoMethodError)
[Notice] Error while processing routes - assuming all public controller methods are actions.
Will send routes privately
Not entirely sure if this is a bug/incomplete feature or not. In the Regular Expression checks, you're looking for \A and \Z to check that the validation is anchored correctly. Is it not equally valid to use '^' and '$' (which is what I'm doing, resulting in what might be false positives if my understanding is right)?
Happy to provide a patch to fix this if '^' and '$' should be allowed as well.
| parse error on value "if", 41 <%= something if condtional %>
| parse error on value "unless", 6 -> <%= " more" unless @use_less %>
Changing it to
<% if conditional %>
<%= something %>
<% end %>
Works
I have some weird problem when processing libs - brakeman hang on one of files.
Will be great if I can skip (giving list of excluded paths in config?) just that file which makes problem instead whole libs.
Ruby 1.9 adds the ability to use a semicolon to introduce local variables to a block scope. Here's an example.
some_list.each do | item; var |
var = some temp calculation
item.do_something ( expression using var)
end
var is out of scope after the block
Brakeman's parser fails to handle this case, dies on the semicolon after item
I've been tracking down what I think is a false positive in a client app. I've distilled what I think are the salient details but I could be missing something. I've added code that replicates the issue in my badapp's user model
I digging into the code it appears that the call to #include_user_input
on (roughly line 199) of check_sql.rb
is returning non-false for code that does include user input but should be escaped correctly.
It is my understanding that the #find_or_create_by_<attr>
methods are safe to use user-input on. If they are not than the second example in my badapp linked above should also be warned about. My investigation in console (Rails 3.1) indicate that they are not vulnerable to a SQLi.
We solve mass-assignment problems by setting attr_accessible to :nil by default in an initializer:
ActiveRecord::Base.send(:attr_accessible, nil)
This means no model attributes can be mass-assigned at all unless specifically allowed with attr_accessible in the model.
However, some models don't need mass assignment, so they don't get an attr_accessible call. Brakeman detects these models as "Mass assignment is not restricted" even though the opposite is true.
Tested in a Rails 2.3.5 app; haven't checked in a Rails3 app yet. I will do so and get back to you.
View layouts can have vulnerabilities, too.
Since layouts are shared between many views, make sure to do duplicate detection (same as views).
Generating report...
/Users/neilmatatall/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/csv.rb:2324:in CSV': undefined method
instance' for Ruport::Formatter::CSV:Class (NoMethodError)
Got the same error through Jenkins, ran it by hand and got same problem. Run of other repositories on same system complete with no error. Any thoughts?
[Notice] Using Ruby 1.8.7. Please make sure this matches the one used to run your Rails application.
Processing application in /var/lib/jenkins/jobs/BrakemanScan/workspace
Processing configuration...
Processing gems...
Processing initializers...
Processing libs...
Processing routes...
Processing templates...
Processing data flow in templates...
Processing models...
Processing controllers...
Processing data flow in controllers...
Indexing call sites... ed
Running checks in parallel...
format_code': private method
gsub' called for nil:NilClass (NoMethodError)format_message' from /opt/ruby-enterprise-1.8.7-2012.02/lib/ruby/gems/1.8/gems/brakeman-1.4.0/bin/../lib/brakeman/warning.rb:98:in
to_row'generate_warnings' from /opt/ruby-enterprise-1.8.7-2012.02/lib/ruby/gems/1.8/gems/brakeman-1.4.0/bin/../lib/brakeman/report.rb:104:in
each'generate_warnings' from /opt/ruby-enterprise-1.8.7-2012.02/lib/ruby/gems/1.8/gems/brakeman-1.4.0/bin/../lib/brakeman/report.rb:339:in
to_s'send' from /opt/ruby-enterprise-1.8.7-2012.02/lib/ruby/gems/1.8/gems/brakeman-1.4.0/bin/../lib/brakeman.rb:262:in
scan'run' from /opt/ruby-enterprise-1.8.7-2012.02/lib/ruby/gems/1.8/gems/brakeman-1.4.0/bin/brakeman:45 from /opt/ruby-enterprise-1.8.7-2012.02/bin/brakeman:19:in
load'Noticed attr_accessible warning seems to be triggered even when attr is protected (assuming I'm correctly interpreting attr_accessible). Rails 3.1.3
No attr accessible
class Affiliation < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
Affiliation vulnerable
ruby-1.9.3-p0 :009 > Affiliation.create! :group => Group.first, :user => User.first
Group Load (0.3ms) SELECT `groups`.* FROM `groups` LIMIT 1
User Load (1.4ms) SELECT `users`.* FROM `users` LIMIT 1
(0.2ms) BEGIN
SQL (0.4ms) INSERT INTO `affiliations` (`created_at`, `group_id`, `user_id`, `updated_at`) VALUES ('2012-01-17 19:47:15', 2, 77, '2012-01-17 19:47:15')
(1.6ms) COMMIT
=> #<Affiliation id: 585, group_id: 2, user_id: 77, created_at: "2012-01-17 19:47:15", updated_at: "2012-01-17 19:47:15">
Adding attr_accessible without arguments:
class Affiliation < ActiveRecord::Base
attr_accessible
belongs_to :user
belongs_to :group
end
Protected against mass-assignment
ruby-1.9.3-p0 :011 > Affiliation.create! :group => Group.first, :user => User.first
Group Load (0.3ms) SELECT `groups`.* FROM `groups` LIMIT 1
User Load (0.3ms) SELECT `users`.* FROM `users` LIMIT 1
WARNING: Can't mass-assign protected attributes: group, user
Brakeman still shows:
Model Warnings:
+----------------------------------------------------------------------------->>
| Confidence | >>
+----------------------------------------------------------------------------->>
| High | Affiliation >>
+----------------------------------------------------------------------------->>
Right now, no Rails 3 configuration is being processed.
Plan:
Need to support both Rails 2 and 3 configuration processing (like route processing does).
Haven't been able to successfully run brakeman. Encountered this problem using Rails 3.1.3 with Ruby 1.9.2-p180, 1.9.2-p290 and 1.9.3-p0
$ brakeman -o brakeman.txt
[Notice] Detected Rails 3 application. Enabling experimental Rails 3 support.
Loading scanner...
[Notice] Using Ruby 1.9.2. Please make sure this matches the one used to run your Rails application.
Processing application in /src/web
Processing configuration...
/.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/processors/lib/rails3_config_processor.rb:73:in []=': can't convert Symbol into Integer (TypeError) from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/processors/lib/rails3_config_processor.rb:73:in
process_attrasgn'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:209:in block (2 levels) in process' from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:261:in
error_handler'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:208:in block in process' from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:326:in
in_context'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:180:in process' from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/processors/base_processor.rb:113:in
block in process_block'
from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/processors/base_processor.rb:112:in map!' from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/processors/base_processor.rb:112:in
process_block'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:209:in block (2 levels) in process' from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:261:in
error_handler'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:208:in block in process' from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:326:in
in_context'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:180:in process' from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/processors/lib/rails3_config_processor.rb:34:in
process_iter'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:209:in block (2 levels) in process' from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:261:in
error_handler'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:208:in block in process' from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:326:in
in_context'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:180:in process' from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/processors/base_processor.rb:113:in
block in process_block'
from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/processors/base_processor.rb:112:in map!' from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/processors/base_processor.rb:112:in
process_block'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:209:in block (2 levels) in process' from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:261:in
error_handler'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:208:in block in process' from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:326:in
in_context'
from /.rvm/gems/ruby-1.9.2-p290/gems/sexp_processor-3.0.9/lib/sexp_processor.rb:180:in process' from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/processors/lib/rails3_config_processor.rb:27:in
process_config'
from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/processor.rb:23:in process_config' from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/scanner.rb:80:in
process_config'
from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman/scanner.rb:54:in process' from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman.rb:207:in
scan'
from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/lib/brakeman.rb:54:in run' from /.rvm/gems/ruby-1.9.2-p290/gems/brakeman-1.0.0/bin/brakeman:173:in
<top (required)>'
from /.rvm/gems/ruby-1.9.2-p290/bin/brakeman:19:in load' from /.rvm/gems/ruby-1.9.2-p290/bin/brakeman:19:in
I tried installing and using brakeman on a pair of Rails 2 applications shortly after seeing your presentation. It looks like it runs the checks correctly, but then fails when generating the report.
Here's the output from one such report:
[21:40:56 Ruby]$ brakeman eclipticdb/
[Notice] Using Ruby 1.8.7. Please make sure this matches the one used to run your Rails application.
Processing application in /Users/evan/Development/Ruby/eclipticdb
Processing configuration...
Processing initializers...
Processing libs...
Processing routes...
Processing templates...
Processing models...
Processing controllers...
Running checks...
format_code': private method
gsub' called for nil:NilClass (NoMethodError)format_message' from /Library/Ruby/Gems/1.8/gems/brakeman-0.0.2/lib/warning.rb:81:in
to_row'generate_warnings' from /Library/Ruby/Gems/1.8/gems/brakeman-0.0.2/lib/report.rb:87:in
each'generate_warnings' from /Library/Ruby/Gems/1.8/gems/brakeman-0.0.2/lib/report.rb:314:in
to_s'send' from /Library/Ruby/Gems/1.8/gems/brakeman-0.0.2/bin/brakeman:265 from /usr/bin/brakeman:19:in
load'We have a rails 2.3.5 app; we have applied the 2.3.11-era CSRF patch to Rails in vendor/rails. Brakeman issues a high-confidence warning:
CSRF protection is flawed in 2.3.5 (CVE-2011-0447). Upgrade to 2.3.11 or apply patches
Ran into a case where I was reviewing a project and we were looking at _users.html.haml, except they were in different paths. Best practices aside, the path would be helpful.
Given a scope that properly(?) uses a prepared statement Brakeman alerts of an existing SQL injection. See https://gist.github.com/1699632 for details. Perhaps I am misunderstanding the vulnerability and an injection does exist but it is my understanding that this is the "right way (TM)" to do this search (if not using MetaWhere for example).
brakeman right_site/
[Notice] Using Ruby 1.8.7. Please make sure this matches the one used to run your Rails application.
Processing application in /Users/pcc/src/rightsit
Processing configuration...
Processing initializers...
Processing libs...
Processing routes...
Processing templates...
Processing models...
Processing controllers...
Running checks...
process_attrasgn' : super: no superclass method
process_attrasgn' for #CheckSessionSettings:0x11215e4e8 (NoMethodError)send' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:209:in
process'error_handler' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:208:in
process'in_context' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:180:in
process'process_default' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.0/bin/../lib/processors/lib/processor_helper.rb:26:in
each_with_index'each' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.0/bin/../lib/checks/base_check.rb:43:in
each_with_index'process_default' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:209:in
send'process' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:261:in
error_handler'process' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:326:in
in_context'process' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.0/bin/../lib/checks/base_check.rb:45:in
process_default'each_with_index' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.0/bin/../lib/checks/base_check.rb:43:in
each'each_with_index' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.0/bin/../lib/checks/base_check.rb:43:in
process_default'send' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:209:in
process'error_handler' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:208:in
process'in_context' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:180:in
process'run_check' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.0/bin/../lib/checks.rb:57:in
run_checks'each' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.0/bin/../lib/checks.rb:51:in
run_checks'run_checks' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.0/bin/brakeman:284 from /opt/local/bin/brakeman:19:in
load'Just noticed it was running in a single thread, much of this can probably be parallelized byt may change the paradigm in ways that might not be possible (don't know enough about the internals).
I imagine at the least that the checks can be done in parallel, any other threading is probably overkill since 95% of the execution is the checks (mostly checksql in my case)
[Notice] Using Ruby 1.8.7. Please make sure this matches the one used to run your Rails application.
Processing application in /Users/obfuscated/src/ritesite
Processing configuration...
Processing initializers...
Processing libs...
Processing routes...
Processing templates...
Processing models...
Processing controllers...
Running checks...
class_name': Error: Cannot get class name from s(:lvar, :klass) (RuntimeError) from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/processors/lib/processor_helper.rb:20:in
class_name'get_target' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/processors/lib/find_call.rb:89:in
process_call'send' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:209:in
process'error_handler' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:208:in
process'in_context' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:180:in
process'process_default' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:267:in
each_with_index'each' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/processors/base_processor.rb:44:in
each_with_index'process_default' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:209:in
send'process' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:261:in
error_handler'process' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:326:in
in_context'process' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/processors/base_processor.rb:58:in
process_if'send' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:209:in
process'error_handler' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:208:in
process'in_context' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:180:in
process'process_rlist' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/processors/lib/find_call.rb:80:in
each'process_rlist' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:209:in
send'process' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:261:in
error_handler'process' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:326:in
in_context'process' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/processors/lib/find_call.rb:75:in
process_selfdef'send' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:209:in
process'error_handler' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:208:in
process'in_context' from /opt/local/lib/ruby/gems/1.8/gems/sexp_processor-3.0.5/lib/sexp_processor.rb:180:in
process'process_source' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/tracker.rb:103:in
find_call'each_method' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/tracker.rb:67:in
each'each_method' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/tracker.rb:66:in
each'each_method' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/tracker.rb:65:in
each'each_method' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/tracker.rb:64:in
each'each_method' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/tracker.rb:102:in
find_call'run_check' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/checks/check_cross_site_scripting.rb:53:in
run_check'run_checks' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/checks.rb:51:in
each'run_checks' from /opt/local/lib/ruby/gems/1.8/gems/brakeman-0.6.1/bin/../lib/tracker.rb:59:in
run_checks'Any chance Sinatra and DataMapper support will be added? We are looking at moving to those frameworks in the future, and would love to get Brakeman working on them as well.
There was a file that was copy/pasted to two parts of a project and contained the same vuln. The report only showed one result. After fixing the vuln in one, it still showed up in the report (because there was a second file with the same name and vuln) which leads us to think the two results were being merged and clobbered.
{"Confidence"=>0, "Warning Type"=>"Cross Site Scripting", "Message"=>"Unescaped model attribute in link_to near line 9: link_to((Unresolved Model).new.action_str, "#", :class => "action rpprelmodal")", "Class"=>"", "Method"=>""}
I believe the warning came from the "#" not being html safe. But it is a literal, and I think it's a reasonable assumption that literals are safe?
Devil's advocate: programmers can put malicious scripts directly into the app.
Placing the following code in test/apps/rails2/app/controllers/application_controller.rb seems to cause brakeman to hang indefinitely when I attempt to run tests. This came up in an app we were testing.
before_filter :awesome
def funky_panda
end
def awesome
something = if params[:thang]
params[:thang]
elsif somevar = "monkeypanda"
somevar = somevar.split(",").map { |s|
s += 'stuff' unless s =~ /regex/
s.split('things')
}.first
somevar.first.downcase
end
if (some_var = SomeClass.things, something)
AnotherClass.thang = @thang = some_var.to_sym
elsif (some_var = find_thang(AppConfig.stuff, something))
AnotherClass.thang = @thang = some_var.to_sym
end
if beta_override && cookies['yummy'] != @thang.to_s
cookies['yummy'] = { :value => @thang.to_s }
end
return true
end
However I run brakeman, whether from the app root with no arguments or by supplying the path, I get:
"Please supply the path to a Rails application."
I'm using brakeman 1.5.2 and built it from source.
Please advise,
Thanks
I'm pretty sure the code:
a = current_user.foo
a.bars.build(params[:bar])
Is vulnerable to mass assignment without attr_protected/accessible.
ActiveRecord::Associations::AssociationCollection#build calls
@reflection.build_association(attrs)
which calls
klass.new(*options)
which calls init, which calls
attributes=
I think brakeman should warn if build is used without attr_ restriction
Forgive me for creating an issue and not a pull request (yet) but it seems Brakeman does not detect when the 'strong_parameters' gem is used and ActiveModel::ForbiddenAttributesProtection is included in a model. This will be the Rails 4-way of protecting mass assignment and I think Brakeman should see it, right?
| parse error on value ":" (tCOLON) | could not parse /Users/neilmatatall/dev/fotobuk/config/initializers/session_store.rb. There is probably a typo in the file. Test it with 'ruby_parse /Users/neilmatatall/dev/fotobuk/config/initializers/session_store.rb' |
| parse error on value ":" (tCOLON) | could not parse /Users/neilmatatall/dev/fotobuk/config/initializers/wrap_parameters.rb. There is probably a typo in the file. Test it with 'ruby_parse /Users/neilmatatall/dev/fotobuk/config/initializers/wrap_parameters.rb' |
| parse error on value ":" (tCOLON) | could not parse /Users/neilmatatall/dev/fotobuk/app/views/photos/index.html.erb |
| parse error on value ":" (tCOLON) | could not parse /Users/neilmatatall/dev/fotobuk/app/controllers/photos_controller.rb. There is probably a typo in the file. Test it with 'ruby_parse /Users/neilmatatall/dev/fotobuk/app/controllers/photos_controller.rb'
Code is at https://github.com/oreoshake/fotobuk
NoMethodError: undefined method `exception' for java.lang.ArrayIndexOutOfBoundsException: 2:Java::JavaLang::ArrayIndexOutOfBoundsException
process_template at /Users/neilmatatall/dev/brakeman/bin/../lib/brakeman/scanner.rb:312
process_template at /Users/neilmatatall/dev/brakeman/bin/../lib/brakeman/scanner.rb:305
process_templates at /Users/neilmatatall/dev/brakeman/bin/../lib/brakeman/scanner.rb:255
each at org/jruby/RubyArray.java:1612
process_templates at /Users/neilmatatall/dev/brakeman/bin/../lib/brakeman/scanner.rb:249
process at /Users/neilmatatall/dev/brakeman/bin/../lib/brakeman/scanner.rb:65
scan at /Users/neilmatatall/dev/brakeman/bin/../lib/brakeman.rb:221
run at /Users/neilmatatall/dev/brakeman/bin/../lib/brakeman.rb:48
(root) at bin/brakeman:45
Return a non-zero exit code (such as 1
) if brakeman detects any errors.
Without rails_xss on a Rails 2.x project, marking a method as safe doesn't seem to work if the method call is in a block
brakeman . -s made_up
link_to 'http://brakemanscanner.org' do
made_up
end
Triggers a warning but
link_to made_up, 'http://brakemanscanner.org'
does not.
| parse error on value ":" (tCOLON) | could not parse /Users/neilmatatall/dev/chdevise/chrails/config/initializers/wrap_parameters.r>>
wrap_parameters.rb (default):
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json]
end
ActiveSupport.on_load(:active_record) do
self.include_root_in_json = false
end
I'm new to running brakeman and wondered why it discovered
def self.find_recent(options = {:limit => 5})
find(:all, :conditions => "created_at > '#{14.days.ago.to_s :db}'", :order => "created_at DESC", :limit => options[:limit])
end
but not
named_scope :since, lambda { |days|
{ :conditions => "published_at > '#{days.ago.to_s :db}'" }
}
This issue is for tracking Rails 3 support in Brakeman.
Here are the issues:
Rails 3 encourages the use of Ruby 1.9.2, and ruby_parser does not currently support new 1.9.2 syntax. This is kind of a problem.
Possible solutions:
This is obviously a bad idea.
This could happen, as Ryan Davis has recently posted requesting help in this area.
Since Ripper is only available in 1.9, Brakeman would have to support two parsers. This would be a lot of work, because Ripper uses a completely different s-expression format and Brakeman is very much tied to the ruby_parser output. One option would be to convert Ripper output to match ruby_parser's, and then process that. I think that is the simplest solution, but I am not convinced it is the best.
Another option is to have a parallel version of Brakeman rewritten to handle Ripper's output and Rails 3, completely separately. This gives me knots in my stomach just writing it.
A third option, which sounds the best architecturally, is to modify Brakeman to have it accept its own particular format. Then it would not be so dependent on ruby_parser. Actually, Brakeman does this already, as it mangles the s-expressions from ruby_parser to simplify and remove uninteresting information. So the solution would be to write adapters to convert from different formats (e.g., Ripper output) to Brakeman's expected input.
Compared to the above issue, this seems fairly straightforward.
Currently, Brakeman looks for method calls like Model.find
or Model.find_by_sql
. It looks like Rails 3 will support this for a short while, but then will be completely moving to the new interface.
I am currently uncertain what methods will accept SQL in Rails 3 besides where
. Needs to be investigated.
routes.rb
is going to be completely different, so anything dealing with it will need to change.
Currently, Brakeman only really uses routes to determine which methods are to be considered actions in the controllers.
Brakeman currently does not really support this, but it needs to.
Rails 3 enables cross-site scripting protection by default. This is not a problem, as Brakeman already supports this.
Need to handle this alternative to respond_to
That is all my initial investigation turned up. Please add more if you are aware of Rails 3 changes that will impact Brakeman.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.