Sergey Khmelevskoy
Sergey Khmelevskoy

Reputation: 2544

Is it safe to pass params via hidden tag in Rails 4?

Im just started learning Rails and trying to make my first application. Just wondering if it's ok to use constructions like this

      <%= form_tag create_message_path, :method => :post do %>
          <%= text_area_tag "message", nil %>
          <%= hidden_field_tag "receiver", @order.printer.user.id %>
          <%= hidden_field_tag "order_id", @order.id %>
          <%= submit_tag "Submit" %>
      <% end %>

And basic strong params.

class MessagesController < ApplicationController
  before_action :correct_user, only: [:update, :destroy]

  def create
    if current_user
      @message = current_user.messages.build(message_params)

      if @message.save
        flash[:success] = "Сообщение создано"
        redirect_to :back
      else
        redirect_to :back
      end
    else
      redirect_to login_path
    end
  end


  private
    def message_params
      params.permit(:message, :read, :receiver, :user_id, :printer_id, :order_id )
    end
    def correct_user
      @message = current_user.messages.find_by(id: params[:id])
      redirect_to root_url if @message.nil?
    end

end

Isn't it a thread? Can user change html input value and send some info (like message to be send to other order) ?

EDIT 1:

  @order = Order.find(params[:id])
  message_item = {
    user_id: current_user.id,
    receiver: @order.printer.user.id,
    message: params[:message],
    order_id: @order.id
  }

  @message = current_user.messages.build(message_item)

Upvotes: 2

Views: 766

Answers (4)

Neil McGuigan
Neil McGuigan

Reputation: 48256

For sensitive data like this, you should either use server-side session variables (simplest) or use an HMAC to validate that the data wasn't changed by the client.

Template:

<input type=hidden name=foo value=bar>
<input type=hidden name=hmac value=<%=hmac($serverSecret + "foo=bar")%>>

Then on form submit, recalculate the HMAC based on $serverSecret, and the claimed value of $foo, and make sure it's the same as the claimed value of $hmac

Upvotes: 2

user4776684
user4776684

Reputation:

First, hidden params can be changed, and they are not good for any sensitive information.

Second, remove those params from your message_params method. You don't want to allow them in params hash (no params that are not on your form should be allowed):

params.permit(:message, :read)

Also, you might want to remove :read too because most likely you will set it in some other controller action.

Third, you set those params by assignment:

@message = current_user.messages.build(message_params)
@message.receiver = @order.printer.user.id
@message.order_id = @order.id

Note, you don't need to write @message.user_id = current_user.id because it will be done for you by Rails.

Upvotes: 5

Josh K
Josh K

Reputation: 765

You are correct, the term hidden only describes that there is no control shown for that input. However, anyone could use the page inspector to change the value or POST to the destination URL of the form with any value they want. You should always ensure that the values you receive through hidden fields are within ranges you allow.

Upvotes: 4

F. Stephen Q
F. Stephen Q

Reputation: 4306

A user can absolutely change these values, and can send whatever data they want. You should not use hidden tags to pass any truly sensitive data, and you should assume that an attacker can change them to whatever they want. In practice, hidden fields are good for passing some configuration/context information, and for brute-force attack/DoS protection tokens. For example, you could use a hidden field to pass in a value specifying that this is a search or login request, but would be inappropriate for specifying that a request was issued by an administrator, or which user was making the request.

Upvotes: 2

Related Questions