Protection Against Form Modification

Learn about user and role protection, the issues we'll face, make design decisions, and learn to write request tests for the user and role protection.

Preventing form modification

There is at least one blind spot in the user and role protection. The project show page has a form that submits a new task. That form is submitted to the TasksController, which doesn’t handle any user-access control. The use case here is a malicious user not going through the web UI but rather creating his own HTTP request and pointing it at the server.

Issues

There are two important issues here, at least from our perspective as Rails Testing Author. First is the habit of noticing when we’re using a resource that’s being accessed as a result of a user request instead of being stored server-side. This is even true when the resource is protected indirectly, as in this case, where we’re accessing a Task that belongs to the Project, the access control is attached. Second, we need to discuss how to test such a case.

We have two similar cases to deal with: task creation from the project form via TaskController#create and any updates and move task methods in the controller.

Design decisions

Let’s plan the create test. For the “given” we need a user, a project that the user belongs to, and a project the user doesn’t belong to. The “when” is the creation of the task, and the “then” is whether the task is created or not.

The design question is where to put the access check and where to write the test by extension. We’re at a slight disadvantage here because the potentially malicious request is coming from outside the UI, Capybara isn’t going to be effective in crafting an integration test. We also didn’t really write the full add-task feature before. We just kind of assumed its existence.

Request tests

In other words, we can’t easily write an integration test for this because the situation is outside the regular UI. If users don’t have the ability to create a task, they also don’t have the ability to see the project page. So, we somewhat reluctantly turn to a request spec. If the functionality were much more complex, we’d probably add Pundit and unit-test the Pundit object:

Get hands-on with 1200+ tech skills courses.