The WordPress coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. development team builds WordPress! Follow this site for general updates, status reports, and the occasional code debate. There’s lots of ways to contribute:
Found a bugbugA bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority.?Create a ticket in the bug tracker.
WordPress 5.6 will finally see the introduction of a new system for making authenticated requests to various WordPress APIs — Application Passwords.
The existing cookie-based authentication system is not being removed, and any custom authentication solutions provided by plugins should continue to operate normally.
For any sites using the Application Passwords feature plugin, it is recommended to deactivate the pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party after upgrading to WordPress 5.6. However, sites won’t experience any errors if the plugin remains active. The current plan is to use the plugin for future prototyping.
Application Password Format
Application Passwords are 24-characters long, generated by wp_generate_password() without the use of special characters — so they consist exclusively of upper-case, lower-case, and numeric characters. For the cryptographically curious, that comes to over 142 bits of entropy.
When presented to the user for entering into an application, they are displayed chunked for ease of use, like so:
abcd EFGH 1234 ijkl MNOP 6789
Application passwords can be used with or without the spaces — if included, spaces will just be stripped out before the password is hashed and verified.
Data Store
WordPress will be storing a user’s application passwords as an array in user metaMetaMeta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress., similar to how interactive login sessions (via WP_Session_Tokens) are stored already.
The WP_Application_Passwords class has all the methods for storing and retrieving records. Records include a number of attributes about them — including assigned name for the application, a timestamp for when it was created, and data on their last usage such as, date and IP address. Each application password is also assigned a uuid for reference, in case you’d like to build infrastructure for additional properties and store them in an alternate location.
Getting Credentials
Generating Manually
From the Edit User page, you can generate new, and view or revoke existing application passwords. The form and the list table are both fully extensibleExtensibleThis is the ability to add additional functionality to the code. Plugins extend the WordPress core software. to allow for overloading to store additional data (more on this later, in “Authentication Scoping”).
The Edit User screen, after a new application password has been created.
Once a given password has been used, it will keep track of where and when it has been used – the “Last Used” column is accurate to within 24 hours (so that WordPress isn’t writing to the database on every usage — only if it’s a new day). This can be incredibly useful for identifying passwords that are no longer in use, so that they can be safely revoked.
Authorization Flow
To ensure that application password functionality is available, fire off a request to the REST APIREST APIThe REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. root URLURLA specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org, and look at the authentication key in the response data. If this key is empty, then application passwords are not available (perhaps because the request is not over https:// or it has been intentionally disabled).
If, however, response.authentication is an object with a key of application-passwords it will offer a URL to send a user to complete the authentication flow. (You could just guess at the URL, but this gives us more of the relevant information in one go, as well as confirming that application passwords are available and enabled.)
The response.authentication['application-passwords'].endpoints.authorization url will likely look something like this:
Instead of just sending the user there to generate an application password, it would then be up to the user to reliably re-enter it into your application. So instead, some additional GET parameters are accepted along with the request:
app_name (required) – The human readable identifier for your app. This will be the name of the generated application password, so structure it like … “WordPress Mobile App on iPhone 12” for uniqueness between multiple versions. Whatever name you suggest can be edited by the user if they choose before the application is created. While you can choose to not pre-populate it for the user, it is required to create a password, so they will then be forced to create their own, and could select a non-intuitive option.
app_id (recommended) – a UUID formatted identifier. The app_id allows for identifying instances of your application, it has no special meaning in and of itself. As a developer, you can use the app_id to locate all Application Passwords created for your application. In the event of a data breach, your app_id could be distributed to void credentials generated with it, or if a site wants to allow only a given app_id or set of app_ids to register, this would enable that. However, it is strictly on the honor system — there is nothing to stop applications from generating new uuids with every authorization.
success_url (recommended) – The URL that you’d like the user to be sent to if they approve the connection. Three GET variables will be appended when they are passed back (site_url, user_login, and password); these credentials can then be used for APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. calls. If the success_url variable is omitted, a password will be generated and displayed to the user instead, to manually enter into their application.
reject_url (optional) – If included, the user will get sent there if they reject the connection. If omitted, the user will be sent to the success_url, with ?success=false appended to the end. If the success_url is omitted, the user just will be sent to their WordPress dashboard.
A screenshot of what the authorization flow will look like to a user.
As the parameters are all passed in via GET variables, if the user needs to log in first, they will all be preserved through the redirect parameter, so the user can then continue with authorization.
It is also worth noting that the success_url and redirect_url parameters will generate an error if they use a http:// rather than https:// protocol — however other application protocols are acceptable! So if you have a myapp:// link that opens your Android, iOS / MacOS, or Windows — those will work!
The application passwords authentication scheme can also be applied to future APIs for WordPress as they become available. For example, if GraphQL or other systems are enabled in WordPress, application passwords will provide them with a solid, established authentication infrastructure to build off of out of the box.
You can’t. 😅 The point of application passwords are that they are to be used programmatically for applications, and not by humans for interactive sessions.
Feature Availability
By default, Application Passwords is available to all users on sites served over SSLSSLSecure Sockets Layer. Provides a secure means of sending data over the internet. Used for authenticated and private actions./HTTPSHTTPSHTTPS is an acronym for Hyper Text Transfer Protocol Secure. HTTPS is the secure version of HTTP, the protocol over which data is sent between your browser and the website that you are connected to. The 'S' at the end of HTTPS stands for 'Secure'. It means all communications between your browser and the website are encrypted. This is especially helpful for protecting sensitive data like banking information.. This can be customized using the wp_is_application_passwords_available and wp_is_application_passwords_available_for_user filters.
For example, to completely disable Application Passwords add the following code snippet to your site.
Without SSL, it is possible for the Application Password to be seen by an attacker on your networknetwork(versus site, blog) or the network between your site and the authorized application. If you are ok with this risk, you can force availability with the following code snippet.
If desired, it is possible to restrict what users on your site can use the Application Passwords feature. For example, to restrict usage to administrator users, use the following code snippet.
In future versions, the expectation is to include the ability to scope a given application password to limit its access. The intention is to work on building this in plugin-land until it’s ready for a core proposal.
What might password scoping look like? Here’s some methods being considered:
In a multisitemultisiteUsed to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site environment, either restrict the credentials to a subset of the user’s blogs, or restrict it to only operate in a normal “blogblog(versus network, site)adminadmin(and super admin)” context, and not a “network admin” context.
Restrict functionality to only manage content — posts, pages, comments, custom post types — and disallow infrastructure management functionality like managing plugins, themes, and users.
Restrict the role that credentials can allow an application to operate as. For example, an Editor may restrict a set of credentials to only operate as though they had Author or Contributor permissions.
However this is done, implementing additional functionality to enforce the principle of least privilege on an application-by-application basis is a worthwhile expansion on the included functionality.
Fine-grained CapabilitiescapabilityA capability is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on their role. For example, users who have the Author role usually have permission to edit their own posts (the “edit_posts” capability), but not permission to edit other users’ posts (the “edit_others_posts” capability).
Right now, a user’s application passwords can be managed by any user who has permission to edit_user them. The ability to customize this behavior using a new set of more fine-grained capabilities is currently planned for 5.7.
Eventually Two-Factor Authentication?
Another useful bit of application passwords is that it will removes an obstacle for the inclusion of multi-factor authentication on interactive logins.
Previously, if you enabled an interactive step — whether captcha or second factor validation — on login pages, you would be in a bind with other non-interactive authentications, for example the legacy XML-RPC system. After all, if a bad actor can just brute force or use social engineering to discern the user’s password, it would be trivially usable via XML-RPC, where there is no ability to include an interactive prompt, and that functionality would need to be disabled entirely.
With that use case now being provided for via application passwords, there is additional flexibility for the normal browser-based wp-login.php system to evolve.
Further Resources
Core TicketticketCreated for both bug reports and feature development on the bug tracker.: #42790
Feature Plugin. Further development of App Passwords will be prototyped in this repo.
For bugbugA bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority. reports or enhancements, open a Trac ticket in the new App Passwords component with the rest-api focus.
Problem statement: no way to authenticate third-party access to REST APIREST APIThe REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/.
Ever since the REST API infrastructure merged via #33982 and shipped in WordPress 4.4 in December 2015, it’s been gaining momentum and been used in more and more places—throughout WordPress’s adminadmin(and super admin), via plugins and themes, and enabled deep, robust interactions powering new functionality such as the GutenbergGutenbergThe Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. editor.
However, the functionality has been limited in that the only way to make authenticated requests to the APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. in coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. has been through Cookie & Nonce-based authentication—there is no good way for third-party applications to communicate with WordPress in an authenticated fashion, apart from the legacy XML-RPC API.
This has resulted in frustration for our Mobile teams especially as they’re working to integrate Gutenberg support, which relies on the REST API. After some time having to store username/password to spoof a cookie and interactive session to scrape a nonce from the wp-admin DOM, and then to use an endpoint to get it instead via [46253]. All of which is a tremendously messy and awkward usage that completely falls apart if someone uses a variant of a two-factor authentication system.
Spoofing an interactive session just to make API requests is bad form and needlessly complex.
There have been many systems considered, including everything from multiple incarnations of OAuth, JWT, and even some solutions that are combinations of the two. Some called for a centralized app repository, some had open registration, but all were complex and none of them could build sufficient traction to come to fruition.
A simpler alternative to Application Passwords is pure Basic Authentication and detailed in #42790. However, Application Passwords is more comprehensive, and a far superior of a choice for the reasons that follow.
Benefit: Ease of API Requests
Given a login and an application password, making an API request is as simple as
curl --user "USERNAME:APPLICATION_PASSWORD" -X POST -d "title=New Title" https://my.wordpress.site/wp-json/wp/v2/posts/POST_ID
It uses the standard HTTPHTTPHTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. authorization headers. Everything supports this trivially.
Benefit: Ease of Revoking Credentials
Application Passwords makes it easy to revoke any individual application password, or wholesale void all of a user’s application passwords. Application Passwords also lists the date a password was last used and the IP it was used from to help track down inactive credentials or bad actors using them from unexpected locations.
Benefit: Ease of Requesting API Credentials
While it is possible for a user to go to their user profile page and generate a new application password, for example if they are creating a command line tool for themselves, the ideal workflow looks something like this:
To request a password for your application, redirect users to:
The URLURLA specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org is included in the REST API index to facilitate automated discovery.
and use the following GET request parameters to specify:
app_name (required) – The human readable identifier for your app. This will be the name of the generated application password, so structure it like … “WordPress Mobile App on iPhone 12” for uniqueness between multiple versions. If omitted, the user will be required to provide an application name.
success_url (recommended) – The URL that you’d like the user to be sent to if they approve the connection. Two GET variables will be appended when they are passed back (user_login and password); these credentials can then be used for API calls. If the success_url variable is omitted, a password will be generated and displayed to the user, to manually enter into your application.
reject_url (optional) – If included, the user will get sent there if they reject the connection. If omitted, the user will be sent to the success_url, with ?success=false appended to the end. If the success_url is omitted, the user will be sent to their WordPress dashboard.
If the user is logged out, they’ll be redirected to the WordPress Login page. After logging in, they’ll be immediately redirected back to the Authorize Application screen.
In discussions with @timothyblynjacobs we’re unsure about whether to add a state parameter (which is just stored and passed back to the application to prevent CSRF attacks). Realistically apps could just include it on their own in the success_url or a site_url parameter (which could remind the application what site the returned credentials are for). Requiring apps to pass a state parameter could encourage best practices, but we wouldn’t be able to enforce that they validate its contents.
It’s also worth noting that the success_url and reject_url are both explicitly designed that apps can pass in custom protocols for the return URLs. That is, they could set them to be wordpress://authentication so that the user’s phone automatically redirects them back from their web browser, directly into the application with the credentials appended to the query. You may have seen this previously with other applications where you “Login with Facebook” in your browser and then Facebook sends you directly back into your app. Or with how your web browser can open Zoom directly on your laptop, pre-populating the room ID and password.
Benefit: Login Security
Unlike pure basic auth that requires entering in credentials directly into the application, Application Passwords allows for an interactive authentication flow. This means that login security features like Two Factor or reCAPTCHA can continue to protect user accounts.
One of the reasons XML-RPC is so often recommended to be disabled is that it allows brute forcing user’s passwords since those additional security protections can’t be implemented. A risk of implementing pure basic auth is that sites will be forced to disable it because it can’t be interactive.
Proposed solution: merge Application Passwords to core
Props to @timothyblynjacobs for help on the content of this post, @jeffpaul for help on the structure of this post, and the many many people who have contributed to the analysis behind this proposal and to Application Passwords.