諸行無常

IT色々お勉強中のブログ

Rails脆弱性情報

脆弱性情報

//routeに":controller"を含んでいると脆弱性に引っかかる?

Not affected:       < 4.0.0, 5.0.0.beta1 and newer 
// 4.0.0以下は影響しない
Impact 
------ 
Users that have a route that contains the string ":controller" are susceptible 
to objects being leaked globally which can lead to unbounded memory growth. 
To identify if your application is vulnerable, look for routes that contain 
":controller". 

Internally, Action Pack keeps a map of "url controller name" to "controller 
class name".  This map is cached globally, and is populated even if the 
controller class doesn't actually exist. 

All users running an affected release should either upgrade or use one of the 
workarounds immediately. 
Versions Affected:  All. 
Not affected:       None. 
Fixed Versions:     1.0.3 
//全てのバージョンは引っかかる。1.0.3? で直している
//rails-html-sanitizer gemを使ってるとダメ?使って無さそう

Impact 
------ 
There is a possible XSS vulnerability in rails-html-sanitizer.  Certain 
attributes are not removed from tags when they are sanitized, and these 
attributes can lead to an XSS attack on target applications. 

All users running an affected release should either upgrade or use one of the 
workarounds immediately.
Not affected:       4.0.13 and older//古いのは影響受けない
Impact 
------ 
Code that uses Active Model based models (including Active Record models) and 
does not validate user input before passing it to the model can be subject to 
an attack where specially crafted input will cause the model to skip 
validations. 
//未検証のパラメータを入れると脆弱性?

Vulnerable code will look something like this: 

SomeModel.new(unverified_user_input) 
Rails users using Strong Parameters are generally not impacted by this issue as they are encouraged to whitelist parameters and must specifically opt-out of input verification using the `permit!` method to allow mass assignment. For example, a vulnerable Rails application will have code that looks like this:
def create 
  params.permit! # allow all parameters 
  @user = User.new params[:users] 
end 
//Strong Parametersで⇒みたいなん書いてるとダメ?User.new params[:users] Active Model and Active Record objects are not equipped to handle arbitrary user input. It is up to the application to verify input before passing it to Active Model models. Rails users already have Strong Parameters in place to handle white listing, but applications using Active Model and Active Record outside of a Rails environment may be impacted. All users running an affected release should either upgrade or use one of the workarounds immediately.
Versions Affected:  All. 
Not affected:       None. 
//全てのバージョンが脆弱性に引っかかる
Fixed Versions:     5.0.0.beta1.1, 4.2.5.1, 4.1.14.1, 3.2.22.1 
//3.2.22.1で直している

Impact 
------ 
Applications that pass unverified user input to the `render` method in a 
controller may be vulnerable to an information leak vulnerability. 

Impacted code will look something like this: 
// render params[:id] こういう書き方してると引っかかる?

def index 
  render params[:id] 
end 
Carefully crafted requests can cause the above code to render files from unexpected places like outside the application's view directory, and can possibly escalate this to a remote code execution attack. All users running an affected release should either upgrade or use one of the workarounds immediately.
Impact 
------ 
Due to the way that `Rails::Html::FullSanitizer` is implemented, if an attacker 
passes an already escaped HTML entity to the input of Action View's `strip_tags` 
these entities will be unescaped what may cause a XSS attack if used in combination 
with `raw` or `html_safe`. 
//viewで[strip_tags](http://railsguides.jp/action_view_overview.html#strip-tags-html)”タグを取り除く”を使ってるとダメ?
For example: 

    strip_tags("<script>alert('XSS')</script>")


All users running an affected release should either upgrade or use one of the 
workarounds immediately. 
//↓のようにすると回避できる
Workarounds 
----------- 
If you can't upgrade, please use the following monkey patch in an initializer 
that is loaded before your application: 

$ cat config/initializers/strip_tags_fix.rb 
class ActionView::Base 
  def strip_tags(html) 
    self.class.full_sanitizer.sanitize(html) 
  end 
end 
Versions Affected:  3.1.0 and newer 
Not affected:       3.0.x and older 
Fixed Versions:     5.0.0.beta1.1, 4.2.5.1, 4.1.14.1, 3.2.22.1 
//3.1.0より新しい奴は引っかかる。3.2.22.1 で直している
Impact 
------ 
When using the nested attributes feature in Active Record you can prevent the 
destruction of associated records by passing the `allow_destroy: false` option 
to the `accepts_nested_attributes_for` method. However due to a change in the 
commit [a9b4b5d][1] the `_destroy` flag prevents the `:reject_if` proc from 
being called because it assumes that the record will be destroyed anyway. 
//nested attributesをActive Recordで使っているとダメ。_destroyオプションで消そうとするとダメ?

However this isn't true if `:allow_destroy` is false so this leads to changes 
that would have been rejected being applied to the record. Attackers could use 
this do things like set attributes to invalid values and to clear all of the 
attributes amongst other things. The severity will be dependent on how the 
application has used this feature. 

All users running an affected release should either upgrade or use one of 
the workarounds immediately.
Versions Affected:  All. 
Not affected:       None. 
Fixed Versions:     5.0.0.beta1.1, 4.2.5.1, 4.1.14.1, 3.2.22.1 
//全てのバージョンは引っかかる。3.2.22.1 で直している
Impact 
------ 
A carefully crafted accept header can cause a global cache of mime types to 
grow indefinitely which can lead to a possible denial of service attack in 
Action Pack. 
//mime typesのheaderを改ざんできる?http://www.tohoho-web.com/wwwxx015.htm
All users running an affected release should either upgrade or use one of the 
workarounds immediately. 
Workarounds 
----------- 
This attack can be mitigated by a proxy that only allows known mime types in 
the Accept header. 

Placing the following code in an initializer will also mitigate the issue: 

require 'action_dispatch/http/mime_type' 

Mime.const_set :LOOKUP, Hash.new { |h,k| 
  Mime::Type.new(k) unless k.blank? 
} 
Versions Affected:  All. 
Not affected:       None. 
Fixed Versions:     5.0.0.beta1.1, 4.2.5.1, 4.1.14.1, 3.2.22.1 
//全てのバージョンは引っかかる。3.2.22.1 で直している

Impact 
------ 
Due to the way that Action Controller compares user names and passwords in 
basic authentication authorization code, it is possible for an attacker to 
analyze the time taken by a response and intuit the password. 
//レスポンス速度?を分析するとパスワードが推測できる?
//http_basic_authenticate_withメソッドを使ってるとダメ?

For example, this string comparison: 

  "foo" == "bar" 

is possibly faster than this comparison: 

  "foo" == "fo1" 

Attackers can use this information to attempt to guess the username and 
password used in the basic authentication system. 

You can tell you application is vulnerable to this attack by looking for 
`http_basic_authenticate_with` method calls in your application. 

All users running an affected release should either upgrade or use one of 
the workarounds immediately. 
Workarounds 
----------- 
If you can't upgrade, please use the following monkey patch in an initializer 
that is loaded before your application: 

$ cat config/initializers/basic_auth_fix.rb 
module ActiveSupport 
  module SecurityUtils 
    def secure_compare(a, b) 
      return false unless a.bytesize == b.bytesize 

      l = a.unpack "C#{a.bytesize}" 

      res = 0 
      b.each_byte { |byte| res |= byte ^ l.shift } 
      res == 0 
    end 
    module_function :secure_compare 

    def variable_size_secure_compare(a, b) 
      secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b)) 
    end 
    module_function :variable_size_secure_compare 
  end 
end 

module ActionController 
  class Base 
    def self.http_basic_authenticate_with(options = {}) 
      before_action(options.except(:name, :password, :realm)) do 
        authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password| 
          # This comparison uses & so that it doesn't short circuit and 
          # uses `variable_size_secure_compare` so that length information 
          # isn't leaked. 
          ActiveSupport::SecurityUtils.variable_size_secure_compare(name, options[:name]) & 
            ActiveSupport::SecurityUtils.variable_size_secure_compare(password, options[:password]) 
        end 
      end 
    end 
  end 
end