So what is CSRF? It stands for Cross-Site Request Forgery and it basically means someone can trick you into doing something on a website without even realizing it. Let me give you an example: let’s say you have an online banking account, and you log in to check your balance. But then, while you’re browsing other websites (like Facebook or Twitter), some malicious hacker sends you a link that looks like this: https://yourbank.com/transfer?amount=1000&to_account=hacker-account
Now, if you click on that link without realizing what it does, your browser will send a request to the bank’s server asking for $1000 to be transferred to the hacker’s account. And since you’re already logged in to the bank’s website, this request will look like it came from you even though you didn’t actually intend to do that!
To prevent CSRF attacks, Rails provides a built-in helper method called `csrf_meta_tags` which adds some hidden fields to your HTML forms. These fields contain a unique token (called a “CSRF token”) that is generated by the server and sent back to the client in each response. When you submit a form, this token is included as a parameter in the request so if someone tries to forge a request from another website, they won’t have access to your CSRF token and their request will be rejected.
To use `csrf_meta_tags` in your Rails app, just add it to your layout file (usually called “application.html.erb”):
# This line calls the `csrf_meta_tags` method and inserts the returned value into the HTML document.
# This method generates a meta tag with a CSRF token, which is used to protect against cross-site request forgery (CSRF) attacks.
# The `csrf_meta_tags` method is provided by Rails and is typically used in the layout file of a Rails application.
<%= csrf_meta_tags %>
That’s it! Now all of your forms will be protected against CSRF attacks by default.
But what if you want to customize the CSRF token or add some extra security measures? Well, Rails provides a few options for that as well:
– You can generate a new CSRF token using `form_authenticity_token` in your controller:
# This method creates a new item using the parameters passed in from the form.
def create
@item = Item.new(params[:item])
# The '@' symbol indicates an instance variable, which can be accessed by other methods within the same class.
# 'Item' refers to the Item model, which is used to interact with the database.
# 'params[:item]' accesses the parameters passed in from the form, which are used to create the new item.
@item.save
# This saves the new item to the database.
head :ok
# This returns a successful response with a status code of 200.
end
This will add the following line to your HTML form:
<!-- This code adds a hidden input field to an HTML form. -->
<input type="hidden" name="_csrf_token" value="f0c1a5e8b94732ab67df"> <!-- The "hidden" type ensures that the field is not visible to the user. -->
<!-- The "name" attribute specifies the name of the field, which will be used to identify it when the form is submitted. -->
<!-- The "value" attribute sets the value of the field, in this case a randomly generated token for security purposes. -->
– You can also set a custom CSRF token using `protect_from_forgery` in your application controller:
# This is a class definition for the ApplicationController class, which inherits from the ActionController::Base class.
class ApplicationController < ActionController::Base
# This line sets up protection from cross-site request forgery (CSRF) attacks by using the :exception option.
protect_from_forgery with: :exception
end
This will generate a new CSRF token for each request and add it to the response headers. You can then use this token in your JavaScript code (or any other client-side script) to prevent CSRF attacks on AJAX requests:
// This function makes an AJAX request to the "/items" endpoint, expecting a JSON response.
$.ajax({
url: "/items",
dataType: "json",
// Before sending the request, set the "X-CSRF-Token" header to the value of the "csrf-token" meta tag.
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRF-Token", $('meta[name="csrf-token"]').attr("content"));
},
success: function(data) {
// Upon successful response, handle the data returned from the server.
// This is where you can perform any necessary actions or manipulations on the data.
}
});
And that’s it! With these simple steps, you can protect your Rails app from CSRF attacks and keep your users safe.