commit: 2980788c8ec973c48d04b8f6aa93ddafab93c168
parent 49376e6b75e4418da4b6ee08d51e1f7c01091bb4
Author: lain <lain@soykaf.club>
Date: Wed, 27 Aug 2025 10:33:36 +0000
Merge branch 'admin-api-revocation' into 'develop'
Admin api revocation fix
Closes #3390
See merge request pleroma/pleroma!4382
Diffstat:
3 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/changelog.d/admin-self-revocation.security b/changelog.d/admin-self-revocation.security
@@ -0,0 +1 @@
+Admin API: Fixed self-revocation vulnerability where admins could accidentally revoke their own admin status via the single-user permission endpoint
+\ No newline at end of file
diff --git a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
@@ -240,6 +240,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
render_error(conn, :not_found, "No such permission_group")
end
+ def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do
+ render_error(conn, :forbidden, "You can't revoke your own admin status.")
+ end
+
def right_delete(
%{assigns: %{user: admin}} = conn,
%{
@@ -265,10 +269,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
json(conn, fields)
end
- def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do
- render_error(conn, :forbidden, "You can't revoke your own admin status.")
- end
-
@doc "Get a password reset token (base64 string) for given nickname"
def get_password_reset(conn, %{"nickname" => nickname}) do
(%User{local: true} = user) = User.get_cached_by_nickname(nickname)
diff --git a/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs b/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs
@@ -321,6 +321,36 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} revoked admin role from @#{user_one.nickname}, @#{user_two.nickname}"
end
+
+ test "/:right DELETE, admin cannot revoke their own admin status (single)", %{
+ admin: admin,
+ conn: conn
+ } do
+ conn =
+ conn
+ |> put_req_header("accept", "application/json")
+ |> delete("/api/pleroma/admin/users/#{admin.nickname}/permission_group/admin")
+
+ assert json_response(conn, 403) == %{"error" => "You can't revoke your own admin status."}
+ end
+
+ test "/:right DELETE, admin cannot revoke their own admin status (multiple)", %{
+ admin: admin,
+ conn: conn
+ } do
+ user = insert(:user, is_admin: true)
+
+ conn =
+ conn
+ |> put_req_header("accept", "application/json")
+ |> delete("/api/pleroma/admin/users/permission_group/admin", %{
+ nicknames: [admin.nickname, user.nickname]
+ })
+
+ assert json_response(conn, 403) == %{
+ "error" => "You can't revoke your own admin/moderator status."
+ }
+ end
end
describe "/api/pleroma/admin/users/:nickname/password_reset" do