- NEW: Licenses – Licenses can now be read and managed through the WordPress Abilities API (requires EDD 3.7.1 or later).
- Security: Package download links are now signed with a site-specific secret, so their expiration can’t be forged.
- Security: The license renewal form no longer reveals a license’s details or renewal price to anyone other than the license owner.
- Security: Fixed an issue that allowed license upgrade and renewal prices to be changed at checkout.
- Security: Fixed an information disclosure issue where the update API could describe unpublished or password-protected products.
- Security: Fixed a stored cross-site scripting issue in the product changelog.
- Security: Fixed a server-side request forgery issue in the product readme.txt location.
- Security: Deleting a license, including through bulk actions, now requires the delete licenses capability.
- Security: Added cross-site request forgery protection to the activation limit and renewal notice actions on the licenses screen.
- Security: Fixed a reflected cross-site scripting issue on the licenses screen.
- Security: Bulk actions on the licenses screen now require the same capabilities as their single-license versions.
- Security: Fixed a SQL injection issue in the licenses list table’s sort order.
- Security: Fixed an issue that could reveal another customer’s activated site URL when adding a site to a license.
- Security: Exporting license keys now requires permission to manage licenses.
- Security: Product changelogs, descriptions, and upgrade notices sent by the update API are now limited to the same HTML as other product content.
- Security: Fixed a SQL injection issue in the license export’s status filter.
- Security: Fixed an issue that let an unauthenticated request delete an order’s licenses while the order remained.
- Admin: The Licenses screen’s page title is now “Licenses”.
- Admin: Fixed the plugin requirements notice styling on the Plugins screen in WordPress 7.1.
- Admin: The license upgrades page no longer appears in the WordPress command palette.
- Admin: Fixed sending a renewal notice to an expired license from the licenses screen’s bulk actions.
- Admin: Clicking Filter on the licenses screen no longer runs the selected bulk action on checked licenses.
- Admin: The licenses screen keeps the search term and tab when it reloads after a bulk action.
- API: The update API no longer describes unpublished, private, or password-protected products unless the request includes an active or expired license for that product. A disabled license no longer counts.
- Blocks: Restored the cancel button on the license renewal form.
- Downloads: Update package download links use a new signature, so links generated before updating stop working. They expire on their own within the store’s download link expiration (24 hours by default).
- Downloads: Product changelogs no longer allow scripts, iframes, or other HTML outside what post content allows, so embedded videos in a changelog are removed.
- Downloads: A product’s readme.txt location must be a public URL. Local and private network addresses are no longer fetched, and invalid URLs aren’t saved.
- Emails: Renewal notices are no longer sent for licenses whose product has been deleted.
- Emails: Fixed the bulk Send Renewal Notice action sending nothing for licenses that had not expired.
- Licenses: A license must be attached to a user account to be upgraded. A license with no account, such as one from a guest purchase, can no longer be upgraded.
- Licenses: Fixed a fatal error when running retroactive licensing on bundles with an unresolvable child license.
- Renewals: In the license renewal form and block, a license attached to a user account can only be renewed by that user.
- Renewals: With email matching enabled, a guest renewing a license attached to an account is now asked to log in.
- Renewals: Renewing a license no longer removes the same product from the cart when it’s already there as a new purchase. Both stay in the cart.
- Renewals: Fixed a false “already in your cart” message when renewing a product that was in the cart as a new purchase.
- Dev: Deprecated
EDD_Software_Licensing::get_download_package(). UseEDD\SoftwareLicensing\Downloads\Package::get_download_package(). - Dev: The activation limit AJAX handlers now return a JSON response instead of a raw number.
- Dev: The
edd_sl_package_download_computed_hashfilter now applies when package URLs are generated, not only when they’re validated. - Dev: Package download link expiration is now generated and checked in UTC.

