<div class="widget">
    <div class="widget-header">
      <div class="title">
        <span class="fs1" aria-hidden="true" data-icon="&#xe092;"></span> Constantize
      </div>
    </div>
    <div class="widget-body">
      <div id="accordion1" class="accordion no-margin">
        <div class="accordion-group">
          <div class="accordion-heading">
            <a href="#collapseOne" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
              <i class="icon-info icon-white">
              </i>
              Description
            </a>
          </div>
          <div class="accordion-body in collapse" id="collapseOne" style="height: auto;">
            <div class="accordion-inner">
             <p class="desc">
			   The constantize method is a Rails MetaProgramming method designed to dynamically find a constant that matches the string specified. This is often used to dynamically instantiate a class or module. When user-supplied input is a part of that equation, great precautions must be taken to ensure security holes are not introduced.
			 </p>
            </div>
          </div>
        </div>
        <div class="accordion-group">
          <div class="accordion-heading">
            <a href="#collapseTwo" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
              <i class="icon-bug icon-white">
              </i>
              Bug
            </a>
          </div>
          <div class="accordion-body collapse" id="collapseTwo" style="height: 0px;">
            <div class="accordion-inner">
              <p>
				Within the file app/controllers/benefit_forms_controller.rb:
			  </p>
			  <pre class="ruby">
				  def download
			   		begin  
			   		  <span style="background-color:yellow">path = Rails.root.join('public', 'docs', params[:name])</span>
			   		  <span style="background-color:yellow">file = params[:type].constantize.new(path)</span>
			   		  send_file file, :disposition => 'attachment'
			   		rescue
			   		  redirect_to user_benefit_forms_path(:user_id => current_user.user_id)
			   		end
			  	  end
			  </pre>
			  <p class="desc">
				The location of the file to render is dynamically generated based on user input (params[:name]). This means the user controls the location of the file to be retrieved. Additionally, the params[:type] (File) is not validated to make sure it matches up with expected values.
			  </p>	 	
            </div>
          </div>
        </div>
        <div class="accordion-group">
          <div class="accordion-heading">
            <a href="#collapseThree" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
              <i class="icon-lightning icon-white">
              </i>
              Solution
            </a>
          </div>
          <div class="accordion-body collapse" id="collapseThree" style="height: 0px;">
            <div class="accordion-inner">
               <p><b> Constantize ATTACK:</b></p>
			   <p class="desc">
				In order to attack this weakness, navigate to the benefit forms page and observe the link to download either the health or dental documents.
			   </p>	
			   <pre class="ruby">
				 http://railsgoat.dev/download?name=Health_n_Stuff.pdf&type=File
			   </pre> 
			   <p>
				Change the name parameter to something a little more fun like:
			    </p>
			    <pre class="ruby">
			 		http://railsgoat.dev/download?name=../../config/initializers/secret_token.rb&type=File
				</pre>
				<p class="desc">
					This second request string specifies to navigate back two directories and then look for config/intiializers/secret_token.rb. It is important to note, even when Rails.root.join is used, leveraging path traversal (ex: ../../) allows the attacker to retrieve any file that the application's user has permissions to.<br/><br/>  Example:
				</p>	
				<pre class="ruby">
					../../../../../../../etc/passwd&type=File
				</pre>	
			   <p><b> Constantize SOLUTION:</b></p>
			   <p class="desc">
				 In this instance and as always, there are multiple ways to fix this. A simple method to secure this function by validating user input is as follows:
			   </p>
			    <pre class="ruby">
					# More secure version
				    def download
				     <span style="background-color:yellow">file_assoc = {"1" => "Health_n_Stuff.pdf", "2" => "Dental_n_Stuff.pdf"}</span>
				     begin  
				       <span style="background-color:yellow">if file_assoc.has_key?(params[:name].to_s)</span>
				          path = Rails.root.join('public', 'docs', file_assoc[params[:name].to_s])
				          <span style="background-color:yellow">if params[:type] == "File"</span>
				            file = params[:type].constantize.new(path)  
				            send_file file, :disposition => 'attachment'
				          end 
				       else 
				         file =  Rails.root.join('public', 'docs', "Dental_n_Stuff.pdf")
				         send_file file, :disposition => 'attachment'
				       end
				     rescue
				       redirect_to user_benefit_forms_path(:user_id => current_user.user_id)
				     end
				    end
				</pre>
				<p class="desc">
					The fix ultimately boils down to leveraging a hash, if the hash has the key provided by the user, the value associated with that key is the name of the file to be returned.
				</p>	
            </div>
          </div>
        </div>
     	<div class="accordion-group">
          <div class="accordion-heading">
            <a  style="background-color: rgb(181, 121, 158)" href="#collapseFour" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
              <i class="icon-aid icon-white">
              </i>
              Hint
            </a>
          </div>
          <div class="accordion-body collapse" id="collapseFour" style="height: 0px;">
            <div class="accordion-inner">
              It can be very helpful for employees to download benefit forms.
            </div>
          </div>
        </div> 
	 </div>
    </div>
  </div>