从URL动态启动会话的最佳方式

时间:2013-11-18 07:06:15

标签: jquery ruby-on-rails security session sinatra

我只是在用户点击浏览器中的按钮时才尝试在Rails中创建会话。使用jQuery进行此操作的最佳方法是什么?

类似这样的实际用途可能是:

  • 防止警报一旦关闭就再次显示。
  • 记住有关不同阶段用户的信息。
  • 操作完成后保存基本的一次性设置。

我想出了这个:

HTML:

<button id="startSession">Start a Session!</button>  

jQuery:

$("#startSession").click(function() {
  $.ajax({
    url: "/sessions-manager?add=funkysession"
  });
});

然后控制器看起来像:

get "/sessions-manager" do
  name = params[:add].to_sym
  session[name] = true  #=> session[:funkysession] = true

  # A session named "funkysession" has now been started
end
但是,我觉得这种方式可以开放利用。例如,人们可以手动打入/sessions-manager?add=user并伪造用户会话以访问我的应用程序的受保护区域。是否有更安全的方式开始会议?

1 个答案:

答案 0 :(得分:0)

我找到了两个可能解决这个问题的方法。

选项1:在AJAX请求中发送自定义标题

这背后的想法是设置一个自定义HTTP标头与实际的AJAX请求一起发送,然后在控制器中检查。这意味着人们无法在其Web浏览器的URL栏中手动与/sessions-manager路由成功交互。可以使用jQuery轻松设置自定义标头:

$("#startSession").click(function() {
  $.ajax({
    url: "/sessions-manager?add=showpassword",
    beforeSend: function(xhr){xhr.setRequestHeader('foo', 'bar');}
  });
});

现在只需检查控制器中是否存在自定义标头:

get "/sessions-manager" do
  if env["foo"] == "bar"
    // Add session
  else
    halt 401 // Authentication required error
  end
end

关于此方法的附注:虽然这肯定是保护/sessions-manager路线的有效方法,但它仍然可能会受到损害。知道他们正在做什么的人可以使用开发人员工具伪造HTTP标头,因此选项2可能适合您。尽管如此,这仍然是一个很好的策略,可以作为额外的保护层来实现,只要知道它的限制。

选项2(首选):多个会话级别

比特币策划者Sam Foley引起我注意的一个更有效的解决方案是限制可以通过/sessions-manager URL创建的会话范围。这可以通过向您要创建的会话添加另一个级别来轻松实现,即 - 为会话提供父级&gt;孩子的关系。看看:

get "/sessions-manager" do
  session[:userprefs] ||= {} // Set parent session as empty hash
  name = params[:add].to_sym
  session[:userprefs][:name] = true
end

好多了。现在我们可以在我们的应用程序(视图或控制器)中的任何位置访问此会话:

if session[:userprefs][:showpassword] 
  "Password is blah"
end 

更重要的是,人们不能打造现有的会议。例如,有人试图伪造用户会话,现在将创建一个名为[:userprefs][:user]的会话,这个会话实际上没用。