WordPress.org

Make WordPress Core

Opened 3 months ago

Closed 3 months ago

#49110 closed enhancement (worksforme)

Add ability to lock/restrict public REST API access from WP Admin

Reported by: apedog Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: REST API Keywords: close
Focuses: administration, rest-api, privacy Cc:

Description

Following a lively discussion in #core-restapi slack channel:

Preface

REST API has been added to WordPress to allow it to be used as a fully fledged CMS. It is also used internally by the new Gutenberg blocks. And used by many plugins. And is considered immensely useful by many developers.
</platitudes>

REST API does however have some risks involved, that should be addressed in Core.
REST API is enabled by default on 100% of installations. Even those that don't need it - ie. front-facing HTML-only sites. This exposes a lot more data publicly then is exposed by regular template pages, and is a privacy concern.

  • User and author data can be accessed publicly even if not available through a front-end page.
  • Old installations that added private data (eg. phone numbers) as meta now have that meta publicly (and easily) exposed through REST queries.
  • Non-technical users of WordPress might not even know their data is exposed through REST.
  • Technically-savvy users might not have the resources to allocate to limiting public/non-authenticated access to the REST API.
  • There may be GDPR concerns involved.
  • WordPress basically ships in with an installed scraper for public use, that the admin has no control over.

Proposal

Add an option to WP Admin to disable/limit public REST API access.
An easily accessible enable/disable lock-down-public-access REST API option should be available to any WordPress administrator. Either in Settings-General, Settings-Privacy, Site Health, or through a dedicated Settings-REST page (will open a separate ticket for a REST control page)

  • Ideally, REST API should have been an opt-in on WordPress install or update, but that ship has sailed. It is also extensively used by new "Gutenberg" blocks. So a full disable is probably not the way to go.
  • An opt-in/opt-out lock-public-access-to-REST option should be available on fresh WordPress installs as well as on the Admin page. Front-facing HTML-only websites should have a one-click restrict public access option on install.
  • Plugins that use REST API should detect locked-down/public-access setting. So there are back-compat concerns here also.

Change History (13)

#1 @TimothyBlynJacobs
3 months ago

#48043 was marked as a duplicate.

#2 @knutsp
3 months ago

Non-technical users of WordPress might not even know that their:

  • published posts are accessible when not visible or linked to from the home page
  • published posts are accessible through XML (RSS/Atom) feed
  • published posts are accessible through XML-RPC API

What makes REST API so special, or should WordPress just warn that it is publishing platform?

As for meta data, I have had the impression they are not available in APIs unless explicitly made public through registering the keys as such?

All interfaces/formats/APIs, HTML, XML, JSON (RPC/REST) was introduced by decisions, not options.

#3 @TimothyBlynJacobs
3 months ago

User and author data can be accessed publicly even if not available through a front-end page.

This is true, but only authors of posts that are shown in the Rest API are included. Additionally, only their display name, URL, and bio are displayed.

Old installations that added private data (eg. phone numbers) as meta now have that meta publicly (and easily) exposed through REST queries.

This is incorrect. Metadata is never exposed publicly unless it is specifically exposed by the developer using register_meta() and explicitly setting show_in_rest to true.

Non-technical users of WordPress might not even know their data is exposed through REST.

No more data is exposed than you'd be able to see in a default WordPress theme or over RSS.

Technically-savvy users might not have the resources to allocate to limiting public/non-authenticated access to the REST API.

This can be done by installing one of a number of plugins: https://wordpress.org/plugins/search/disable+rest+api/ Many security plugins also include settings to limit REST API access.

There may be GDPR concerns involved.

Could you share an example of what these concerns would be? Only public data is exposed by default.

WordPress basically ships in with an installed scraper for public use, that the admin has no control over.

Only data that is also exposed in the theme and RSS.

See also: #39806, #38446

#4 @apedog
3 months ago

What makes REST API so special, or should WordPress just warn that it is publishing platform?

Not every WordPress installation is a CMS. Some are small front-facing HTML-only sites. Sites whose users/admins shouldn't be expected to deal with REST and its risks.
It's not about telling the user "Oh btw, we're also exposing the data through REST queries. Be careful. Study up. Maybe install a plugin".
A user should have the option to simply disable this from the Admin area. This should be a core default option.

All interfaces/formats/APIs, HTML, XML, JSON (RPC/REST) was introduced by decisions, not options.

I've heard this and don't really know what it means. A decision might be made as to the default options. That makes sense. But the ability to control those options should be given to the user. Basic control through the admin area. More granular control through code (the later, I believe, exists. The former does not).

@TimothyBlynJacobs
First of all thank you for all the technical notes. However I didn't open this ticket in order to fix/change REST on my installations. But as an option that I believe should exist by default. To be used by site admins without technical knowledge and without coding.

only authors of posts that are shown in the Rest API are included. Additionally, only their display name, URL, and bio are displayed.

That's still a lot. Consider a database created before the advent of REST in WordPress. It might have outdated information. Or information the user never expected to be released publicly. It does not appear on the front HTML pages (theme templates). The user has no expectation of the information being available publicly.

There may be GDPR concerns involved.

Could you share an example of what these concerns would be? Only public data is exposed by default.

Apologies. That should read as MAYBE (may, might). I don't know of any myself. I wrote that as a discussion opening-point. If there are none - then that point should be conceded.

Only data that is also exposed in the theme and RSS.

Theme template files do not expose as much data as REST queries. And are much more commonly tested - via the browser inspector and view-source (ctrl+u) then REST APIs are. Editing theme templates requires minimal/low-level technical knowledge (either of PHP or of WordPress core) and is very common. The same cannot be said of REST and RSS.

If some of these concerns also affect RSS - then that should be addressed too. I defer to those with better technical knowledge and suggest that's out of the scope of this ticket.

#5 @xkon
3 months ago

This is a really nice topic and thanks for bringing it up @apedog . I've also read the whole slack discussion but I'll add my thoughts here as slack is hard to keep discussions going as we're all on async mode :).

First, let me just say that I do agree with @TimothyBlynJacobs and @SergeyBiryukov mentions that it wouldn't make much of a difference to disable public access to REST just for "copying" reasons. That can be done in various ways, others are easier others are harder, but the "damage" can be done at the end of the day.

That being said I wouldn't go to the lengths of disabling all REST endpoints as some data are either way publicly available from the website's structure itself so it wouldn't make much of a difference, i.e. Posts/Pages :) .

But I am interested to hear thoughts regarding Users.

@TimothyBlynJacobs you mention:

Additionally, only their display name, URL, and bio are displayed.

On a default setup as far as I'm aware there's more than that on /users/ endpoint. We have ID, Name ( what is chosen for display), url, bio, slug (which should pretty much be the username in most occasions if not all) & Gravatar links.

So IMHO, pushing out usernames & pictures, etc by default might be acceptable, but there should be a way of at least having that disabled or automatically follow the rules of a theme and website setup ( that could be hard :D ).

As an example: a website might not be utilizing "authors" views via its theme and not mentioning anywhere how many or who the authors are. Since they have published a post or a page they are added on the REST endpoint, which goes "against" of what the site owner has tried to accomplish.

Yes anyone could add a plugin to alter REST and how it works, there are plenty out there, but not everyone is aware about REST and that their site might still have aspects publicly available that they are trying to "hide" by altering their themes and not using /author/ templates.

Do tell me if I'm missing the mark here though as I'm not aware if REST would actually hide anything of the above mentioned automatically etc :).

#6 @TimothyBlynJacobs
3 months ago

Not every WordPress installation is a CMS. Some are small front-facing HTML-only sites. Sites whose users/admins shouldn't be expected to deal with REST and its risks.

What are the risks? A small front-facing HTML only site is the site that would be least impacted by the REST API. Since it is only exposing data that would already be public.

Theme template files do not expose as much data as REST queries.

I think we have to be explicit here, what data is that? In a standard WordPress theme, I'm not sure what data is exposed that wouldn't already be exposed.

But the ability to control those options should be given to the user. Basic control through the admin area

The way this has been done is through the use of dedicated plugins. An argument has to made as to _why_ the REST API in its current state is such a privacy risk that it must be easily disabled from the admin without the user of any plugins.

On a default setup as far as I'm aware there's more than that on /users/ endpoint. We have ID, Name ( what is chosen for display), url, bio, slug (which should pretty much be the username in most occasions if not all) & Gravatar links.

I think those are the same? Sorry what am I missing. The author ID and slug are already exposed publicly.

As an example: a website might not be utilizing "authors" views via its theme and not mentioning anywhere how many or who the authors are.

We don't have an option in core to disable author archives. Even if the theme doesn't have custom author archive templates, you can still see the default templates, no?

So if a theme is intentionally completing disabling author archives and templates, I'd expect them to disable it in the REST API as well. Are WordPress.org themes allowed to disable those templates?

#7 @apedog
3 months ago

What are the risks? A small front-facing HTML only site is the site that would be least impacted by the REST API. Since it is only exposing data that would already be public.

  • A small front-facing HTML only site can hide ALL information that is database-related. ID's, slugs, post_type, author etc. It can even hide the fact that it is a WordPress installation.
  • This can be done by low-level devs (with only basic knowledge of PHP and HTML) editing the theme templates and using only the browser inspector and view-source for review.

We don't have an option in core to disable author archives. Even if the theme doesn't have custom author archive templates, you can still see the default templates, no?

  • A theme can easily disable author archives. Just add an authors.php file that doesn't print the info (or one that HTML redirects http-equiv).
  • Rewrite rules can be superseded (requires some knowledge of WordPress).

The author ID and slug are already exposed publicly.

  • References to author ID and slug can be removed from all theme templates.
  • Rewrite rules can be superseded (requires some knowledge of WordPress).

So if a theme is intentionally completing disabling author archives and templates, I'd expect them to disable it in the REST API as well.

  • This would require an understanding/knowledge of REST that might not exist. We cannot assume.
  • A lot can be achieved just by hacking at the WordPress template hierarchy with no knowledge of WordPress or of writing plugins.

#8 @TimothyBlynJacobs
3 months ago

A lot can be achieved just by hacking at the WordPress template hierarchy with no knowledge of WordPress or of writing plugins.

You have to know that these templates exist, the exact same way you would know about REST. It is another technical detail. If you are going to such extreme lengths to remove this information, also doing it manually for the REST API does not seem like a step too far at all.

#9 follow-up: @apedog
3 months ago

You have to know that these templates exist, the exact same way you would know about REST.

I emphatically disagree.
Installing WordPress and hacking away at the default theme is a common (and encouraged) use-case.
It requires only basic knowledge of HTML and PHP and a willingness to read about the templates and WP in general. A very low technical barrier.
Knowing REST, or even knowing of REST, is not a requirement. Nor should it be.

  • WP Admin area must (IMO) afford to its user as much control of the REST API as it affords to robots.txt and the RSS feed.
  • WP Admin area must (IMO) afford to its user as information about REST API as it gives about RSS.

#10 in reply to: ↑ 9 @knutsp
3 months ago

The ambition to not let any very low end "developer/hacker" get any surprises about how content of an advanced publishing system for the internet gets acessible is very odd, IMO. Like an ostrich that buries it's head in the sand is not invisible.

When first digging into WordPress, many years ago, I remember I was a bit surprised RSS feeds was also available for any archive, just by adding /feed to the URL. Should I have expected it not to, based on the fact that I had edited the template? I even deleted such template, but still the index.php took over. I understood one ting quit early: Must learn more, or else I don't know what I am really doing, so far.

Replying to apedog:

  • WP Admin area must (IMO) afford to its user as much control of the REST API as it affords to robots.txt and the RSS feed.

robots.txt is not enforcing restrictions.
The options for feeds is just for convenience. To disable it you need a plugin.

  • WP Admin area must (IMO) afford to its user as information about REST API as it gives about RSS.

That's very little, and I don't think it belongs in the admin area for end users. To be educated in how WordPress works you must consult documentation.

An overview of how content may be accessed through different interfaces and formats will be a good thing, if not already there. This may be linked to from admin.

The goal of the REST API is to provide access not only public content, but for editing and administration.

Properly and completely restricting access is a thing for dedicated plugins, like membership, written be people who actually know what they are doing. Trying to make it correct that assuming what you can't see in browser by visiting exposed links of your site on not a way to go.

#11 @apedog
3 months ago

When first digging into WordPress, many years ago, I remember I was a bit surprised RSS feeds was also available for any archive, just by adding /feed to the URL. Should I have expected it not to, based on the fact that I had edited the template?

Good point. The Admin area links to ample documentation regarding RSS - had you wanted those questions answered.
The same should be afforded to REST API. Preferably from a similar settings page, if not from the exact same page.

I even deleted such template, but still the index.php took over. I understood one ting quit early: Must learn more, or else I don't know what I am really doing, so far.

I absolutely relate to this attitude. I completely agree with your point.
That is the impetus behind this ticket. To facilitate exactly that kind of understanding and access. As it stands, REST is hidden from an admin user. It exists as external-only documentation, and is thus implicitly only targeted at developers interested in using it. Not at site admins.

An overview of how content may be accessed through different interfaces and formats will be a good thing, if not already there. This may be linked to from admin.

That is a must (IMO)
Some measure of control would also be a positive addition. In much the same way the WP Admin area allows minimal control of permalinks and rewrite rules.

#12 @jorbin
3 months ago

  • Keywords close added

Plugins should be able to use the REST api on the front end and an option to disable it is essentially an option to allow users to break their site. This topic has been discussed in #39806, #38446 amongst other places. As @joehoyle wrote one of the previous times this was discussed:

The more WP functionality core functionality we see moving to be build on the REST API, the more it will become not possible to disable it. The REST API is not just an external facing layer on WordPress, it is core functionality.

As per usual, if you don't want your site to be publicly accessible, there are plugins and other means of doing that - but it's not a default / feature of WordPress core to enable such a thing.

User facing options also are not free, as was noted by Havoc Pennington in 2002 in an article that has had a lasting impact on the philosophies of WordPress:

It turns out that preferences have a cost. Of course, some preferences also have important benefits - and can be crucial interface features. But each one has a price, and you have to carefully consider its value. Many users and developers don't understand this, and end up with a lot of cost and little value for their preferences dollar.

Too many preferences means you can't find any of them.
Preferences really substantively damage QA and testing.
Preferences make integration and good UI difficult.
The point of a good program is to do something specific and do it well.
Preferences keep people from fixing real bugs.
Preferences can confuse many users.

I find that if you're hard-core disciplined about having good defaults that Just Work instead of lazily adding preferences, that naturally leads the overall UI in the right direction. Issues come up via bugzilla or mailing lists or user testing, and you fix them in some way other than adding a preference, and this means you have to think about the right UI and the right way to fix problems. Basically, using preferences as a band-aid is the root of much UI evil.

I don't see any new arguments that makes me believe this ticket shouldn't be closed as a duplicate of #39806

#13 @azaozz
3 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to worksforme
  • Status changed from new to closed

Completely agree with @TimothyBlynJacobs, @xkon, and @jorbin that an user facing option to "lock/restrict the public REST API" is not a good idea. As pointed out above it will not only allow users to "break their sites". It also "pushes" the users into having to make a decision about concepts and features that most people are not aware of. Leaving such choices in the hands of the web developers, like theme/plugin authors, is the proper solution.

If there are cases of private or restricted data available through the REST API for non logged-in users, they should be treated as bugs and fixed in specific tickets for each specific case. Similarly, if a theme or a plugin restricts what data is accessible for non logged-in users, the theme/plugin should also ensure that access to that data is restricted through RSS and REST.

@apedog I understand your concerns but a user facing option in wp-admin doesn't seem to be the best solution :) REST is just another way to access a WordPress powered site, similarly to many other web sites that are not powered by WordPress. If a website owner or a website "builder/developer" wants to restrict some of the public data available by default to non logged-in users, best would be to install a "proper" plugin, or develop one if their needs are not met by any existing plugin.

Closing this as "worksforme" since it is the intended behaviour. Please open specific tickets if there are cases where (private or restricted) data is not available by default through the "front-end", but is available through the REST API for non logged-in users.

Note: See TracTickets for help on using tickets.