• 2.7.0 4221d4b19d

    2.7.0
    All checks were successful
    CI / Lint + Static Analysis (push) Successful in 1m56s
    CI / Unit Tests (PHP 8.3) (push) Successful in 1m49s
    CI / Unit Tests (PHP 8.4) (push) Successful in 1m48s
    CI / Unit Tests (PHP 8.5) (push) Successful in 1m52s
    Release / Verify tag, version and changelog (push) Successful in 3s
    Release / Lint + Static Analysis (push) Successful in 1m53s
    Release / Unit Tests (PHP 8.5) (push) Successful in 1m38s
    Release / Build zip and publish release (push) Successful in 3s
    Release / Unit Tests (PHP 8.3) (push) Successful in 1m37s
    Release / Unit Tests (PHP 8.4) (push) Successful in 1m37s
    Stable

    eric released this 2026-10-16 22:36:07 -07:00 | 1 commits to main since this release

    Security

    • DNS pinning now works with the cURL transport. The pinned IP was passed as $args['curl'], which WordPress never reads, so cURL looked the hostname up again when connecting, and a DNS rebind could get past the private-IP check. CURLOPT_RESOLVE is now set on the cURL handle from the http_api_curl action, for this request only (#3).
    • Loopback is now checked on the resolved IP as well as on the literal URL host. Before, [::], 0177.0.0.1, 2130706433, 127.1 or a name resolving to 127.x fell through to the private-range check, so the Allow Private IPs setting opened localhost. Only the apprise_notifications_allow_localhost filter can open loopback now. 0.0.0.0/8 and :: also count as loopback (#4).
    • The private-IP check now blocks non-global ranges that PHP's FILTER_FLAG_NO_PRIV_RANGE / FILTER_FLAG_NO_RES_RANGE let through: 100.64.0.0/10 (CGNAT, Tailscale, and Alibaba Cloud metadata at 100.100.100.200), 192.0.0.0/24, 198.18.0.0/15, the documentation ranges, 224.0.0.0/4, and in IPv6 64:ff9b:1::/48, 100::/64, Teredo 2001::/32, 2001:db8::/32, fec0::/10 and ff00::/8. NAT64 (64:ff9b::/96) and 6to4 (2002::/16) addresses are checked by the IPv4 address they embed, so 64:ff9b::a9fe:a9fe is treated as 169.254.169.254. Allow Private IPs and the apprise_notifications_allow_private_ip filter still open these ranges (#5).
    • On multisite, only a super admin can change Allow Private IPs. A subsite administrator has manage_options but not network-level trust, and could use the setting with Test Connection to probe hosts and ports on the server's internal network. For other users the checkbox is now disabled, and anything they submit for it is ignored. Values already saved are not changed: if a subsite admin turned the setting on before this release, it stays on until a super admin turns it off (#6).
    • Allow Private IPs no longer opens link-local and cloud metadata addresses: 169.254.0.0/16 (metadata at 169.254.169.254 on AWS, GCP, Azure and others), fe80::/10, AWS IMDS over IPv6 at fd00:ec2::254, and Alibaba Cloud metadata at 100.100.100.200. No Apprise server runs there. The apprise_notifications_allow_private_ip filter can still open them, but it gets false as the default for these addresses whatever the setting, and only a strict true lets one through (#7).

    Fixed

    • Email suppression → Matching events only with user_register on no longer blocks the new user's own set-password email. Only the admin's new-user email is suppressed, which is the one the Apprise notification replaces. Before, a newly registered user never got their login link (#8).
    • Email suppression now needs an Apprise API URL as well as the plugin being enabled. With no URL set, All emails used to drop every site email, password resets included, and Matching events only dropped the emails it covers, with no Apprise notification sent in their place. The settings page now warns when a suppression mode is chosen but no API URL is set. A URL that is set but unreachable still can't be detected before WordPress sends mail (#9).
    • The Apprise notice about a new plugin version now respects the plugin's Enable Notifications switch. Before, a site with notifications turned off but Check for new versions on kept sending update notices to the Apprise URL. With notifications off, the daily notice job is unscheduled; new versions still show on the Plugins and Updates screens with one-click update. On multisite the main site's switch applies, since only the main site sends the notice (#10).

    Changed

    • The Theme Auto-Updated event is now labelled Theme Updated. It has always fired for manual theme updates as well as automatic ones. The event key (theme_update) is unchanged.
    • The Enable Notifications description no longer says it doesn't affect the update checker, which stopped being true with the fix above.
    • README and readme.txt reviewed against the code: the README's event list now has all 17 events and their defaults, its custom-event example uses the dispatcher instead of the apprise_notifications_event_types filter removed in 2.4.1, it lists every public hook, and it no longer describes delivery as synchronous. readme.txt drops a Screenshots section with no screenshots (#12).

    Removed

    • Raw cURL options returned in $args['curl'] by apprise_notifications_request_args are no longer filtered. WordPress never applied them, so the filtering did nothing.
    Downloads