Multisite: only super admins can enable Allow Private IPs #6

Closed
opened 2026-10-16 21:01:55 -07:00 by eric · 0 comments
Owner

Found in security audit run 3 (2026-10-16, 06d630d), where it was recorded as needs-validation. Decision: subsite admins should not get internal-network reach.

Problem

On multisite, a subsite administrator holds manage_options but not network-level trust. Core denies them plugin install, file editing and unfiltered_html, and core's own fetches of user URLs use wp_safe_remote_*. This plugin still lets them:

  1. Save allow_private_ips = 1. sanitize_settings() at includes/class-apprise-admin-settings.php:270 has no multisite or super-admin check, and core options.php authorizes the save with per-site manage_options.
  2. Point api_url at an RFC1918 or link-local address.
  3. Click Test Connection (:811). The web server sends the request there, and the transport error or status code comes back, showing whether the host and port are reachable.

The update checker already defers to the main site on multisite (class-apprise-update-checker.php:166,187). This setting does not.

Design

  • Saving: in sanitize_settings(), when is_multisite() && ! is_super_admin(), ignore the submitted allow_private_ips and keep the stored value.
  • UI: in render_allow_private_ips_field(), show the checkbox disabled for those users, with a note that only a network administrator can change it.
  • Existing installs: don't migrate or wipe values that are already saved, so existing setups keep working. Call it out in the CHANGELOG: a subsite where a subsite admin already enabled it stays enabled until a super admin turns it off.
  • Unchanged: single-site behaviour, and the apprise_notifications_allow_private_ip filter.
  • Tests: with is_multisite true and is_super_admin false, sanitize_settings() keeps the previous value for both '1' and '0' input. With is_super_admin true, the submitted value is saved.

The verifier's harness VerifierMultisitePrivateIpTest.php (in the run-3 audit artifacts) already sets up the multisite stubs.

Found in security audit run 3 (2026-10-16, `06d630d`), where it was recorded as needs-validation. Decision: subsite admins should not get internal-network reach. ## Problem On multisite, a subsite administrator holds `manage_options` but not network-level trust. Core denies them plugin install, file editing and `unfiltered_html`, and core's own fetches of user URLs use `wp_safe_remote_*`. This plugin still lets them: 1. Save `allow_private_ips = 1`. `sanitize_settings()` at `includes/class-apprise-admin-settings.php:270` has no multisite or super-admin check, and core `options.php` authorizes the save with per-site `manage_options`. 2. Point `api_url` at an RFC1918 or link-local address. 3. Click Test Connection (`:811`). The web server sends the request there, and the transport error or status code comes back, showing whether the host and port are reachable. The update checker already defers to the main site on multisite (`class-apprise-update-checker.php:166,187`). This setting does not. ## Design - **Saving:** in `sanitize_settings()`, when `is_multisite() && ! is_super_admin()`, ignore the submitted `allow_private_ips` and keep the stored value. - **UI:** in `render_allow_private_ips_field()`, show the checkbox disabled for those users, with a note that only a network administrator can change it. - **Existing installs:** don't migrate or wipe values that are already saved, so existing setups keep working. Call it out in the CHANGELOG: a subsite where a subsite admin already enabled it stays enabled until a super admin turns it off. - **Unchanged:** single-site behaviour, and the `apprise_notifications_allow_private_ip` filter. - **Tests:** with `is_multisite` true and `is_super_admin` false, `sanitize_settings()` keeps the previous value for both `'1'` and `'0'` input. With `is_super_admin` true, the submitted value is saved. The verifier's harness `VerifierMultisitePrivateIpTest.php` (in the run-3 audit artifacts) already sets up the multisite stubs.
eric closed this issue 2026-10-16 21:52:08 -07: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
eric/apprise-wordpress-notifications#6
No description provided.