Server settings → Plugins: the action dispatcher calls any method named after the posted action, so some answer 500 #484

Closed
opened 2026-10-01 10:47:01 +00:00 by tiagoagueda · 0 comments
Owner

Found on 2026-09-29 in a read-only review of postulo at 95348908d, reading PluginActionView.post and posting unexpected actions in a test.

Checked again on 2026-10-01 against main at 0a5cad587: still present. The code is now at core/server_views.py:1313-1319 (PluginActionView.post) and core/server_views.py:1463 (_switch); the four posted actions fail in the same way.

PluginActionView.post resolves its handler with getattr(self, f"_{action}", None) from the posted action, so every attribute of the view whose name starts with an underscore, its own and those it inherits from View and the mixins, is a reachable action. Those that are not handlers crash the request instead of answering "That is not something this page does."

  • Where: core/server_views.py:1312-1318, PluginActionView.post; core/server_views.py:1462, _switch(self, request, disabled), the helper behind _disable and _enable.
  • What happens: checked by posting to server:plugin_action as an administrator: action=switch raises TypeError: PluginActionView._switch() missing 1 required positional argument: 'disabled'; action=allowed_methods and action=_init__ raise TypeError from View._allowed_methods and View.__init__; action=_eq__ hands NotImplemented back as the response, which fails in Django's handler. Each is an Internal Server Error with a traceback in the log.
  • Who can trigger it: only an authenticated administrator (the view is behind StaffRequiredMixin and CSRF), typically through a stale or hand-built form. Nothing is reached beyond a crash, which is why this is filed as a bug rather than as a security issue.
  • Why it matters: the page promises a polite refusal for anything it does not do, and the set of reachable actions is decided by whatever methods the class and its bases happen to have, so any helper added later becomes an action without anybody choosing that.
  • Fix: dispatch through an explicit table naming the actions the template posts (upload, cancel, confirm, refresh, install, disable, enable, remove), for example ACTIONS = {"upload": "_upload", …}, and refuse anything else with the existing message.

Done when

  • The plugin page's tests (tests/test_server_settings.py or the file that holds them) gain a test that posts action=switch and action=allowed_methods as an administrator and gets a redirect to server:plugins with "That is not something this page does." It fails today with a TypeError.
Found on 2026-09-29 in a read-only review of postulo at 95348908d, reading `PluginActionView.post` and posting unexpected actions in a test. Checked again on 2026-10-01 against `main` at `0a5cad587`: still present. The code is now at `core/server_views.py:1313-1319` (`PluginActionView.post`) and `core/server_views.py:1463` (`_switch`); the four posted actions fail in the same way. `PluginActionView.post` resolves its handler with `getattr(self, f"_{action}", None)` from the posted `action`, so every attribute of the view whose name starts with an underscore, its own and those it inherits from `View` and the mixins, is a reachable action. Those that are not handlers crash the request instead of answering "That is not something this page does." - **Where:** `core/server_views.py:1312-1318`, `PluginActionView.post`; `core/server_views.py:1462`, `_switch(self, request, disabled)`, the helper behind `_disable` and `_enable`. - **What happens:** checked by posting to `server:plugin_action` as an administrator: `action=switch` raises `TypeError: PluginActionView._switch() missing 1 required positional argument: 'disabled'`; `action=allowed_methods` and `action=_init__` raise `TypeError` from `View._allowed_methods` and `View.__init__`; `action=_eq__` hands `NotImplemented` back as the response, which fails in Django's handler. Each is an Internal Server Error with a traceback in the log. - **Who can trigger it:** only an authenticated administrator (the view is behind `StaffRequiredMixin` and CSRF), typically through a stale or hand-built form. Nothing is reached beyond a crash, which is why this is filed as a bug rather than as a security issue. - **Why it matters:** the page promises a polite refusal for anything it does not do, and the set of reachable actions is decided by whatever methods the class and its bases happen to have, so any helper added later becomes an action without anybody choosing that. - **Fix:** dispatch through an explicit table naming the actions the template posts (`upload`, `cancel`, `confirm`, `refresh`, `install`, `disable`, `enable`, `remove`), for example `ACTIONS = {"upload": "_upload", …}`, and refuse anything else with the existing message. ## Done when - The plugin page's tests (`tests/test_server_settings.py` or the file that holds them) gain a test that posts `action=switch` and `action=allowed_methods` as an administrator and gets a redirect to `server:plugins` with "That is not something this page does." It fails today with a `TypeError`.
tiagoagueda added this to the 0.6.0 milestone 2026-10-01 10:47:01 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#484
No description provided.