diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-04-17 16:50:39 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-05-05 11:37:34 -0300 |
commit | 0f3b7d1a319383f743f9938e1eed00f0fba7a367 (patch) | |
tree | 57e8072a1d25458442a9cec90bd687dedf271f9b /actionpack/lib/abstract_controller/base.rb | |
parent | 666e9f65bdfeb6cc5aa80b6254608adc3d7845ce (diff) | |
download | rails-0f3b7d1a319383f743f9938e1eed00f0fba7a367.tar.gz rails-0f3b7d1a319383f743f9938e1eed00f0fba7a367.tar.bz2 rails-0f3b7d1a319383f743f9938e1eed00f0fba7a367.zip |
Only accept actions without File::SEPARATOR in the name.
This will avoid directory traversal in implicit render.
Fixes: CVE-2014-0130
Diffstat (limited to 'actionpack/lib/abstract_controller/base.rb')
-rw-r--r-- | actionpack/lib/abstract_controller/base.rb | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index fd6a46fbec..2541125ec6 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -112,7 +112,7 @@ module AbstractController def process(action, *args) @_action_name = action_name = action.to_s - unless action_name = method_for_action(action_name) + unless action_name = _find_action_name(action_name) raise ActionNotFound, "The action '#{action}' could not be found for #{self.class.name}" end @@ -138,7 +138,7 @@ module AbstractController # available action consider actions that are also available # through other means, for example, implicit render ones. def available_action?(action_name) - method_for_action(action_name).present? + _find_action_name(action_name).present? end private @@ -182,6 +182,23 @@ module AbstractController end # Takes an action name and returns the name of the method that will + # handle the action. + # + # It checks if the action name is valid and returns false otherwise. + # + # See method_for_action for more information. + # + # ==== Parameters + # * <tt>action_name</tt> - An action name to find a method name for + # + # ==== Returns + # * <tt>string</tt> - The name of the method that handles the action + # * false - No valid method name could be found. Raise ActionNotFound. + def _find_action_name(action_name) + _valid_action_name?(action_name) && method_for_action(action_name) + end + + # Takes an action name and returns the name of the method that will # handle the action. In normal cases, this method returns the same # name as it receives. By default, if #method_for_action receives # a name that is not an action, it will look for an #action_missing @@ -203,11 +220,16 @@ module AbstractController # # ==== Returns # * <tt>string</tt> - The name of the method that handles the action - # * <tt>nil</tt> - No method name could be found. Raise ActionNotFound. + # * <tt>nil</tt> - No method name could be found. def method_for_action(action_name) if action_method?(action_name) then action_name elsif respond_to?(:action_missing, true) then "_handle_action_missing" end end + + # Checks if the action name is valid and returns false otherwise. + def _valid_action_name?(action_name) + action_name.to_s !~ Regexp.new(File::SEPARATOR) + end end end |