prix-fixe

Expand History Expand History
Collapse History Collapse History

Enable Request Forgery Protection in test

If we’re feeling skeptical that the application’s behavior does meet the criteria as defined in our test suite, we can boot it locally and visit it in a web browser ourselves:

$ rails server --port 3000

Once it’s running, we can follow the instructions described in our system test by opening a web browser and:

  • visiting http://localhost:3000/
  • clicking on “Share a Note”
  • filling in the text box labelled “Message” with the value “Hello, World”
  • clicking on “Share”

Oh no!

Surprisingly, our server responds to our submission with an error page.

If we inspect our rails server process log, it contains the following output:

Started POST "/notes" for ::1 at 2019-05-04 13:37:35 -0400
Processing by NotesController#create as HTML
  Parameters: {"content"=>"Hello, World"}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 461)

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):

By default, Rails comes with some security-minded default behavior. In this case, the error’s mention of being unable to verify CSRF token authenticity stems from Rails’ Cross Site Request Forgery Protection.

The Rails Security Guidelines describe CSRF:

This attack method works by including malicious code or a link in a page that accesses a web application that the user is believed to have authenticated. If the session for that web application has not timed out, an attacker may execute unauthorized commands.

By default, this protective measure is in place in every Rails Environment except for test.

To ensure that all environments have this protection in place, this commit enables CSRF protection in test.rb.

When we run the test again, it is no longer passing.

It fails with a new error:

Error:
UserSharesAMessageTest#test_visiting_the_index:
DRb::DRbRemoteError: ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken)

In this instance, regressing from the Green Phase to the Red Phase has a positive effect. Since our test environment’s behavior did not have parity with the other environments, a test failure uncovering that fact is helpful and important to address.

In cases like this that uncover important gaps in behavior, we can consider transitioning from the Green Phase to Red Phase as a temporary (but helpful!) detour toward the Refactoring Phase.