Opened 22 months ago
Last modified 2 weeks ago
#61644 new feature request
Invalidate application password
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | 5.6 |
| Component: | Application Passwords | Keywords: | has-patch has-unit-tests |
| Focuses: | rest-api | Cc: |
Description
Currently application passwords does not have any expiration. Due security issue as password is returned in query string and all GET requests are logged in webserver logs we need to invalidate those tokens programatically.
To revoke token we need to get uuid because it is not possible to delete token by appId. Currently there is endpoint GET /wp-json/wp/v2/users/me/application-passwords/introspect but because this is GET request method it is cached by litespeed cache plugin and returns cached results.
So my proposal would be to:
- Add ability to revoke token based on appId as this is known value to application
- Change request method to POST for wp-json/wp/v2/users/me/application-passwords/introspect as litespeed cache plugin is not caching POST requests
Change History (2)
#1
@
22 months ago
- Focuses rest-api added
- Severity changed from major to normal
- Version changed from 6.5.5 to 5.6
This ticket was mentioned in PR #11535 on WordPress/wordpress-develop by @yashyadav247.
2 weeks ago
#2
- Keywords has-patch has-unit-tests added
Core Track Ticket: https://core.trac.wordpress.org/ticket/61644
Problem
Application passwords can currently only be revoked through the REST API by their internal uuid or by deleting all passwords for a user. For clients that only know their own app_id, there is no supported way to invalidate the matching credentials programmatically. This becomes a security concern because newly created application passwords are returned once and may end up exposed through logged URLs or other downstream logging systems, while the client still lacks a direct way to revoke them by its known identifier.
Root cause
WordPress stores both a per-password uuid and an optional application-provided app_id, but the delete flow is only wired to the password uuid. The collection delete endpoint only supports deleting all application passwords, and the internal helper layer had no delete-by-app_id capability. Although app_id is exposed in the REST schema, it was not usable as a revocation key.
Solution
Extend the existing collection delete endpoint to accept an app_id query parameter and revoke all application passwords for the target user that match that app_id. This keeps the existing single-item DELETE .../<uuid> route unchanged, preserves the collection delete response shape of deleted and count, validates app_id as a UUID, and adds an internal WP_Application_Passwords helper to remove all matching records while continuing to fire the existing wp_delete_application_password action for each deleted password. Focused REST API tests were added to cover matching deletes, multiple matches, zero matches, invalid app_id, and unchanged delete-all behavior.
Hi @senna765,
Thanks for the ticket and welcome to Trac!
I could see us adding this. Probably as a
DELETE /wp/v2/users/me/application-passwords?app_id=blah.We wouldn't be making this change. This is a read action, it should not have
POSTsemantics. If the Litespeed plugin is caching an authenticated route, that's incorrect. The REST API sends nocache headers on authenticated requests.