summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBen Busby <noreply+git@benbusby.com>2021-11-12 14:34:36 -0700
committerBen Busby <noreply+git@benbusby.com>2021-11-12 14:34:36 -0700
commit2d988a1239bd9988d453df5baba75a610f979eb3 (patch)
tree874e3f93d33e9c098ed9c0eae85721a8878c6210 /lib
parent8ee4f308a47ea613a97493b8afbe1aed02f80036 (diff)
downloadfarside-2d988a1239bd9988d453df5baba75a610f979eb3.tar.gz
Throttle incoming requests to 1/sec per ip
This introduces a way of throttling requests in a way that makes sense for the purpose of the app. The app only supports redirecting to one particular service when browsing, which would seldom be required more than once per second for normal "human" browsing. Without this, the service could easily be used to DOS multiple instances at once. That being said, anyone concerned about someone DOS-ing multiple instances at once should be aware that this would be trivial to do with a simple bash script. This is simply a preventative measure to hopefully deter people from trying to attack all public instances of private frontends using farside.link. Note that this throttling applies to all routes in the app, including the homepage. This could be updated to exclude the homepage I guess, but I'm not really sure what the use case would be for that.
Diffstat (limited to 'lib')
-rw-r--r--lib/farside/application.ex3
-rw-r--r--lib/farside/router.ex1
-rw-r--r--lib/farside/throttle.ex19
3 files changed, 22 insertions, 1 deletions
diff --git a/lib/farside/application.ex b/lib/farside/application.ex
index 708ff0d..fd199e1 100644
--- a/lib/farside/application.ex
+++ b/lib/farside/application.ex
@@ -8,7 +8,8 @@ defmodule Farside.Application do
def start(_type, _args) do
children = [
Plug.Cowboy.child_spec(scheme: :http, plug: Farside.Router, options: [port: 4001]),
- {Redix, {@redis_conn, [name: :redix]}}
+ {Redix, {@redis_conn, [name: :redix]}},
+ {PlugAttack.Storage.Ets, name: Farside.Throttle.Storage, clean_period: 60_000}
]
opts = [strategy: :one_for_one, name: Farside.Supervisor]
diff --git a/lib/farside/router.ex b/lib/farside/router.ex
index 7f31e04..e2014b2 100644
--- a/lib/farside/router.ex
+++ b/lib/farside/router.ex
@@ -3,6 +3,7 @@ defmodule Farside.Router do
use Plug.Router
+ plug(Farside.Throttle)
plug(:match)
plug(:dispatch)
diff --git a/lib/farside/throttle.ex b/lib/farside/throttle.ex
new file mode 100644
index 0000000..fc8b591
--- /dev/null
+++ b/lib/farside/throttle.ex
@@ -0,0 +1,19 @@
+defmodule Farside.Throttle do
+ import Plug.Conn
+ use PlugAttack
+
+ rule "throttle per ip", conn do
+ # throttle to 1 request per second
+ throttle conn.remote_ip,
+ period: 1_000, limit: 1,
+ storage: {PlugAttack.Storage.Ets, Farside.Throttle.Storage}
+ end
+
+ def allow_action(conn, _data, _opts), do: conn
+
+ def block_action(conn, _data, _opts) do
+ conn
+ |> send_resp(:forbidden, "Exceeded rate limit\n")
+ |> halt
+ end
+end