From 620247a015f6cd894a119bb5173a3da7e5913064 Mon Sep 17 00:00:00 2001 From: Stephanie Wilde-Hobbs Date: Tue, 12 May 2020 17:12:27 +0100 Subject: [PATCH] Add database configuration whitelist --- docs/configuration/cheatsheet.md | 11 +++++++++ .../web/admin_api/admin_api_controller.ex | 13 +++++++++- .../admin_api/admin_api_controller_test.exs | 24 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md index 707d7fdbd..7b7a332c7 100644 --- a/docs/configuration/cheatsheet.md +++ b/docs/configuration/cheatsheet.md @@ -911,6 +911,17 @@ config :auto_linker, Boolean, enables/disables in-database configuration. Read [Transfering the config to/from the database](../administration/CLI_tasks/config.md) for more information. +## :database_config_whitelist + +List of valid configuration sections which are allowed to be configured from the database. + +Example: +```elixir +config :pleroma, :database_config_whitelist, [ + {:pleroma, :instance}, + {:pleroma, Pleroma.Web.Metadata} +] +``` ### Multi-factor authentication - :two_factor_authentication * `totp` - a list containing TOTP configuration diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index 9f1fd3aeb..9c5fbfc5d 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -949,7 +949,8 @@ def config_show(conn, _params) do def config_update(conn, %{"configs" => configs}) do with :ok <- configurable_from_database(conn) do {_errors, results} = - Enum.map(configs, fn + Enum.filter(configs, &whitelisted_config?/1) + |> Enum.map(fn %{"group" => group, "key" => key, "delete" => true} = params -> ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]}) @@ -1011,6 +1012,16 @@ defp configurable_from_database(conn) do end end + defp whitelisted_config?(%{"group" => group, "key" => key}) do + if whitelisted_configs = Config.get(:database_config_whitelist) do + Enum.any?(whitelisted_configs, fn {whitelisted_group, whitelisted_key} -> + group == inspect(whitelisted_group) && key == inspect(whitelisted_key) + end) + else + true + end + end + def reload_emoji(conn, _params) do Pleroma.Emoji.reload() diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index 4697af50e..31e73d6a5 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -2943,6 +2943,30 @@ test "proxy tuple ip", %{conn: conn} do ] } end + + test "doesn't set keys not in the whitelist", %{conn: conn} do + clear_config(:database_config_whitelist, [ + {:pleroma, :key1}, + {:pleroma, :key2}, + {:pleroma, Pleroma.Captcha.NotReal} + ]) + + post(conn, "/api/pleroma/admin/config", %{ + configs: [ + %{group: ":pleroma", key: ":key1", value: "value1"}, + %{group: ":pleroma", key: ":key2", value: "value2"}, + %{group: ":pleroma", key: ":key3", value: "value3"}, + %{group: ":pleroma", key: "Pleroma.Web.Endpoint.NotReal", value: "value4"}, + %{group: ":pleroma", key: "Pleroma.Captcha.NotReal", value: "value5"} + ] + }) + + assert Application.get_env(:pleroma, :key1) == "value1" + assert Application.get_env(:pleroma, :key2) == "value2" + assert Application.get_env(:pleroma, :key3) == nil + assert Application.get_env(:pleroma, Pleroma.Web.Endpoint.NotReal) == nil + assert Application.get_env(:pleroma, Pleroma.Captcha.NotReal) == "value5" + end end describe "GET /api/pleroma/admin/restart" do