Limiter le nombre d’actions par minute pour les utilisateurs authentifiés - #6327
Conversation
1b0aef5 to
5f2e228
Compare
| from rest_framework import throttling | ||
|
|
||
|
|
||
| class FailSafeUserRateThrottle(throttling.UserRateThrottle): |
There was a problem hiding this comment.
Je suis un peu chagrin par l'implémentation de DRF qui porte bien son nom SimpleRateThrottle 😬
Mais bon elle a le mérite d'être simple à lire et sûrement suffisant pour notre besoin.
Est-ce qu'on a confiance en notre redis ? Et si ce n'est pas le cas, est-ce qu'il ne faudrait pas l'activer progressivement en surchargeant get_cache_key et en renvoyant None pour 90% des utilisateurs puis 80%, etc ?
There was a problem hiding this comment.
On utilise le failsafe. S’il tombe, on laissera passer toutes les requêtes. Bon, les tâches async en revanche... 🙈
Je viens de tester, le script suivant utilise 185 MB de RAM (RSS) (d’après l’output de INFO MEMORY).
import random
from datetime import datetime
import django
def main():
from django.core.cache import caches
cache = caches["failsafe"]
now_ts = datetime.now().timestamp()
for i in range(1_000_000):
cache.set(i, [now_ts] * random.randint(1, 10), 3600)
if __name__ == "__main__":
django.setup()
main()Notre redis (taille S) a 100 MB d’espace disque, on pourrait le passer en L pour avoir 500 MB. On passerait à 20 € par mois.
There was a problem hiding this comment.
Après une petite analyse datadog, on a max 500 utilisateurs concurrents sur une minute. Donc stocker leur historique (même s’il fait 60 requêtes) ne posera pas de soucis.
Un test plus réaliste montre 15MB used_memory_rss_human (2 MB en used_memory_human).
|
C'est super ! |
La limite de On peut suivre le nombre de 429 suite au déploiement et vérifier qu’on n’impacte pas trop les utilisateurs, et décider de l’augmenter si besoin. |
tonial
left a comment
There was a problem hiding this comment.
Ça me parait très bien comme solution.
On pourra toujours améliorer dans le futur si c'est nécessaire 🤷
Helps identifying and preventing enumeration. In order to render a complete menu, the RateLimitMiddleware must be placed after the ItouCurrentOrganizationMiddleware.
5f2e228 to
de632c3
Compare
🤔 Pourquoi ?
Sécurité : mieux identifier et bloquer les énumérations.
🍰 Comment ?
Afin de pouvoir effectuer un rendu complet de la page de 429, il faut que le middleware soit placé après
ItouCurrentOrganizationMiddleware.🏝️ Comment tester ?
Le testeur malin changera la limite à une requête par minute.
💻 Captures d'écran