【问题标题】:Rails integration test against page modification hack?针对页面修改黑客的 Rails 集成测试?
【发布时间】:2012-04-21 21:03:00
【问题描述】:

我正在使用 Capybara 1.1.2、Rails 3.1.3、rspec-rails 2.9.0 和 Ruby 1.9.3p0。

假设应用具有标准用户和 account_admin 用户。标准用户可以创建另一个标准用户,但标准用户不能创建 account_admin 用户。

当然,用户界面不会为标准用户提供创建帐户管理员的选项。但是使用 Firebug 需要 30 秒,并且用户可以重写 HTML,因此它会提交一个 POST 请求来创建一个 account_admin。

如何测试我的应用是否能防止这种简单的黑客攻击?

正常的标准用户测试如下所示:

context "when standard user is signed in" do

  before do
    login_as standard_user
    visit users_path       # go to index
    click_link('Add user') # click link like user would
  end

  describe "when fields are filled in" do

    let(:new_email) { "new_user@example.com" }

    before do
      fill_in "Email", with: new_email
      fill_in "Password", with: "password"
      fill_in "Password confirmation", with: "password"
      choose "Standard user" # radio button for Role
    end

    it "should create a user" do
      expect { click_button submit }.to change(User, :count).by(1)
    end

  end

end

有没有办法“欺骗”测试以获取表单上不允许的值?我尝试将单选按钮视为文本字段,但 Capybara 将其视为不存在的字段:

fill_in "Role", with: "account_admin" # doesn't work

直接修改参数哈希也不起作用:

params[:role] = "account_admin" # doesn't work

我是否必须将其编写得更像一个控制器测试,直接调用post :create

【问题讨论】:

    标签: ruby-on-rails-3 capybara rspec-rails


    【解决方案1】:

    Capybara 作者 jnicklas 确认 here Capybara 无法让应用程序执行 UI 中不可用的操作。他建议对控制器进行授权测试。

    但是, 使用 Capybara 语法以 RSpec 编写的请求规范确实允许直接使用 HTML 动词(和一些额外的帮助器),如 RSpecRails 文档中所述。因此,您可以使用属性哈希、getpostpost_via_redirect 等动词和 response.body 对象,而不是 Capybara 的 fill_inclick_link 指令和 page 对象。它类似于控制器测试,但您使用 Rails 的路由根据提供的路径选择适当的控制器操作。以下是后一种技术的示例:

    describe "when standard user attempts to create account_admin user" do
    
      let(:standard_user) { FactoryGirl.create(:standard_user) }
    
      let(:attr) { { email: "account_admin@example.com",
                     password: "password",
                     password_confirmation: "password",
                     role: "account_admin" }
                  }
    
      before do
        login_as standard_user
        get new_user_path
      end
    
      it "should not create a account_admin user" do
        lambda do
          post users_path, user: attr
        end.should_not change(User, :count)
      end
    
      describe "after user posts invalid create" do
        before { post_via_redirect users_path, user: attr }
    
        # redirect to user's profile page
        it { response.body.should have_selector('title', text: 'User Profile') }
        it { response.body.should have_selector('div.alert.alert-error', text: 'not authorized') }
      end
    
    end  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2011-10-03
      • 2017-07-15
      • 2011-08-17
      • 2021-08-20
      相关资源
      最近更新 更多