eduardoboucas / staticman

💪 User-generated content for Git-powered websites
https://staticman.net
MIT License
2.42k stars 542 forks source link

feature request: GDPR compliance and double opt-in for notifications #277

Open OlafHaag opened 5 years ago

OlafHaag commented 5 years ago

Hey, I want to spark a discussion on how to optionally make the staticman notifications GDPR compliant and safe against abuse. Since staticman is my first exposure to Node.js, I'd be glad if more experienced contributors would join this discussion to hopefully result in a PR. The discussion on #42 already mixes different topics.

The GDPR demands that:

Art. 7 GDPR Conditions for consent

  1. Where processing is based on consent, the controller shall be able to demonstrate that the data subject has consented to processing of his or her personal data.

First, to fulfill this requirement it would be good to have a timestamp for when consent was given that is saved as a variable with the mailing list member in mailgun.

For preventing e-mail address abuse and really being on the safe side when it comes to consent, the usual practice is to follow the double opt-in scheme. A user who checks the notification checkbox would first get an e-mail asking to confirm the subscription and only upon clicking the confirmation link will be added to the mailing list.

So there needs to be a unique code that gets emailed to the user. A confirmation link, containing information about them and the mailing list in question and the unique code: Clicking on the link will confirm they are okay with their address being part of our mailing list. Clicking the URL sends back details of the user who are checked against the unique code and triggers their addition to the mailing list on Mailgun.

Is that possible? Any ideas how to go about that? Maybe these resources can be salvaged somehow: How to send transactional email in a NodeJS app using the Mailgun API Double Opt-in in PHP with Mailgun

alexwaibel commented 4 years ago

Interesting idea. For the time being, users wishing to have their comments removed from a page can try to contact the person running that site and have them manually delete comments.

OlafHaag commented 4 years ago

Interesting idea. For the time being, users wishing to have their comments removed from a page can try to contact the person running that site and have them manually delete comments.

If I remember correctly, a problem is that one can enter somebody else's e-mail address which lands on your mailing-list and is then getting e-mail notifications for new replies to that comment section without the holder of that address ever giving consent.

hispanic commented 4 years ago

@OlafHaag Good points. Seems to me that implementing double opt-in in Staticman is feasible. I plan on getting closer to the Mailgun API soon. When I do, I'll keep this in mind.

hispanic commented 4 years ago

While working on this, a thought occurred to me. Enabling double opt-in will require that the "encrypt" endpoint be disabled.

Here's the basic flow for double opt-in:

  1. The user submits a comment and opts to subscribe to future comments.
  2. Staticman receives the request and sends a confirmation email to the user. The email contains a link with an encrypted querystring.
  3. The user receives the email and clicks the link to confirm their subscription.
  4. Staticman receives the request, decrypts the querystring, and uses the payload data to subscribe the user.

Notice that I'm assuming an encrypted string instead of a hash. This is because I want to be able to decrypt the data to be able to subscribe the user. All of the data about the potential subscriber will be contained in that encrypted string, including email address, what they are subscribing to, etc. This allows us to avoid persisting any data about the user until they actually confirm, which is a win from a privacy perspective. It also prevents the mailing lists from getting filled-up with spam email addresses.

However, because the "encrypt" endpoint is currently exposed for anyone to hit, an attacker could easily create their own valid encrypted strings and subscribe whoever they want. They'd be able to see the expected structure of the payload data simply by looking at the source code.

I see a few potential options:

  1. Disable the "encrypt" endpoint, period. With it now being a requirement that users stand-up their own installs of Staticman, I don't see there being a need for this endpoint to be exposed any longer. It could simply be replaced with a script that can be executed on the command line.
  2. Programmatically make the "encrypt" endpoint being enabled and double opt-in being enabled mutually exclusive. From a security perspective, this feels a bit weak, simply because there is the potential for holes in the logic.
  3. Require that Staticman be configured with a pepper - https://en.wikipedia.org/wiki/Pepper_(cryptography) This would be placed in the JSON config file and required when double opt-in is enabled. Because peppers are recommended to be relatively large, this could enlarge the size of the encrypted string a good deal.

My preference is option 1, but that assumes my reasoning is correct. Thoughts?

OlafHaag commented 4 years ago

There is already the Deploy to Heroku button, which makes it easy for users to use their own install, right? They'd only have to pull updates from time-to-time to get changes. I think this is reasonable, although I can't comment on the other options.

alexwaibel commented 4 years ago

@hispanic just a quick reaction, but personally I am a bit weary of making changes that prevent us from eventually offering a public instance or that prevent one staticman instance from serving multiple users.

The decision to move to having users host their own instances was one that I made only because we do not currently have the bandwidth to properly support such an offering. I think that in the future, with more contributors and maintainers, a public instance is something we may reconsider.

hispanic commented 4 years ago

@alexwaibel Oh, I wasn't aware. That's good to know. When reviewing the PR's I've submitted, you might want to keep an eye out for any changes I've made that you feel run counter to that strategy. I don't think any do.

I'll go with one of the other two options. Thanks for quick feedback, guys!