Skip to content

fix: a public link needs the permission to view the password it shares - #941

Merged
blaipr merged 1 commit into
mainfrom
fix/a-public-link-needs-the-password-it-shares
Sep 24, 2026
Merged

blaipr merged 1 commit into
mainfrom
fix/a-public-link-needs-the-password-it-shares

Conversation

@blaipr

@blaipr blaipr commented Sep 24, 2026

Copy link
Copy Markdown
Member

A public link is the account's password, handed to whoever holds the URL. Creating one decrypts the password with the master key and seals it into the link's vault, and the creator can open the link like anyone else.

Which accounts can be linked was already bounded: getDataForLink() reads through AccountFilterUser, as getPasswordForId() does. The profile's own view-password permission, though, was only checked where the password is shown directly. The account view offers the link button only on isShowLink() && isShowViewPass(), but none of the three create paths checked the second half:

  • the account view
  • the links page
  • POST publicLink/create, which answers with the new hash

So a profile allowed to publish links (PUBLICLINK_CREATE) but not to view passwords could read the password of every account it could list, by linking it.

Change

PublicLink::create() now refuses with AccountPermissionException unless checkUserAccess(ACCOUNT_VIEW_PASS) passes. All three doors reach it. Refresh is unchanged: it re-seals an existing link and hands the caller nothing new.

Tests

  • Unit: create() asks for ACCOUNT_VIEW_PASS and is refused without it, before anything is decrypted.
  • Integration (real container and DB): an owner whose profile may publish links but not view passwords is refused.
  • The existing "cannot mint for an unreadable account" test now runs with the view-password permission and expects NoSuchItemException. Otherwise it would pass on the new check instead of the account filter it exists to prove.
  • The hand-built contexts in AccountAccessTest and PublicLinkRoundTripTest now carry a profile. Acl refuses a session without one, administrators included.

Both new tests were mutation-verified: they fail without the fix.

@blaipr
blaipr merged commit fe0273a into main Sep 24, 2026
8 checks passed
@blaipr
blaipr deleted the fix/a-public-link-needs-the-password-it-shares branch September 24, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant