Browse Source

Use rate limiting to prevent auth floods

sh4nks 9 years ago
parent
commit
c3dacf693f
3 changed files with 22 additions and 1 deletions
  1. 4 1
      flaskbb/app.py
  2. 13 0
      flaskbb/auth/views.py
  3. 5 0
      flaskbb/extensions.py

+ 4 - 1
flaskbb/app.py

@@ -35,7 +35,7 @@ from flaskbb.forum.views import forum
 from flaskbb.forum.models import Post, Topic, Category, Forum
 # extensions
 from flaskbb.extensions import db, login_manager, mail, cache, redis_store, \
-    debugtoolbar, migrate, themes, plugin_manager, babel, csrf, allows
+    debugtoolbar, migrate, themes, plugin_manager, babel, csrf, allows, limiter
 # various helpers
 from flaskbb.utils.helpers import format_date, time_since, crop_title, \
     is_online, render_markup, mark_online, forum_is_unread, topic_is_unread, \
@@ -117,6 +117,9 @@ def configure_extensions(app):
     # Flask-And-Redis
     redis_store.init_app(app)
 
+    # Flask-Limiter
+    limiter.init_app(app)
+
     # Flask-WhooshAlchemy
     with app.app_context():
         whoosh_index(app, Post)

+ 13 - 0
flaskbb/auth/views.py

@@ -14,8 +14,10 @@ from datetime import datetime, timedelta
 from flask import Blueprint, flash, redirect, url_for, request
 from flask_login import (current_user, login_user, login_required,
                          logout_user, confirm_login, login_fresh)
+from flask_limiter.util import get_remote_address
 from flask_babelplus import gettext as _
 
+from flaskbb.extensions import limiter
 from flaskbb.utils.helpers import (render_template, redirect_or_next,
                                    format_timedelta)
 from flaskbb.email import send_reset_token, send_activation_token
@@ -31,6 +33,17 @@ from flaskbb.utils.tokens import get_token_status
 auth = Blueprint("auth", __name__)
 
 
+def login_rate_limiting():
+    """Dynamically load the rate limiting config from the database."""
+    # [count] [per|/] [n (optional)] [second|minute|hour|day|month|year]
+    return "{count}/{timeout}minutes".format(
+        count=flaskbb_config["LOGIN_ATTEMPTS"],
+        timeout=flaskbb_config["LOGIN_TIMEOUT"]
+    )
+
+limiter.limit(login_rate_limiting, key_func=get_remote_address)(auth)
+
+
 @auth.route("/login", methods=["GET", "POST"])
 def login():
     """Logs the user in."""

+ 5 - 0
flaskbb/extensions.py

@@ -20,6 +20,8 @@ from flask_themes2 import Themes
 from flask_plugins import PluginManager
 from flask_babelplus import Babel
 from flask_wtf.csrf import CsrfProtect
+from flask_limiter import Limiter
+from flask_limiter.util import get_remote_address
 
 from flaskbb.exceptions import AuthorizationRequired
 
@@ -59,3 +61,6 @@ babel = Babel()
 
 # CSRF
 csrf = CsrfProtect()
+
+# Rate Limiting
+limiter = Limiter(auto_check=False, key_func=get_remote_address)