add missing rate limit

This commit is contained in:
byte[] 2020-07-21 10:50:33 -04:00
parent 799edcb50f
commit ad6e055aff
8 changed files with 82 additions and 0 deletions

View file

@ -9,6 +9,10 @@ defmodule PhilomenaWeb.ConversationController do
plug PhilomenaWeb.FilterBannedUsersPlug when action in [:new, :create]
plug PhilomenaWeb.LimitPlug,
[time: 60, error: "You may only create a conversation once every minute."]
when action in [:create]
plug :load_and_authorize_resource,
model: Conversation,
id_field: "slug",

View file

@ -8,6 +8,10 @@ defmodule PhilomenaWeb.Image.CommentController do
alias Philomena.Comments
alias Philomena.Images
plug PhilomenaWeb.LimitPlug,
[time: 30, error: "You may only create a comment once every 30 seconds."]
when action in [:create]
plug PhilomenaWeb.FilterBannedUsersPlug when action in [:create, :edit, :update]
plug PhilomenaWeb.UserAttributionPlug when action in [:create]

View file

@ -8,6 +8,10 @@ defmodule PhilomenaWeb.Image.SourceController do
alias Philomena.Repo
import Ecto.Query
plug PhilomenaWeb.LimitPlug,
[time: 5, error: "You may only update metadata once every 5 seconds."]
when action in [:update]
plug PhilomenaWeb.FilterBannedUsersPlug
plug PhilomenaWeb.CaptchaPlug
plug PhilomenaWeb.UserAttributionPlug

View file

@ -10,6 +10,10 @@ defmodule PhilomenaWeb.Image.TagController do
alias Philomena.Repo
import Ecto.Query
plug PhilomenaWeb.LimitPlug,
[time: 5, error: "You may only update metadata once every 5 seconds."]
when action in [:update]
plug PhilomenaWeb.FilterBannedUsersPlug
plug PhilomenaWeb.CaptchaPlug
plug PhilomenaWeb.UserAttributionPlug

View file

@ -18,6 +18,10 @@ defmodule PhilomenaWeb.ImageController do
alias Philomena.Repo
import Ecto.Query
plug PhilomenaWeb.LimitPlug,
[time: 10, error: "You may only upload images once every 10 seconds."]
when action in [:create]
plug :load_image when action in [:show]
plug PhilomenaWeb.FilterBannedUsersPlug when action in [:new, :create]

View file

@ -5,6 +5,10 @@ defmodule PhilomenaWeb.Topic.PostController do
alias Philomena.Posts
alias Philomena.UserStatistics
plug PhilomenaWeb.LimitPlug,
[time: 30, error: "You may only make a post once every 30 seconds."]
when action in [:create]
plug PhilomenaWeb.FilterBannedUsersPlug
plug PhilomenaWeb.UserAttributionPlug

View file

@ -9,6 +9,10 @@ defmodule PhilomenaWeb.TopicController do
alias Philomena.Repo
import Ecto.Query
plug PhilomenaWeb.LimitPlug,
[time: 300, error: "You may only make a new topic once every 5 minutes."]
when action in [:create]
plug PhilomenaWeb.FilterBannedUsersPlug when action in [:new, :create]
plug PhilomenaWeb.UserAttributionPlug when action in [:new, :create]
plug PhilomenaWeb.AdvertPlug when action in [:show]

View file

@ -0,0 +1,54 @@
defmodule PhilomenaWeb.LimitPlug do
@moduledoc """
This plug automatically limits requests which are submitted faster
than should be allowed for a given client.
## Example
plug PhilomenaWeb.LimitPlug, [time: 30, error: "Too fast! Slow down."]
"""
alias Plug.Conn
alias Phoenix.Controller
@doc false
@spec init(any()) :: any()
def init(opts), do: opts
@doc false
@spec call(Conn.t(), any()) :: Conn.t()
def call(conn, opts) do
limit = Keyword.get(opts, :limit, 1)
time = Keyword.get(opts, :time, 5)
error = Keyword.get(opts, :error)
data = [
current_user_id(conn.assigns.current_user),
:inet_parse.ntoa(conn.remote_ip),
conn.private.phoenix_action,
conn.private.phoenix_controller
]
key = "rl-#{Enum.join(data, "")}"
[amt, _] =
Redix.pipeline!(:redix, [
["INCR", key],
["EXPIRE", key, time]
])
cond do
amt <= limit ->
conn
true ->
conn
|> Controller.put_flash(:error, error)
|> Controller.redirect(external: conn.assigns.referrer)
|> Conn.halt()
end
end
defp current_user_id(%{id: id}), do: id
defp current_user_id(_), do: nil
end