Proposal: REST API Authentication / Application Passwords – Make WordPress Core
Skip to content
Make WordPress Core
Welcome!
The WordPress
core
Core
Core 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
bug
bug
A 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.
Want to contribute?
Get started quickly with tickets marked as
good first bugs
for new contributors or join a
bug scrub
. There’s more on the
reports page
, like
patches needing testing
, and on
feature projects page
Other questions?
Here is a detailed
handbook for contributors
, complete with tutorials.
Communication
Core uses
Slack
for real-time communication. Contributors live all over the world, so there are discussions happening at all hours of the day.
Core development meetings are every Wednesday at
15:00 UTC
in the
#core
channel on
Slack
. Anyone can join and participate or listen in!
Problem statement: no way to authenticate third-party access to
REST API
REST API
The 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”)
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
admin
admin
(and super admin)
, via plugins and themes, and enabled deep, robust interactions powering new functionality such as the
Gutenberg
Gutenberg
The 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.
block
Block
Block 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
API
API
An 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
core
Core
Core 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.
We’d like to propose integrating
Application Passwords
into Core.
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.
Broad conceptual overview of varying methods (See:
WP-API/authentication#15
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
HTTP
HTTP
HTTP 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
URL
URL
A 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.
"name": "Trunk",
"authentication": {
"application-passwords": {
"endpoints": {
"authorization": "http://example.com/wp-admin/authorize-application.php"
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
While there is a
standalone plugin for Application Passwords
that’s developed in a
GitHub repo
PR#540 to WordPress-develop
is the official work we’re proposing to be merged into core. The pull request is based off of the original
feature plugin
Feature Plugin
A plugin that was created with the intention of eventually being proposed for inclusion in WordPress Core. See
Features as Plugins
’s codebase. We welcome comments on this proposal post, contributions to
Application Passwords
itself, and even more so review and feedback on the
existing merge proposal pull request
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.
application-passwords
authentication
rest-api
two-factor
Share this:
Share on Threads (Opens in new window)
Threads
Share on Mastodon (Opens in new window)
Mastodon
Share on Bluesky (Opens in new window)
Bluesky
Share on X (Opens in new window)
Share on Facebook (Opens in new window)
Share on LinkedIn (Opens in new window)
Yes! Let’s do this! (Although TBH I’d probably say yes to any of the proposed solutions… I admit I just want to support whichever initiative has hustlers behind it, and application passwords sounds like a good enough user
UX
UX
User experience
and a super simple developer UX.)
I admit that I have not researched
which
authentication method I believe is best, but I am very excited at some form of authentication being included in
Core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
for the
REST API
REST API
The 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”)
Sounds like a plan to me! Application passwords were a bit frustrating at the first time when I came across one, but I’ve learnt to love those because of the easy way revoking a one without the need to change credentials everywhere.
Oh yes, please! Maybe add oAuth 2 in the future, but a battle ready implementation of auth sometime soon would be amazing.
Yes pleas! We need some better authentication as we have now. And this way is preferable over just BASIC-Auth.
This would be great. I’ve used the existing application passwords
plugin
Plugin
A 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
or can be cost-based plugin from a third-party.
and it is solid, minimalist and gets the job done. The only comment I would make is to the demonstration of authenticating an application where the password gets sent back to the
success_url
or
reject_url
. Should this require
HTTPS
HTTPS
HTTPS 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.
so the application password doesn’t get sent over plaintext? In fact, I wonder if the whole application password system should only work if the site is running on HTTPS unless e.g.
WP_DEBUG = true
or the environment mode is set to development.
Already being discussed!
Here’s a bit more for context:
I’m somewhat torn on it, as it feels somewhat odd to require
https
HTTPS
HTTPS 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.
to fire the request to the
REST api
REST API
The 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”)
, but you can pass the same credentials — or even your real credentials into xmlrpc without https and have them work. 🤷♂️
Personally I’d be fine either way. Do we know yet what percentage of sites have https available?
The fact that it works for XMLRPC is, IMHO, a historical necessity that’s now a
bug
bug
A 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.
we should fix, not something we should replicate. Opened
a ticket
for this just this morning.
I’m just in favor of consistency, whichever direction that goes.
Also may be worth offering a warning on wp-login.php as well if not
https
HTTPS
HTTPS 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.
I second what Joost said! If we’re going to be consistent lets do it with the good parts and not sacrifice security
I also don’t want to let perfect be the enemy of good, and if for a few releases we have authentication for the new
rest api
REST API
The 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”)
requriing
https
HTTPS
HTTPS 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.
for requests while xmlrpc doesn’t — with a plan in place to eventually require it for xmlrpc after a specified version — that’s fine by me too.
> Do we know yet what percentage of sites have
https
HTTPS
HTTPS 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.
available?
85+% of the web in general now runs on https –
– I suspect this may be even higher for WordPress sites.
I forgot to add this to the post. The number I got from
dd32
was ~75% of WordPress sites that have reported to
WordPress.org
WordPress.org
The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization.
as being `
https
HTTPS
HTTPS 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.
` at least
once
. It may be less than that if a site was served over HTTPS in the past.
+1 for
HTTPS
HTTPS
HTTPS 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.
Oh, and /by the way/ for a Steve Jobs-esque “one more thing” — application passwords work for xmlrpc requests as well. So it can be an easy upgrade for any existing apps that already use xmlrpc to be more secure.
The only thing they won’t ever do is work on wp-login.php
Yes, I like the idea to have application passwords working on the XML-RPC layer. We can start using it in mobile apps, and at the same time start working on migrating the apps to the
REST API
REST API
The 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”)
. XML-RPC does already send the clear password on the wire, so I see this only as an improvement for those sites that still use plain
HTTP
HTTP
HTTP 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.
I am / we are 100% in favor of this. Opening this up is like opening the dawn of a new era of WordPress based web applications. Suddenly authentication is not something you need to fix when working with the
API
API
An 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.
and you can just build awesome stuff.
Good job, you have all our support, and I’m going to try and find some people to help you land this.
I think this is a great thing to do!
I like this proposal and approve of a merge. Anything I can do to help ship this let me know!
Thank you for working on this. This would be a first step to replace the use of XMLRPC in the mobile apps and it would allow us to add more features for self hosted users.
This is a fantastic proposal and obviously something that has been thought thru over a long period of time. Thank you for going above and beyond. I look forward to seeing this in
Core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
as well as your two-factor
feature plugin
Feature Plugin
A plugin that was created with the intention of eventually being proposed for inclusion in WordPress Core. See
Features as Plugins
Funnily enough, application-passwords was
initially written as a part of the two-factor feature plugin
— as we would need a way to allow folks to continue to use xml-rpc requests even if two-factor was enabled — as it would be silly to secure `wp-login.php` with two-factor, but leave
core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
’s api’s open without requiring an interactive second factor, which is kinda hard to do for api requests! (Generate a new totp code every 30 seconds when you want to send api requests? No thanks!)
REST API
REST API
The 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”)
authentication is sorely needed, but I’m not convinced this is the right approach. When it comes down to it, Application Passwords is Basic Authentication with a few user experience improvements for connecting apps, but it offers little in the way of additional security.
Inability to identify clients/apps
One major flaw is that the WordPress site can’t identify (much less verify) the clients accessing it. The last used date and last IP might be useful for identifying inactive passwords, but they’re pretty useless from a security point of view since they’re only updated once a day and the IP is overwritten by subsequent updates. Unauthorized clients could easily access protected resources without being detected.
Not being able to identify a client also means the administrator of a site can’t revoke passwords across multiple users if a specific app were to be compromised. Every application password for every user would have to be revoked, which mitigates the usefulness of being able to revoke a single password.
External database breaches
External services would need to store application passwords in clear text in their databases. Because this solution doesn’t differentiate between authentication and authorization, these are essentially real passwords that give clients all the
capabilities
capability
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).
that a user has (at least all the functionality exposed in the REST API). If an attacker were to gain access to one of these databases, they’ll potentially gain access to the plaintext passwords for thousands of sites. We don’t store user passwords in clear text, so why should we encourage external clients to do it?
Credentials as
GET
parameters
Passing
user_login
and
password
as
GET
variables isn’t ideal. URLs are publicly viewable, stored in access logs, available in the browser history, can be bookmarked, etc. The
specification for URIs
has this to say:
URI producers should not provide a URI that contains a username or password that is intended to be secret.
Open redirect with
success_url
reject_url
Allowing a client to provide
success_url
and
reject_url
parameters sounds like an open redirect that’s ripe for abuse. An attacker that was able to modify the
success_url
could intercept the application password without the client or user ever being aware.
Security burden
While this solution is superficially similar to some of the OAuth flows, it doesn’t include many of the security considerations detailed in those specifications. It relies on users to understand which capabilities they’re granting an app, especially if they’re a site
admin
admin
(and super admin)
, and provides external clients with too much trust. Instead of taking on the challenge of addressing a complex problem, too much of the security burden is shifted to users, developers, and clients.
The OAuth specifications cover several attack vectors and how the protocol addresses them. I think it would be useful to at least consider these various vectors and categorically decide whether or not they should be addressed in a solution for
core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
I’d be delighted for a more in-depth discussion to address these concerns later, just trying to add some quick thoughts on a couple points now while making sure I’m not losing track of the devchat going on as I write this.
Inability to identify clients/apps
The same issue remains even if we went full OAuth and had open registration. The only way to really mitigate this would be a centralized app repository, which has long since been identified as a non-starter.
Also worth noting that this is also a problem with pretty much every other system, including the interactive wp-login.php ui for wp-
admin
admin
(and super admin)
and xml-rpc.
External database breaches
If any external database is storing passwords in plaintext in their database, I’d argue they’re `doing_it_wrong()` — this is why solutions such as
Vault
have been put together.
You also remark that
“We don’t store user passwords in clear text, so why should we encourage external clients to do it?”
— that’s largely because as WordPress
Core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
, we don’t need to /use/ the passwords, just verify a string matches a hash of the passwords. Or did you mean storing that plugins for WordPress don’t store api keys in plaintext in the options table? Because they absolutely 100% do.
An attacker that was able to modify the success_url could intercept the application password without the client or user ever being aware.
No, there isn’t an open redirect here. The success_url and reject_url are both explicitly shown to the user before they approve or reject anything. No user is forwarded to any url without their informed consent.
Anyway, will try to circle back later to address stuff I’d missed, or any issues you may take with my responses. Thanks for taking the time to share your thoughts. <3
The same issue remains even if we went full OAuth and had open registration. The only way to really mitigate this would be a centralized app repository, which has long since been identified as a non-starter.
As far as OAuth goes, I’m fairly certain this is covered in those specifications, so it’s not unsolvable. Even identifying the client making a request can be solved to some extent.
What I was referencing was the ability to identify which app a password was generated for, which would require a client identifier of some sort. It could be as simple as the “App Name” or an
app_id
as suggested by
timothyblynjacobs
below. That would allow all passwords associated with the client to be revoked. Otherwise, the functionality for revoking passwords that currently exists doesn’t scale and is only useful on a per user basis.
If any external database is storing passwords in plaintext in their database, I’d argue they’re `doing_it_wrong()` — this is why solutions such as Vault have been put together.
I think that’s placing too much trust in third parties. By handing them the plaintext password (in the
URL
URL
A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org
, nonetheless), I think we would be encouraging them to store it as is and we can’t just turn a blind eye to that.
I meant “we” as in WordPress
Core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
. I do realize that plugins store
API
API
An 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.
keys in plaintext in the database — I do as well in one of my own plugins. I can’t speak for every
plugin
Plugin
A 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
or can be cost-based plugin from a third-party.
, but in my case, the API keys have a limited set of
capabilities
capability
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).
. Application Passwords are similar to API keys and might be treated as such, but they don’t have any
capability
capability
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).
restrictions.
No, there isn’t an open redirect here. The success_url and reject_url are both explicitly shown to the user before they approve or reject anything. No user is forwarded to any url without their informed consent.
Allowing the user to verify the URL is a good step, but that’s still pretty open and ripe for abuse. It also provides a burden on the user to understand what’s going on, especially with something like the custom protocol used as an example in the proposal.
Thanks for taking the time to respond to my comments. I understand the desire to get an authentication solution into core, but wanted to register my concerns.
Thanks for your feedback
bradyvercher
I don’t disagree with much of your comments, but there are two things that we need to solve with an authentication solution.
1. Users should be able to connect to an application with a simple flow where they don’t have to preregister the application in a different screen. In other words, we can’t force users to first go to an Applications screen, and manually input all the OAuth details for the new application. And then go thru a connection flow.
2. A centralized registry of applications is not something
WordPress.org
WordPress.org
The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization.
can support. This is what was called “broker” authentication and would have allowed for applications to register themselves with WordPress.org, which would alleviate the issues in the first requirement.
Because of this, the
REST API
REST API
The 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”)
team back at
WordCamp
WordCamp
WordCamps are casual, locally-organized conferences covering everything related to WordPress. They're one of the places where the WordPress community comes together to teach one another what they’ve learned throughout the year and share the joy.
US 2019 explored OAuth 2 with Dynamic Client Registration. This allows for clients to register themselves without needing a central registry. That registration process can happen during the authentication flow, so it appears as seamless to the user.
I like this solution, but it is quite complex to implement and we haven’t been able to attract enough contributors to make it a reality.
Now, with those requirements and a OAuth Dynamic Client Registration implementation, we still wouldn’t be able to solve your listed issues.
Inability to identify clients/apps
A malicious application that used Dynamic Client Registration isn’t forced to use the same unique identifier for each instance. So it isn’t a guarantee that an administrator would be able to revoke all credentials for an application at once.
Application Passwords does support an “App Name” that can be used to identify an application. We could build a tool to revoke all applications with the same App Name. Or potentially, we could also support an
app_id
parameter that would be stored and not changeable.
External database breaches
This isn’t exactly right. It requires that applications store the credentials in a form that they can be converted back to plain text. Applications absolutely should store these in an encrypted form.
This isn’t unique to Application Passwords, however. The same is true of OAuth Access Tokens. If they were to get breached, they would also be able to be used as fully fledged credentials. OAuth supports confidential clients that could also mandate an app secret, but that can’t be supported for all clients since not all clients can maintain secrets ( web or mobile apps ).
And of course, since the app secret has to be in a place that is accessible to the application, it isn’t unlikely that the access tokens and client secret are both leaked in the same breach.
Credentials as GET parameters
This is how the OAuth 2 implicit flow works. It is no longer considered the best solution by the OAuth Group, but it isn’t in itself insecure. A future expansion of App Passwords could support an Authorization Code type flow, but we would most likely still need to support an implicit style flow. Of note, the OAuth plugins that have been explored in wp-api have supported the implicit flow.
Open redirect with success_url/reject_url
It is somewhat of an open redirect. But this isn’t something solvable due to the requirements outlined above. An OAuth Dynamic Client Registration would be subject to the same attacks.
Additionally, we display the
URL
URL
A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org
the user will be redirected to. That will hopefully alleviate some issues.
Lastly, the current plan is to require
SSL
SSL
Secure Sockets Layer. Provides a secure means of sending data over the internet. Used for authenticated and private actions.
by default on both ends of the connection. Modifying the
success_url
would require intercepting an
HTTPS
HTTPS
HTTPS 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.
connection. OAuth 2 relies on HTTPS for security.
The OAuth specifications cover several attack vectors and how the protocol addresses them. I think it would be useful to at least consider these various vectors and categorically decide whether or not they should be addressed in a solution for
core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
They have been considered, but we should definitely document the decision points. Like I said, we have tried gaining momentum over the past year on a more comprehensive OAuth solution, but have been unable to get volunteers. It is also a substantially more complex protocol which reduces the likelihood of core adoption.
Thanks for the background,
timothyblynjacobs
! I’ve implemented Dynamic Client Registration for a project, so I’m familiar with that and agree it is a more user-friendly solution that helps address some of the concerns about the flow.
This isn’t exactly right. It requires that applications store the credentials in a form that they can be converted back to plain text. Applications absolutely should store these in an encrypted form.
In order for an application to pass the credentials back to the authentication server, they must be able to be converted back to plaintext. Encrypted text can be unencrypted. And if it isn’t unlikely that the app secret and tokens would be breached together, does the same not also go for an encryption key and credentials?
I do agree that this is a problem with any long-lived access token/password, though. JWTs with an expiration and some sort of refresh mechanism would provide some benefit, but also add to the complexity.
This is how the OAuth 2 implicit flow works. It is no longer considered the best solution by the OAuth Group, but it isn’t in itself insecure.
I’m not super familiar with all the various flows, but it does concern me that Application Passwords could redirect to a typical web app with the credentials in the
URL
URL
A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org
and expose them to browser history/plugins and access logs. Is that not insecure?
It is somewhat of an open redirect. But this isn’t something solvable due to the requirements outlined above. An OAuth Dynamic Client Registration would be subject to the same attacks.
OAuth does call for more stringent validation of the redirect URI, but ultimately it does fall on the user to inspect the redirect to some extent.
Although if an
admin
admin
(and super admin)
were required to approve the client registration, they could perform the validation. I understand that’s probably beyond what y’all are looking to implement, but I think it’s important to clarify that the site admin (authenticating server) and users providing authorization aren’t always one and the same.
Lastly, the current plan is to require
SSL
SSL
Secure Sockets Layer. Provides a secure means of sending data over the internet. Used for authenticated and private actions.
by default on both ends of the connection.
This is good to hear.
Like I said, we have tried gaining momentum over the past year on a more comprehensive OAuth solution, but have been unable to get volunteers. It is also a substantially more complex protocol which reduces the likelihood of
core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
adoption.
I understand and do wish I had the ability to contribute. By the same token, I think the lack of direction from decision makers and likelihood that core won’t adopt a given solution prevents many volunteers and companies from contributing or investing resources.
And if it isn’t unlikely that the app secret and tokens would be breached together, does the same not also go for an encryption key and credentials?
Yep! But my point was that the two solutions have essentially the same issues. Not that App Passwords is
more
secure than an OAuth token. I think also few OAuth implementations require anything beyond just the access token to access protected resources.
I do agree that this is a problem with any long-lived access token/password, though. JWTs with an expiration and some sort of refresh mechanism would provide some benefit, but also add to the complexity.
If I remember our conversations with
rmccue
correctly, few popular OAuth implementations implement token lifetimes that are short enough to make a substantial improvement in security. Our plan out of WC US was to
punt
punt
Contributors sometimes use the verb "punt" when talking about a ticket. This means it is being pushed out to a future release. This typically occurs for lower priority tickets near the end of the release cycle that don't "make the cut." In this is colloquial usage of the word, it means to delay or equivocate. (It also describes a play in American football where a team essentially passes up on an opportunity, hoping to put themselves in a better position later to try again.)
refresh token support to a future release.
I’m not super familiar with all the various flows, but it does concern me that Application Passwords could redirect to a typical web app with the credentials in the
URL
URL
A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org
and expose them to browser history/plugins and access logs. Is that not insecure?
I think insecure is a bit too binary, but like I said it isn’t the most ideal form. Application Passwords is available over the
REST API
REST API
The 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”)
, so if a client wanted to, they could generate a new application password and delete the old one. We could potentially add a dedicated REST API endpoint to implement a formal “exchange” mechanism.
OAuth does call for more stringent validation of the redirect URI, but ultimately it does fall on the user to inspect the redirect to some extent.
As I understand it, most of that validation is with regards to validating that the provided
redirect_uri
matches the registered one. But requiring a separate registration step would violate our requirements.
Although if an
admin
admin
(and super admin)
were required to approve the client registration, they could perform the validation.
The function checking that the redirect URLs are valid will be filterable. So if it was desired, a
plugin
Plugin
A 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
or can be cost-based plugin from a third-party.
could compare those URLs to an approved list of hostnames.
plugin
Plugin
A 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
or can be cost-based plugin from a third-party.
could compare those URLs to an approved list of hostnames.
Why was this / pre-registration of apps outside of
Core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
’s scope?
Preregistration violates the first requirement I mentioned in my
comment
. It makes the signup flow too complicated.
I meant to ask about that comment. 🙂 I understand that it violates the requirement / is complicated, what I’m trying to understand is what makes it complicated? :coffee:
It’s adding another step in the user flow where instead of the user clicking authorize, they have to go to a separate screen in their WordPress install and copy values over from the application into their WordPress site one by one and only then can they actually go to a connection screen.
Let’s do it! Implementing this would remove so many headaches for us mobile developers <3
I don’t have a strong opinion about
core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
inclusion at the moment, this comment is to note that a lot of care needs to be taken to ensure that existing installs (including plugins that bundle the Application Passwords
plugin
Plugin
A 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
or can be cost-based plugin from a third-party.
) would transition seamlessly upon core upgrade, possibly including from an older version of the plugin.
That’s one of the first things that
timothyblynjacobs
and I were discussing earlier this week.
We’re re-using the same data structure (storing an array of application passwords entries serialized in a usermeta key, similar to how
core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
stores user sessions) as the
plugin
Plugin
A 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
or can be cost-based plugin from a third-party.
had previously done — so data
migration
Migration
Moving the code, database and media files for a website site from one server to another. Most typically done when changing hosting companies.
should be completely smooth.
There shouldn’t be any namespace conflicts, as everything previously had been under an `Application_Passwords` class — that’s since been renamed to `WP_Application_Passwords` and the bulk of it spread out to more relevant areas of the codebase — so some of it is now in functions instead of methods.
We’re also talking about adding in a minor redirect for existing apps that link to `admin.php?page=auth_app` to `application-authorization.php` maintaining the submitted parameters for redirect urls and the like, and adding code to not only deactivate the Application Passwords plugin on upgrade, but check for `class_exists()` checks and if so, unhook the places where it’s attached itself.
(apologies if any of this comes across as answering a friendly reminder with a full unabridged essay, it’s also me gathering disparate thoughts into one place to ensure that I’ve not lost track of any concerns along the way)
> storing an array of application passwords entries serialized in a usermeta key
Serialized arrays tend to be pretty fragile so it may be worth reconsidering how the data is stored as we work towards
core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
integration.
Yeah this is a possibility for improvement. When
georgestephanis
and I were discussing it, we did look at the session tokens implementation which by default stores session tokens in a single serializes user
meta
Meta
Meta 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.
key.
The session tokens implementation does allow for alternate persistence methods. But we weren’t sure if Application Passwords necessitated the complexity that would require.
Did you have a different persistence method in mind
batmoo
💯 I maintain a
plugin
Plugin
A 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
or can be cost-based plugin from a third-party.
that has a fork of a very early form of the Application Passwords plugin which I can test against to ensure compatibility.
I’m absolutely in favor of this! It’s about time we extend the REST-
API
API
An 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.
so that it can be used by third-party systems with ease.
This would be very valuable, especially the ease of revoking credentials, making it much clearer and an easier flow.
carike
thanks for highlighting it in other channels.
I’m absolutely in favor of this. Is it perfect? No, but it’s a big improvement both in usability of the
REST API
REST API
The 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”)
and
in the overall security of doing so.
Major +1 on this. It will be a welcomed improvement.
I know that we pondered a lot of this many years ago (
), so I chatted through some of the remaining thoughts with Matt. He brought up a good reminder that we should be sure to think about how we can support permissions in the future, too. Things like permission-based tokens or restrictions by role?
Yup! I’ve already been discussing precisely this topic with
timothyblynjacobs
over DM’s (oops — we’ve since moved all discussion to the public `#
core
Core
Core is the set of software required to run WordPress. The Core Development Team builds WordPress.
-passwords` channel) on the same day this post went up.
We think it’s definitely a good idea for a v2 — and something that the application-passwords
feature plugin
Feature Plugin
A plugin that was created with the intention of eventually being proposed for inclusion in WordPress Core. See
Features as Plugins
could shift to integrating for a future iteration once the base functionality is in core. However, there’s a number of ways that we could scope things, and
plugin
Plugin
A 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
or can be cost-based plugin from a third-party.
-land is likely the best way to sort out the best way to add as a later
enhancement
enhancement
Enhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature.
to Core.
Among the things we were considering were — as you’d mentioned — role-ing down the authentication, so that an `administrator` could generate an application password that only had `author`
capabilities
capability
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).
(for example) — we were also considering a way of restricting what endpoints could be queried — for example, while an content editing app may have need for the ability to do anything and everything with posts, it may make sense to ensure that they can’t query any theme or plugin or potentially user management endpoints.
This could potentially be accomplished via restricting which
rest api
REST API
The 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”)
url paths could be queried — for example, granting `wp/v2/posts/*` but not `wp/v2/plugins` — this could get tricky when plugins start adding in custom namespaces that we can’t account for though.
We also want to be careful that any scoping isn’t exclusive to the REST API. If Core in a couple years choses to integrate a GraphQL api or something else, it would be nice if those scopes would cross-apply regardless of which type of api is being queried.
However, this is a much more complex issue and is ideally left to a future revision (in our consensus). That being said, it would do well if we could ensure with this merge that any relevant filters and actions are in place to make the authorization flow we have capable of being supplemented by additional parameters such as scoping data — and my goal would be to have a rough proof of concept plugin released within a couple weeks after merge, to ensure that we have established an approved api to build against.
tl;dr: Yup! Makes absolute sense for future development of this feature, and we’re on it!
💯 Yep I think this is a great room for future improvement. And another big benefit to App Passwords is that we’d be able to support this in the future, but would be difficult with plain basic auth.
I personally thing scoping by roles/
capabilities
capability
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).
will be the right way to go about it.
I think this would also be something that is possible to prototype in a
plugin
Plugin
A 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
or can be cost-based plugin from a third-party.
by using filters. ( We need to add a couple of
JS
JS
JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors.
hooks
Hooks
In WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same.
).
Excellent, both for conscientiously moving conversations into a public place and for thinking through this with the future in mind. 🙂
Let’s move forward with this proposal as a v1, knowing there is a v2 already in discussion.
Thanks for the great work, everyone!
I have a
UX
UX
User experience
request for this, just wanted to note here before moving it into GH or what have you – when you’re sent to the site to retrieve the app passwords from, being asked to log in can be a little confusing if you’re coming from another WP site, since the login screen is very generic by default and gives very little indicator as to the site in question. I think a reasonable solution to this might be to show a notice on the login screen stating something like “Please log in to {sitename} to complete authentication.” I think this helps both disambiguate which WordPress you’re on and also remind you what you were doing when you got kicked to that screen in the first place.
👍 That makes sense to me. Right now I think the redirect to `wp-login.php` is just a consequence of
auth_redirect()
. Maybe we could look at the `redirect_to` to determine when to show the message?
We have a
Github
GitHub
GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged by the repository owner.
issue
tracking
UI
UI
User interface
refinements to the flow it could be added to.
Worth noting that this has been addressed now.
I think we’re all set here, having
georgestephanis
and
timothyblynjacobs
assemble a props list (.org usernames) and then
timothyblynjacobs
will handle the big commit.
I have created a step by step article of using the application passwords instead of actual user password. See
using application passwords
Comments are closed.
Site resources
Email Updates
Enter your email address to subscribe to this blog and receive notifications of new posts by email.
Join 6,695 other subscribers
Recent Updates
Recent Comments
No Replies
Current Release
The current release in progress is
WordPress 7.0
. Planned future releases are listed on
the Project Roadmap
. Feature projects not tied to specific releases can be found on
the Features page.
Regular Chats
Note:
All chats happen on
Slack
Weekly Developer Meetings
: [time relative]Wednesday 15:00 UTC[/time] in
#core
About the Dev Chat
Agendas
Summaries
Performance Weekly Chat
[time relative]Tuesday 15:00 UTC[/time] in
#core-performance
New Contributors Chat
The 2nd and 4th Wednesday of every month at 17:00 UTC in
#core
See all meetings →
Recent Posts and Comments
Team Pledges
2664 people
have pledged time to contribute to Core Team efforts! When looking for help on a project or program, try starting by reaching out to them!
compose new post
reply
edit
go to top
go to the next post or comment
go to the previous post or comment
toggle comment visibility
esc
cancel edit post or comment
Loading Comments...
You must be
logged in
to post a comment.
US