Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Security / UX of private pages using a shared password #10588

Open
2 of 6 tasks
RealOrangeOne opened this issue Jun 21, 2023 · 11 comments
Open
2 of 6 tasks

Improve Security / UX of private pages using a shared password #10588

RealOrangeOne opened this issue Jun 21, 2023 · 11 comments

Comments

@RealOrangeOne
Copy link
Member

RealOrangeOne commented Jun 21, 2023

Issue Summary

Wagtail's page privacy feature could be improved to communicate better to the user and provide ways for Wagtail installations to fine tune how the 'shared password' is created.

Is your proposal related to a problem?

Wagtail allows pages to be password protected as part of a feature called 'private pages'.

An admin can specify a password, which an end user must enter when visiting a page to view the page. The same functionality exists for documents. This feature was only really intended for low-security applications.

Whilst the implementation is fundamentally secure, is has a few small weaknesses:

  1. The password is stored in the database in plain text. This allows admin users to see what the password is set to, but also means a database leak also exposes the password's values.
  2. There are no strength checks for the password, meaning a user may use a weak password to protect sensitive content.
  3. It is not explicitly clear to the user that this is not a secure option, it is presented to be similar to the more secure auth (login) based private access.
  4. The term password can be be inferred to be 'secure' when it is not.

Aside: CVE-2020-11037 ensures that verification of the password is not vulnerable to a timing attack.

Because the password validation implementation is secure, it's not possible to exploit any of the above weaknesses to bypass authentication, however people may be using this feature incorrectly, and so improvements should be made.

Describe the solution you'd like

The following items may be split to standalone issues for easier collaboration.

Additional context

@RealOrangeOne RealOrangeOne added status:Unconfirmed Issue, usually a bug, that has not yet been validated as a confirmed problem. type:Bug labels Jun 21, 2023
@RealOrangeOne
Copy link
Member Author

My suggestions for fixing:

  1. Add opt-out functionality for validating the strength of the passwords used to protect pages, using Django's existing password validators. This helps protect users from using weak passwords to protect their pages.
  2. Add a warning to users that password protection is only designed for low-security applications, and that authenticated user permissions are far more secure.

If we want a more thorough fix, we could:

  1. Store the password hashed, along with the name of the person who set the password. This doesn't allow password retrieval, but at least shows an admin who to ask for its current value.

Personally, I think it's worth doing the full solution, as adding point 3 would remove the need for point 2. If we're going to ship a feature, we should make sure it's as secure as possible by default, whilst protecting users from a potential foot-gun.

Happy to create a patch if that makes sense to others.

@RealOrangeOne RealOrangeOne added status:Needs Info component:Security component:Page and removed status:Unconfirmed Issue, usually a bug, that has not yet been validated as a confirmed problem. labels Jun 21, 2023
@zerolab
Copy link
Contributor

zerolab commented Jun 21, 2023

Store the password hashed, along with the name of the person who set the password. This doesn't allow password retrieval, but at least shows an admin who to ask for its current value.

Screenshot 2023-06-21 at 16 52 12

We already capture who updates the privacy options in the audit log. In the screenshot, I added a password, then updated it.

@allcaps
Copy link
Member

allcaps commented Jun 22, 2023

The feature isn't very secure and not intended to be used in situations that should be very secure. Therefore, the help text warning (point 2) is the most important. We should add it to the user interface (for content editors) and to the Wagtail documentation (for developers).

Hashing the password could contribute to the false impression that this feature is secure. Do we want to go down this road?

Maybe we should not hash the password, but make the intended use-case even more clear. Maybe:

  • Rename 'Password' to 'Shared secret'
  • Have a reveal option, and display the shared secret in the interface.
  • Something else?

This way, everybody could have the correct understanding of the intended use-case and implications. And don't miss use the feature for situations it isn't designed for.

@lb-
Copy link
Member

lb- commented Jun 22, 2023

Great idea Coen, I think that clear communication and terminology could really help here.

@RealOrangeOne
Copy link
Member Author

The feature isn't very secure

Why? It follows Wagtail's existing permissions model for pages (which ought to be secure), collects and compares passwords in a secure way, and correctly restricts access. Besides how the password is stored (and the lack of strength requirements), I'm not sure I see how it "isn't very secure"?

@allcaps
Copy link
Member

allcaps commented Jul 28, 2023

Why?

AFAIK, the intended use case is to share the password between multiple people. I've never encountered anyone using this feature in any other way. And: shared passwords are insecure.

I'm sure Python/Django/Wagtail code doing the permission checks is fine. To me the plain password storage fits the use-case. Password is just the wrong name for the field. Maybe: shared secret?

This shared password feature is the lightest form of 'security'. Hashing the password is easy, but I'm against it, as it doesn't fit the intended use-case.

It would be better to reword and show the password in the admin interface. This would make it clear that, if a developer needs something better, they have to use one of the other options, or roll their own.

@lb-
Copy link
Member

lb- commented Jul 28, 2023

I agree with @allcaps - I think we should opt for a different name for the field and maybe add some documentation.

If we want to enhance this further, we could add a button that generates a really long unique string. It's still a shared secret, insecure, but it makes it slightly easier for users to make this secret more complex.

This could make the behaviour a bit closer to something like a public link for a Google Document.

We could even use some of their wording about how 'anyone with this link can access this page'.

@lb- lb- added the component:Privacy Private / protected / restricted pages label Aug 2, 2023
@thibaudcolas
Copy link
Member

Same as @allcaps and @lb-.

  • As a baseline – "Shared secret" as a name, and the "Anyone with this secret can access the page. " as a user-friendly explanation of the behavior that matches what other tools do.
  • If we want to increase the likelihood of good secrets being used, a "[Button]\ Generate a pass-phrase" as discussed
  • And also having a way to disable this option for sites that don’t want to allow this approach.

@lb-
Copy link
Member

lb- commented Jan 24, 2024

Discussed this today at core team. LB to update the issue description & feedback on the PR accordingly.

  1. 'Shared password' should be the field label
  2. re-order the options so that it goes from least secure to most secure (move logged in users after the Shared password)
  3. Better help text to advise that this is not secure
  4. Add a comment in the code that this is called password but is not the same as a user password (to avoid concerns in the future)
  5. De-scope the code generator & setting to disable this feature for now, can be done as a future enhancement (I will create two separate issues for that).
Screenshot 2024-01-24 at 7 55 46 pm

@lb- lb- changed the title Improve Security / UX of password-protected pages Improve Security / UX of private pagse using a shared password Jan 26, 2024
@lb- lb- changed the title Improve Security / UX of private pagse using a shared password Improve Security / UX of private pages using a shared password Jan 26, 2024
@lb-
Copy link
Member

lb- commented Jan 26, 2024

OK - I have updated this issue's description to hopefully align with the agreed items.

I have created three new issues:

And left two tasks as standalone on this issue (we may opt to do/not do these or split these later).

  • Add internal code comments with clarity that the 'password' is not the same as a full security password, maybe even updating internal field names to shared_password to alleviate future concerns.
  • Add the ability to have a password validators configured (e.g. min length) leveraging the Django password validation system.

@lb-
Copy link
Member

lb- commented Feb 17, 2024

Just added #11640 to the main issue description, a new enhancement suggestion has come up to allow either disabling privacy features completely or having even more control over them.

Input welcome on that issue. cc @RealOrangeOne

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

Successfully merging a pull request may close this issue.

5 participants