github nilsteampassnet/TeamPass 3.2.2.5

5 hours ago

What's Changed

This is a maintenance release on the 3.2.2 line. It closes two access-control flaws: copying a folder could write into folders the user cannot access and duplicate items the user is restricted from, and moving an item, from the edit form or the REST API, did not require the right to remove it from its folder (GHSA-q47m-rvr6-jqw7, GHSA-vxv5-cr34-5q7g). It also adds optional renewal periods on individual items and opens the Renewal page to every non-administrator user, and rebuilds the Monitoring → Logs page around a single filter panel. The bug fixes cover accented characters saved as HTML entities, Active Directory groups that were never mapped to roles, S3 backup restores, and the e-mail test button that never reported an error. Upgrading is required for every installation.

This release changes the database schema. UPGRADE_MIN_DATE is raised, so every installation goes through the upgrade wizard once. The migration adds one column to the items table and one index to the LAPR endpoints table. It rewrites no existing data.

🔒 Security fixes

  • Copying a folder could write into inaccessible folders and duplicate restricted items (GHSA-q47m-rvr6-jqw7) - the folder copy only rejected a target that was in the user's read-only list. It also read the personal-folder flag, which opens the creation gate, from any folder row. Any user could therefore copy folders and items into a folder they cannot see, including another user's personal tree. The copy decrypted items the user is restricted from with the server key and stored unrestricted copies. Because the read-only list also holds the folders forbidden to the user, a forbidden subfolder was copied along with its items. The target must now be a folder the user can access. The copied folders are re-resolved from the database and limited to the user's scope, restricted items are skipped, and copies carry the personal flag of the folder they land in. Reported by @kta1kri.

  • The REST API moved items without the delete right on the source folder (GHSA-q47m-rvr6-jqw7) - PUT /item/update with a new folder_id only required the edit right on the item's folder, and only "not read-only" on the target. A user with the ND (no delete) level could therefore take items out of a folder, and could move items into NE or NDNE folders. A move now follows the web move_item rule: delete on the source folder and edit on the target, otherwise 403 before anything is written. Reported by @kta1kri.

  • The item edit form checked move rights on the wrong folder (GHSA-vxv5-cr34-5q7g) - when an item was saved with a different folder, update_item computed the user's rights once, on the destination folder sent by the browser, and used that answer for the "may delete from the old folder" check. A user with the ND level on a shared folder could move its items into any folder of their own. Rights are now evaluated on the item's actual folder (edit to save, delete to move the item out), and the destination is checked separately (edit), like the other move paths. Reported by @kta1kri.

  • Moving an item to a personal folder through the API left other users' keys on it - PUT /item/update only changed the folder, so every user of the source folder kept a key on an item that now sat in someone's personal folder. The web move removes those keys. The API move now deletes them in the same transaction, keeping only the owner's key and the system accounts' keys. It answers 422 without writing anything when the caller does not yet hold every key of the item, which typically happens while the background distribution of a new item's keys is still running. A key distribution that finishes after the move narrows the keys again.

✨ New features

  • Individual password renewal periods, and a Renewal page for every user (PR #5378, @guerricv) - an item can now carry its own renewal period (1 to 36500 days), set from its main tab by anyone who can edit it, on personal and shared items alike. It works even when the folder expiration feature is off. When a folder period also applies, the shorter one wins. Deadlines count from the last password change or from creation. Moving an item or changing its period does not reset that age, while a copy starts a new one. The Renewal page moves from the administration area to the user sidebar, next to Favourites. It lists every accessible item with a known deadline, expired first, with an optional cut-off date, and it respects folder rights, personal folders and item restrictions. Folder banners, the item form and move confirmations show the policy that applies and the resulting deadline. The item list shows an orange hourglass within 14 days of the deadline and a red crossed calendar once it has passed. Expiration remains advisory: nothing is deleted and reading is never blocked. Items linked to LAPR are excluded from ordinary renewal while the module is enabled. Security Posture and the governance reports use the effective deadlines. The REST API reads and writes renewal_period.

🛠️ Improvements

  • Monitoring → Logs rebuilt around one filter panel (issue #5363) - the eight tabs are replaced by three log sources, filtered from a search-style facet panel. Authentication lockouts keep their own screen, because they show live state with unlock actions rather than a journal. The purge now uses the filters the table displays, so it deletes exactly what is on screen, and the separate purge form below the table is gone. A filter that a purge cannot express is refused instead of being approximated.

  • API authentication refusals are now diagnosable - the API still answers every refusal with the same 401 Invalid credentials, but the log now names the cause: unknown or disabled account, API access not enabled, wrong password, private key awaiting re-encryption, outdated extension token, and so on. For LDAP accounts, the log states that the API compares the password with the one seen at the last web sign-in, never with the directory. The profile warns when API access is off for the account or when its key awaits re-encryption, and administrators see a notice listing the accounts in that state. Every user allowed to use extension tokens can now list and revoke them. Tokens are deleted when the user's key pair is regenerated, and a token that predates such a regeneration is refused. Purging a user also deletes their tokens and API sessions.

  • Readable selected values in multiple-choice fields - the selected values were rendered as white text on a light grey background (1.3:1 contrast). They now use a dark background with a 5:1 contrast.

  • Browser extension documentation rewritten - installation from the Chrome, Edge and Firefox stores replaces the ZIP procedure. The page now documents the setup wizard, the settings page and the vault lock, and it updates the licence, troubleshooting and fleet deployment sections.

🐛 Bug fixes

  • Accented characters were saved as HTML entities when client/server encryption is disabled - since 3.2.0.0, 17 request handlers read the incoming data through a filter that behaves like htmlentities(). With encryption between the browser and the server turned off, "é" was saved as é, for example in folder titles, and a literal < typed in an export or e-mail template came back decoded. The data is now read unaltered, and a test guarantees that both transport modes decode to the same values. Installations running with encryption enabled, the default, were not affected.

  • Active Directory groups were never mapped to roles when the user DN attribute setting was empty - the installer seeds this setting with an empty value, and the group lookup did not replace it with distinguishedName. It found no user DN, so no AD group was ever mapped to a role at sign-in. An empty setting now resolves to distinguishedName, with a fallback to the entry's DN. The LDAP synchronization of the Users page no longer spins forever when the directory request fails.

  • Restoring a backup stored on S3 failed with "Malformed UTF-8 data" (issue #5376, PR #5379, @guerricv) - because of the order in which two cURL options were set, the downloaded backup was written into the page's response instead of the temporary restore file, which stayed empty. The download now lands in the file. An empty or truncated download is reported as a download failure instead of a misleading decryption error.

  • The e-mail test button never reported a failure (issue #5361) - PHPMailer kept its 300-second timeout, so an unreachable SMTP relay held the request until a reverse proxy answered 504, and the "in progress" message stayed on screen. The error returned by the mail server was also discarded, so every caller read a success. At sign-in, the pending e-mail sender flagged failed messages as sent and removed them from the queue. The SMTP timeout is now 30 seconds, and 10 seconds for the two test buttons. The server's answer is reported in the interface, failed messages stay queued, and the SMTP conversation is shown under the test button when a debug level is selected.

  • Clearing Knowledge Base logs without dates deleted every matching entry - the Knowledge Base log purge deleted every row for the selected user and action when both dates were left empty. It is now bounded in time.

  • A user's log could include entries recorded for an IP address - the actor column of the system log holds either a user ID or an IP address, and it was compared as an integer, so 10.0.0.5 matched user 10. It is now compared as text.

⬆️ Upgrade notes

  • Schema. The upgrade adds a renewal_period column (unsigned integer, default 0) to the items table and an index on the credential column of the LAPR endpoints table. Existing items start with no individual renewal period. UPGRADE_MIN_DATE is raised, so every installation goes through the upgrade wizard once; the Docker entrypoint runs the migration on start.
  • Renewal page. The page leaves the administration area. Administrators no longer have it, and they supervise renewals through the compliance reports. Non-administrator users find it in their sidebar, even when folder expiration is disabled. Items linked to LAPR no longer count as overdue or as missing an expiration, so Security Posture figures can drop after the upgrade.
  • Moving items. A user with the ND, NE or NDNE level can no longer move items out of that folder, from the web or from the API. An API move also needs the edit right on the target folder. Review the folder rights of users who relied on the previous behaviour.
  • REST API clients. Moves refused by the rules above answer 403. A move to a personal folder answers 422 while the caller does not yet hold every key of the item: retry once the background key distribution has finished. Item reads now return renewal_period, and item creation and updates accept it; omitting it on an update keeps the current value. A correct password is refused (401) while the account's private key awaits re-encryption after a directory password change, until the user signs in to the web interface once.
  • Values saved as HTML entities. Text already saved as é while client/server encryption was off is not rewritten. Saving the object again, such as renaming the folder, repairs it.
  • Back up your database before upgrading, as always.

Full Changelog: 3.2.2.4...3.2.2.5

Important

  • Requires at least PHP 8.2

Languages

Please join Teampass v3 translation project on Poeditor and translate it for your language.

Installation

Follow instructions from Documentation.

Upgrade

Follow instructions from Documentation.

Ideas and comments

Are welcome ... please use Discussions.

Download TeamPass

Don't miss a new TeamPass release

NewReleases is sending notifications on new releases.