This module teaches Drush's sql:sanitize command how to clean up Simplenews newsletter subscriber data. If your site uses Simplenews, every subscriber's real email address lives in the database — and a plain drush sql-sanitize (or drush sql:sync) copy of that database, pulled to a laptop for local development or pushed to a staging/dev site, carries all of those real addresses along with it. This module closes that gap: install it, and the next sanitize run anonymizes subscriber emails automatically, the same way Drupal core already anonymizes user accounts.

Similar projects

Drush Sanitization is an issue for the Simplenews module with a merge request which adds a basic sanitize support (subscriber emails and the mail spool). It is not yet merged. My module works today on current Simplenews releases and also covers Simplenews Stats data, which Simplenews core cannot depend on. I've offered to help on the Simplenews issue; if it lands, I'll narrow my module to Simplenews Stats support or point users to the upstream feature.

Simplenews Drush Sanitize addresses the same problem but was built for Drupal 7 and Drush's old hook-based sanitize system. It has a single 7.x-1.x-dev release, hasn't seen real activity in years, and isn't compatible with the Symfony-event-based sql:sanitize used by modern Drush — it doesn't work on current Drupal/Drush versions.

Commerce SQL Sanitize isn't a competitor — it's the direct inspiration for this module's approach, solving the identical problem for Commerce order/address/payment data instead of Simplenews subscribers.

About me

I've built Drupal sites for 18+ years, in federal government, ecommerce, finance, healthcare and higher education industries. I maintain several contrib projects including Select 2 All and Features. I've spoken at Drupal GovCon 2018 and several Evolve Drupal events in the last few years. By day, I'm a Senior Software Engineer at Principal Financial Group where I work on the team building the shared installation profile that powers 21 production Drupal websites. This is my first security advisory coverage application.

Project link

https://www.drupal.org/project/simplenews_sql_sanitize

Comments

matthand created an issue. See original summary.

vishal.kadam’s picture

Issue summary: View changes
matthand’s picture

Issue summary: View changes
geocalleo’s picture

Thanks for the module. It's small, clean and well tested, and it fills a real gap for Simplenews sites.

A few things before this is ready:

  1. LICENSE.txt is committed to the repository. drupal.org adds it when packaging, so please remove it.
  2. sanitizeSimplenewsData() resets the entity cache for simplenews_subscriber only. simplenews_subscriber_history and simplenews_stats_item are also cached content entities, so their stale cached copies (with real addresses) can survive the sanitize. Please add the same hasDefinition()-guarded resetCache() for both.
  3. Not a blocker: the SanitizePluginInterface / #[CLI\Hook] approach matches Drush core's own sanitize plugins through 13.x. Drush 14 moves to Symfony event listeners and deprecates the interface, so it will need a port before widening the Drush constraint.
  4. Minor: the README says "Drush 10+", while composer.json declares ^11 || ^12 || ^13.

Otherwise it looks solid. It uses the Database API correctly, keys the new addresses on each table's primary key so they can't collide, truncates the mail spool sensibly, and gates Simplenews Stats support properly. The functional test that proves the Drush hook actually fires is a nice touch.

Setting to Needs work.

geocalleo’s picture

Assigned: Unassigned » geocalleo
Status: Needs review » Needs work
matthand’s picture

Status: Needs work » Needs review

Thank you @geocalleo for the review! I addressed all of the issues you raised in the new release v1.0.1. The cache issue you mentioned is now mitigated and a regression test added to confirm. I decided to hold off on Drush 14 support since it's still in development and not yet stable. I added a ticket to port to Drush 14 for when they make a stable release. Ready for your review again!

avpaderno’s picture

Assigned: geocalleo » Unassigned

Thank you for applying!

Before giving links helpful to understand how the review process works, what to expect from a review, and what to do to avoid a review takes more time than needed, I would like to thank all the reviewers for the work they do.
These applications are volunters-driven, which also means it is not possible to predict when an application will be marked fixed and the applicant will get the permission to opt projects into security advisory policy. While we aim to make an application as quick as possible, it is also important for us that more people review the project used for an application. In this way, we make sure applications do not miss some important points that should be instead reported.
Applications are not meant to be complete debugging sessions that eliminate every existing bug, though. I apologize if sometimes applications seem to go into too-detailed reviews.

Please read Review process for security advisory coverage: What to expect for more details and Security advisory coverage application checklist to understand what reviewers look for. Tips for ensuring a smooth review gives some hints for a smoother review.

The important notes are the following.

  • If you have not done it yet, you should enable GitLab CI for the project and fix the PHP_CodeSniffer errors/warnings it reports.
  • For the time this application is open, only your commits are allowed.
  • The purpose of this application is giving you a new drupal.org role that allows you to opt projects into security advisory coverage, either projects you already created, or projects you will create. The project status will not be changed by this application; once this application is closed, you will be able to change the project status from Not covered to Opt into security advisory coverage. This is possible only 14 days after the project is created.

    Keep in mind that once the project is opted into security advisory coverage, only Security Team members may change coverage.
  • Only the person who created the application will get the permission to opt projects into security advisory coverage. No other person will get the same permission from the same application; that applies also to co-maintainers/maintainers of the project used for the application.
  • We only accept an application per user. If you change your mind about the project to use for this application, or it is necessary to use a different project for the application, please update the issue summary with the link to the correct project and the issue title with the project name and the branch to review.

To the reviewers

Please read How to review security advisory coverage applications, Application workflow, What to cover in an application review, and Tools to use for reviews.

The important notes are the following.

  • It is preferable to wait for a project moderator before posting the first comment on newly created applications. Project moderators will do some preliminary checks that are necessary before any change on the project files is suggested.
  • Reviewers should show the output of a CLI tool only once per application.
  • It may be best to have the applicant fix things before further review.

For new reviewers, I would also suggest to first read In which way the issue queue for coverage applications is different from other project queues.

avpaderno’s picture

As a side note, the license file is allowed in a project repository, even if it must be for the same license used by Drupal core.
The packaging script adds the license file to the package it creates, but the license file should be in the project repository, in the same way the license for Drupal core is in its repository, since the source for a project is its project repository.

avpaderno’s picture

As a further side note, it is not necessary to create new releases when changing files as suggested in a review.
The suggested changes could not be backward compatible, or the review could have suggested wrong changes; committing the changes in the branch is better, and it avoids that people using the project update the project to a release containing issues the previous release did not have.

matthand’s picture

Issue summary: View changes
avpaderno’s picture

Issue summary: View changes
matthand’s picture

Thank you for the reviews. The changes addressing the latest feedback are merged into the 1.0.x branch, which is the branch under review.

  • GitLab CI: the project runs the standard GitLab CI template, and all jobs (PHPCS, PHPStan, cspell and PHPUnit) pass on the current 1.0.x.
  • LICENSE.txt: following comment #8, I restored LICENSE.txt in the repository, using the same text as Drupal core's copy.
  • Drush version: the README, composer.json and the project page now all say Drush 13. The code uses Drush 13's sanitize API, so the earlier claim of Drush 11 and 12 support was wrong.
  • About Me: I added an About Me section to the issue summary.
  • Other fixes from a self-review::
    • Anonymizing addresses now works on every SQLite version. The previous SQL used CONCAT(), which older SQLite versions don't support.
    • dt() now receives only literal strings.
    • The README follows the standard README template.

About releases: I did tag one more release, 1.0.2, after comment #9. It fixes sanitizing on older SQLite versions and corrects the declared Drush compatibility, and I judged those fixes should reach users straight away. I will not tag any further releases while the application is under review. All further changes will only be merged to 1.0.x, which will always be the current code.

Thank you for this opportunity!

avpaderno’s picture

Status: Needs review » Postponed (maintainer needs more info)

As a side question, since you added an About me section, where did you read that section should be added to the application summary?

matthand’s picture

@avpaderno I read the Tips for ensuring a smooth review documentation you shared and the heading Include some information about your background and experience with Drupal in your application conveyed that you wanted my background included in the application issue. So I added an About Me section. Would you like me to make any changes?

matthand’s picture

Status: Postponed (maintainer needs more info) » Needs review

Moving back to needs review because I believe I've answered everything asked. And, I have prepared the application and project based on the documentation shared. Happy to adjust anything as needed. Thank you!

dietric@gmail.com’s picture

Thanks for the module and for the quick follow-up on the earlier review. I read through 1.0.x and found nothing blocking.

Security notes:

  • No routes, forms or permissions are added, and all SQL is built from hardcoded literals, so I see no injection path today. buildAnonymizeExpression() is public static and interpolates $prefix and $id_column unescaped. Please add a docblock note that arguments must be trusted constants, or make it protected.
  • The cache reset now covers all three entity types and has a kernel test.

Suggestions, none blocking:

  1. Mention in the README that custom fields added to the subscriber entity are not sanitized.
  2. Recommend a cache rebuild after sanitizing, since rendered admin pages could still hold real addresses.
  3. Say that only no and 0 disable the options, as in Drush core, since false is treated as enabled.

I did not run the tests locally.