Skip to content

No WordPress privacy exporters/erasers for personal data in nx_entries #143

Description

@sadmansakibnadvi

Describe the bug

NotificationX stores personal data in its own {$prefix}nx_entries table but registers no WordPress privacy exporters or erasers, so that data is invisible to Tools → Export Personal Data and Tools → Erase Personal Data.

A repo-wide search for wp_privacy_personal_data_exporters, wp_privacy_personal_data_erasers, and wp_add_privacy_policy_content across includes/, blocks/, and notificationx.php returns zero results.

What's stored

Entry data payloads routinely include, depending on source:

  • name, first_name, last_name
  • email
  • ip
  • postal fields — city, country, state, line_1, line_2, postal_code (e.g. includes/Extensions/SureCart/SureCart.php#L166-L209)

This is personal data under GDPR/CCPA, and for some integrations it is linked to purchase or enrollment history.

Compounding: uninstall doesn't clean up

uninstall.php is a boilerplate stub — it contains only the WP_UNINSTALL_PLUGIN guard and no cleanup — so nx_entries and its personal data survive plugin deletion entirely.

Not covered by the existing GDPR/CCPA extensions

includes/Extensions/GDPR/ and includes/Extensions/CCPA/ are consent-banner notification sources. They help site owners display a cookie notice; they do nothing about data subject rights over NotificationX's own stored data.

Steps to reproduce

  1. Install NotificationX and any source that captures customer data (WooCommerce Sales, SureCart, EDD…).
  2. Let a few notifications accumulate so {$prefix}nx_entries has rows containing a customer's name and email.
  3. Go to Tools → Export Personal Data, enter that customer's email, and run the export.
  4. Repeat with Tools → Erase Personal Data.

Expected: the export includes the customer's NotificationX entries; the erasure removes or anonymizes them.
Actual: neither tool sees the data. It is not exported, and it is not erased — the customer's name and email continue to appear in public social-proof popups after they have exercised their right to erasure.

Suggested fix

Register a single exporter/eraser pair keyed on data.email. Because every source funnels through the same nx_entries table and a common data shape, one implementation covers all integrations at once — this doesn't need per-extension work.

add_filter( 'wp_privacy_personal_data_exporters', [ $this, 'register_exporter' ] );
add_filter( 'wp_privacy_personal_data_erasers',   [ $this, 'register_eraser' ] );

Erasure should probably anonymize rather than hard-delete, so notification counts and campaign history stay intact.

Separately, uninstall.php should drop the plugin's tables (ideally behind an opt-in "delete data on uninstall" setting, which is the common convention).

Impact

Compliance. A site owner cannot fulfil a GDPR Article 17 erasure request with the tools WordPress provides, and in the worst case the erased individual's name keeps being displayed publicly on the site.

The exposure scales with how sensitive the source is. It is one thing for a T-shirt purchase; it is quite another for appointment, donation, or health-adjacent booking data — which is what prompted this report.

Environment

Found on master @ 55f62f10.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions