This CVE isn't a missing check — it's a fundamental misapplication of WordPress's role system as a trust boundary. Propovoice created a ndpv_manager role that grants capabilities at the WordPress level, then built REST endpoints treating that role as an application-level privilege ceiling rather than a floor. When the create() function accepts a role parameter without validation, it's not bypassing a plugin boundary — it's being fed the very role system the plugin installed into WordPress.
The privilege escalation is trivial: a user with ndpv_manager can request administrator for a new account, and WordPress complies because the endpoint never checked for promote_users. But the real exposure isn't the admin account — it's the CRM data (ndpv_manager already has access to client records, communications, proposals, and financial data) that becomes the attacker's foothold before they even escalate.
This bug class has appeared before in ACF, Ultimate Member, and other CRM plugins. The pattern recurs because WordPress's set_role() looks like a permissioned operation, so developers rationally interpret it as inherently safe. The fix — validate against an allowlist or check current_user_can('promote_users') — is trivial but doesn't address why this keeps happening: WordPress's capability model provides no native abstraction for 'can create users within this application context but not across the platform.'
Audit other Propovoice endpoints for the same assumption — that custom roles represent permission ceilings rather than floors. Also check whether the plugin properly cleans up ndpv_manager on uninstall; orphaned roles with elevated capabilities are a persistent threat that outlives the plugin that created them.