Une checklist de sécurité pragmatique pour les applications Ruby on Rails
Les quelques récidivistes derrière la plupart des incidents de sécurité Rails, dans l'ordre où nous les vérifions lors d'un audit.
Publié le 4 février 2024 · 5 min de lecture
La plupart des incidents de sécurité Rails que nous avons été appelés à analyser a posteriori remontent à une poignée de récidivistes, pas à des zero-days. Voici la checklist que nous appliquons réellement lors d'un audit, dans l'ordre où nous la déroulons.
1. Mass assignment et strong parameters
Toujours le constat le plus fréquent : un contrôleur qui autorise plus d'attributs que le formulaire n'en envoie réellement, souvent parce que quelqu'un a ajouté un permit généralisé pour faire passer un test récalcitrant et ne l'a jamais retiré. Chaque liste de permit doit être une liste blanche délibérée et relue, jamais un raccourci.
2. L'autorisation, pas seulement l'authentification
Un cookie de session vous dit qui est connecté. Il ne dit rien de ce que cet utilisateur a le droit de toucher. Nous trouvons régulièrement des actions de contrôleur qui vérifient qu'un utilisateur est présent et s'arrêtent là, laissant n'importe quel utilisateur authentifié charger l'enregistrement d'un autre compte en devinant un id. Des policies Pundit ou CanCanCan, appliquées de façon cohérente et testées, comblent cette faille ; des vérifications ad hoc dispersées dans les contrôleurs, non.
class InvoicePolicy < ApplicationPolicy
def show?
record.account_id == user.account_id
end
end
3. SQL brut et interpolation de chaînes
ActiveRecord vous protège par défaut, jusqu'à ce que quelqu'un passe en SQL brut pour un rapport rapide et interpole un paramètre directement dans la chaîne. Liez toujours les paramètres, même dans une tâche rake que personne ne pense exécuter deux fois.
# Vulnerable
Invoice.where("status = '" + params[:status] + "'")
# Safe
Invoice.where(status: params[:status])
4. Secrets dans le dépôt
Les credentials Rails règlent proprement ce problème, mais seulement si chaque environnement les utilise réellement. Nous trouvons encore des clés d'API codées en dur dans des initializers « temporairement », commitées des années plus tôt.
5. Fraîcheur des dépendances
Un outil d'audit tournant en CI, qui bloque réellement les merges, et non un simple avertissement dans les logs que personne ne lit. Une vulnérabilité connue qui traîne huit mois dans un lockfile est le constat le plus facile de toute revue.
6. Rate limiting sur tout ce qui touche à l'argent ou à l'authentification
Les endpoints de connexion, de réinitialisation de mot de passe et de paiement sans rate limiting sont une invitation ouverte au credential stuffing. Un middleware de limitation de requêtes couvre l'essentiel du sujet en quelques lignes de configuration.
Rien de tout cela n'est avancé. C'est précisément pourquoi cela vaut la peine d'être vérifié à intervalles réguliers plutôt que de compter sur la mémoire de quelqu'un.
Articles liés
Gérer des données de santé sensibles avec Rails : les bases de la sécurité et de la conformité pour la HealthTech
Construire une application Rails qui manipule des données de santé change le niveau d'exigence de base. Notes sur le chiffrement au niveau des champs, l'audit des accès et les exigences d'hébergement HDS.
Concevoir une architecture de services Rails autour de SEPA et des flux de paiement
Les paiements changent les questions de conception auxquelles une codebase Rails doit répondre. Notes sur l'isolation des mouvements d'argent, les ledgers, et la modélisation de SEPA comme le processus asynchrone qu'il est.