Nouveau : Datasets open source gratuits disponibles !Decouvrir →
💎
Intermediaire 25 min Rails

Securiser une application Rails

Securiser une application Rails : un tutoriel approfondi

Pourquoi Securiser une application Rails ?

Securer une application Rails est essentiel pour prévenir les attaques et protéger l'information des utilisateurs. Dans un monde où la sécurité est devenue une priorité, même une petite faille peut avoir des conséquences graves.

Un cas d'usage concret : Imaginez que vous développez un site e-commerce qui collecte des informations personnelles et financières des clients. Une faille de sécurité pourrait permettre aux pirates informatiques d'accéder à ces données sensibles, entraînant des dommages financiers, une perte de confiance de vos clients et même des poursuites judiciaires.

Prerequis

  • Connaissances en Ruby et Rails
  • Familiarité avec les bases de données SQL
  • Compréhension du concept d'authentification et d'autorisation
  • Installation de Ruby, Rails, PostgreSQL (ou une autre base de données SQL)
  • Installation de Git pour le versionnement du code

Concepts fondamentaux

1. Authentification et Autorisation

Authentification est la vérification des identités des utilisateurs. Il s'agit de savoir qui est quelqu'un.

Autorisation est la détermination des actions qu'un utilisateur peut effectuer sur l'application. Par exemple, un utilisateur normal ne devrait pas avoir accès à certaines fonctionnalités réservées aux administrateurs.

## app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      flash[:success] = 'Connexion réussie'
      redirect_to root_url
    else
      flash.now[:danger] = 'Identifiants invalides'
      render 'new'
    end
  end

  def destroy
    log_out if logged_in?
    flash[:success] = 'Déconnexion réussie'
    redirect_to root_url
  end
end

2. Hashing des mots de passe

Le mot de passe d'un utilisateur ne devrait jamais être stocké en clair dans la base de données. C'est pourquoi nous utilisons un algorithme de hachage pour stocker les mots de passe.

## app/models/user.rb
class User < ApplicationRecord
  has_secure_password
end

3. Cookies sécurisés

Les cookies doivent être sécurisés pour éviter que des attaques comme le man-in-the-middle ne puissent accéder aux informations stockées.

## config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, key: '_your_app_session', expire_after: 90.minutes, secure: Rails.env.production?

4. Protection contre les Cross-Site Scripting (XSS)

L'XSS est une attaque où un attaquant injecte du code malveillant dans une page web pour être exécuté par d'autres utilisateurs.

<%= sanitize @comment.content %>

5. Protection contre les Cross-Site Request Forgery (CSRF)

Le CSRF est une attaque où un attaquant force l'utilisateur à effectuer des actions non voulues sur votre site web.

## app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
end

6. Gestion des erreurs

Il est important de gérer les erreurs avec prudence pour éviter des informations sensibles d'être révélées aux utilisateurs.

## app/controllers/users_controller.rb
class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
    rescue ActiveRecord::RecordNotFound
      flash[:danger] = 'Utilisateur non trouvé'
      redirect_to root_url
  end
end

Mise en pratique : projet fil rouge

Mini-projet : Gestionnaire de tâches

  1. Créer un nouveau projet Rails

    rails new task_manager -d postgresql
    cd task_manager
    
  2. Générer le modèle User

    rails generate model User name:string email:string password_digest:password
    rake db:migrate
    
  3. Générer le contrôleur Sessions

    rails generate controller Sessions new create destroy
    
  4. Ajouter les routes pour les sessions

    # config/routes.rb
    resources :sessions, only: [:new, :create, :destroy]
    get 'logout', to: 'sessions#destroy'
    
  5. Implémenter l'authentification

    # app/controllers/sessions_controller.rb
    class SessionsController < ApplicationController
      def new; end
    
      def create
        user = User.find_by(email: params[:session][:email].downcase)
        if user && user.authenticate(params[:session][:password])
          log_in user
          flash[:success] = 'Connexion réussie'
          redirect_to root_url
        else
          flash.now[:danger] = 'Identifiants invalides'
          render 'new'
        end
      end
    
      def destroy
        log_out if logged_in?
        flash[:success] = 'Déconnexion réussie'
        redirect_to root_url
      end
    
      private
    
      def user_params
        params.require(:user).permit(:email, :password)
      end
    end
    
  6. Ajouter la vue pour les sessions

    <!-- app/views/sessions/new.html.erb -->
    <%= form_for @session do |f| %>
      <div class="form-group">
        <%= f.label :email %>
        <%= f.text_field :email, class: 'form-control' %>
      </div>
      <div class="form-group">
        <%= f.label :password %>
        <%= f.password_field :password, class: 'form-control' %>
      </div>
      <div class="form-group">
        <%= f.submit 'Connexion', class: 'btn btn-primary' %>
      </div>
    <% end %>
    
  7. Ajouter la vue pour les tâches

    <!-- app/views/tasks/new.html.erb -->
    <%= form_for @task do |f| %>
      <div class="form-group">
        <%= f.label :name %>
        <%= f.text_field :name, class: 'form-control' %>
      </div>
      <div class="form-group">
        <%= f.submit 'Ajouter', class: 'btn btn-primary' %>
      </div>
    <% end %>
    
  8. Générer le modèle Task

    rails generate model Task name:string description:text user_id:integer
    rake db:migrate
    
  9. Ajouter la relation entre User et Task

    # app/models/user.rb
    class User < ApplicationRecord
      has_secure_password
      has_many :tasks
    end
    
    # app/models/task.rb
    class Task < ApplicationRecord
      belongs_to :user
    end
    
  10. Générer le contrôleur Tasks

    rails generate controller Tasks new create index show edit update destroy
    
  11. Ajouter les routes pour les tâches

    # config/routes.rb
    resources :tasks, except: [:new, :edit]
    
  12. Implémenter l'index et le show des tâches

    # app/controllers/tasks_controller.rb
    class TasksController < ApplicationController
      before_action :logged_in_user
    
      def index
        @tasks = current_user.tasks.order(created_at: :desc)
      end
    
      def show
        @task = current_user.tasks.find(params[:id])
      rescue ActiveRecord::RecordNotFound
        flash[:danger] = 'Tâche non trouvée'
        redirect_to root_url
      end
    
      private
    
      def logged_in_user
        unless logged_in?
          store_location
          flash[:danger] = 'Veuillez vous connecter pour accéder à cette page.'
          redirect_to login_url
        end
      end
    end
    
  13. Ajouter les vues pour l'index et le show des tâches

    <!-- app/views/tasks/index.html.erb -->
    <h1>Mes tâches</h1>
    <ul>
      <% @tasks.each do |task| %>
        <li><%= task.name %> - <%= link_to 'Détails', task_path(task) %></li>
      <% end %>
    </ul>
    <%= link_to 'Nouvelle tâche', new_task_path %>
    erb
    <!-- app/views/tasks/show.html.erb -->
    <h1><%= @task.name %></h1>
    <p><%= @task.description %></p>
    <%= link_to 'Retour', tasks_path %>
    

Erreurs frequentes et debugging

1. ActionController::ParameterMissing

Cause : L'erreur se produit lorsqu'un paramètre est attendu mais pas présent dans la requête.

## ❌ Mauvais
def create
  @task = Task.new(task_params)
end

## ✅ Correct
def create
  @task = Task.new(task_params)
end

2. ActiveRecord::RecordNotFound

Cause : L'erreur se produit lorsqu'une ressource n'est pas trouvée dans la base de données.

## ❌ Mauvais
@user = User.find(params[:id])

## ✅ Correct
@user = User.find_by(id: params[:id])

3. ActionDispatch::Cookies::CookieOverflowError

Cause : L'erreur se produit lorsqu'un cookie dépasse la taille maximale autorisée.

## ❌ Mauvais
cookies[:big_cookie] = '...' * 1000

## ✅ Correct
session[:big_session] = '...' * 1000

Pour aller plus loin

1. Authentification avec OAuth2

Intégrez l'authentification avec des services tiers comme Google, Facebook ou GitHub pour une expérience utilisateur plus facile et sécurisée.

2. Sécurité de l'API

Protégez votre API contre les attaques courantes en utilisant des mécanismes comme JWT (JSON Web Tokens) et CORS (Cross-Origin Resource Sharing).

3. Sécurité des formulaires

Utilisez les helpers de Rails pour créer des formulaires sécurisés, en utilisant form_with et en vérifiant les paramètres avec strong_parameters.

## app/controllers/users_controller.rb
class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
    if @user.save
      log_in @user
      flash[:success] = 'Compte créé avec succès'
      redirect_to @user
    else
      render 'new'
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :password, :password_confirmation)
  end
end

Défi pratique

Créez une application API RESTful pour gérer des utilisateurs et leurs tâches. Utilisez les gems jwt et cancancan pour la gestion des autorisations.

En suivant ce tutoriel, vous aurez une bonne compréhension de la sécurité en Rails et pourrez mettre en place des mesures efficaces pour protéger vos applications.

Besoin d'aide sur Rails ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Comment sécuriser les mots de passe des utilisateurs dans une application Rails?
Utilisez le gem 'bcrypt' pour hasher les mots de passe avant de les stocker en base de données. Activez également la vérification du mot de passe au moment de l'authentification.
Quelles sont les meilleures pratiques pour protéger contre les injections SQL dans une application Rails?
Utilisez les ActiveRecord::Relation#where pour construire des requêtes SQL sécurisées. Évitez d'utiliser directement les paramètres non-sanitaires dans vos requêtes.
Comment configurer le SSL sur une application Rails pour protéger la confidentialité?
Ajoutez la ligne `config.force_ssl = true` dans votre fichier de configuration environnemental (development.rb, production.rb). Assurez-vous que votre serveur web est configuré pour utiliser un certificat SSL.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.