diff --git a/config/config.example.yml b/config/config.example.yml index f3f43bba..86b6e720 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -436,6 +436,19 @@ full_refresh: false ## feed_threads: 1 +## +## Setting to disable easy to abuse API endpoints that can +## be spammed and therefore blocking your Invidious instance. +## +## Notes: The following API endpoints will be disabled: +## - /api/v1/videos +## - /api/v1/clips +## - /api/v1/transcripts +## +## Accepted values: true, false +## Default: false +## +disable_api: false jobs: diff --git a/src/invidious.cr b/src/invidious.cr index d7c5b80b..09fbb624 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -217,6 +217,7 @@ end Kemal.config.powered_by_header = false add_handler FilteredCompressHandler.new add_handler APIHandler.new +add_handler DisableAbusableAPIHandler.new add_handler AuthHandler.new add_handler DenyFrame.new diff --git a/src/invidious/config.cr b/src/invidious/config.cr index 7853d9a3..6e46f954 100644 --- a/src/invidious/config.cr +++ b/src/invidious/config.cr @@ -180,6 +180,9 @@ class Config # Playlist length limit property playlist_length_limit : Int32 = 500 + # Disable easy to abuse API endpoints + property disable_api : Bool = false + def disabled?(option) case disabled = CONFIG.disable_proxy when Bool diff --git a/src/invidious/helpers/handlers.cr b/src/invidious/helpers/handlers.cr index 7c5ef118..a30136b2 100644 --- a/src/invidious/helpers/handlers.cr +++ b/src/invidious/helpers/handlers.cr @@ -133,6 +133,26 @@ class APIHandler < Kemal::Handler end end +class DisableAbusableAPIHandler < Kemal::Handler + {% for method in %w(GET HEAD) %} + # This endpoints make a video request to Invidious companion. + {% for endpoint in %w(videos clips transcripts) %} + only ["/api/v1/{{ endpoint.id }}/:id"], {{ method }} + {% end %} + {% end %} + + def call(env) + return call_next env unless only_match?(env) && CONFIG.disable_api + + env.response.content_type = "application/json" + env.response.status_code = 403 + message = {"error" => "This API endpoint has been disabled by the administrator."}.to_json + env.response.print message + env.response.close + return + end +end + class DenyFrame < Kemal::Handler exclude ["/embed/*"]