jazzband / django-newsletter

An email newsletter application for the Django web application framework, including an extended admin interface, web (un)subscription, dynamic e-mail templates, an archive and HTML email support.
GNU Affero General Public License v3.0
846 stars 204 forks source link

Make IP Address and Email Database Storage PII / GDPR Compliant #319

Open 9mido opened 4 years ago

9mido commented 4 years ago

IP addresses and email addresses fall into the PII and GDPR categories. The only way to be compliant and lawful is if you encrypt the IP & email in the database.

For the IP, one way to combat this is to create a setting that enables / disables the IP address collection in the database. Otherwise, encrypt it by default.

Email would just need to be encrypted since it is required.

Both should be able to be decrypted somehow as well.

dokterbob commented 4 years ago

Good point! I'll go into some of the considerations below. If and when other users agree, I would happily merge something like my proposal below.

Encryption

Although I'm not too sure on encrypting it at a database-level. That implies that there is a single key somewhere, and if that key leaks (which is likely when the database itself leaks), there is no improved protection of users. The only way to guarantee a higher level of security would be to store the key on a Yubikey or equivalent HSM, or to load the key on every start of the service from some external key storage.

IP Privacy

A better way would be to:

Email privacy

Referring also the the encryption section above, I see no reason to encrypt email addresses. Rather, GDPR seems to require service providers to take all possible precautions to safeguard the personal information of users. This means, the server should be kept safe, no outdated dependencies should be used etc. Only after that, and only if we can store the encryption keys in a safer place than the database or the server itself, does it make sense to encrypt anything.

In addition, encrypting email addresses would make it impossible to do a SELECT/get() on email addresses, which is something that our application heavily relies upon.

Ref; https://www.reddit.com/r/gdpr/comments/91u93h/do_i_need_to_encrypt_user_email_addresses_in_my/

Proposal

  1. Add a configuration option filter_ip() option and provide a default (privacy by default!) implementation which masks the last bits as per the GA reference above.
  2. Not encrypting email addresses, but adding an explicit reference that we are storing personal information and that GDPR compliance requires that common security precautions are taken.
9mido commented 4 years ago

Wow great explanation of everything and glad to see you think it is a good idea.

I looked at django-fernet-fields which uses the SECRET_KEY to do both the encryption and decryption. If you are using postgres, you can use django-pgcrypto-fields which uses a postgres pgcrypto extension. It would be nice if django-newsletter had something like this built in without relying on these other packages and overriding the app.

I am looking forward to hearing other user's ideas!

thismatters commented 10 months ago

It's kind of a quagmire for this package to get involved in security questions. However, this package could follow Django's lead and provide an AbstractSubscription model which any project maintainer could subclass and make their own security choices.