Add database configuration whitelist
authorStephanie Wilde-Hobbs <steph@rx14.co.uk>
Tue, 12 May 2020 16:12:27 +0000 (17:12 +0100)
committerStephanie Wilde-Hobbs <steph@rx14.co.uk>
Tue, 12 May 2020 16:12:27 +0000 (17:12 +0100)
docs/configuration/cheatsheet.md
lib/pleroma/web/admin_api/admin_api_controller.ex
test/web/admin_api/admin_api_controller_test.exs

index 707d7fdbd58228b61988666afb107fb7e5e10903..7b7a332c7e975a5c91eeeff49a72aea130da67d2 100644 (file)
@@ -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
index 9f1fd3aeb334f273577a189f460cb55229937096..9c5fbfc5dad00ce946e959b7497045e0a06b8234 100644 (file)
@@ -949,7 +949,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController 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 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController 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()
 
index 4697af50ebcb367dede7a8f9580d38feb9278682..31e73d6a54a02023226cd17e556e4b4e6697d1b8 100644 (file)
@@ -2943,6 +2943,30 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest 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