Repository navigation
bcc-login: close visibility leaks (REST, oEmbed, feeds, endpoints, SearchWP) and restore Phrase access - #227
Merged
Merged
Conversation
Phrase stopped getting restricted posts in 1.2.8: the new the_posts backstop re-checked queries the visibility filter exempts. It now only re-checks queries the filter set up, and bcc-login's internal query vars are ignored when they come in with a query's own arguments. Restricted posts could also be read without logging in: - REST API: single posts from the posts controllers, oEmbed data and Yoast SEO's get_head route now follow the rules of the post's page. On sites whose default visibility isn't public, REST lists and search leave out post types without visibility support for visitors below the default. The old REST response check, which never matched these routes, is removed. - Embeds of the site's own posts in content are decided per visitor when output, as the cached embed is shared by everyone. - Feeds: ?post_types= is sanitised and limited to viewable post types, and translatedFrom only points to a published original with the same audience. - bcc-login's endpoints are served at template_redirect, so they can't be combined with a feed; only the known endpoints skip the login check, and HEAD requests don't run them. - SearchWP gets the rules as a plain post ID condition rather than a meta query, which skewed its ranking and slowed searches down; this covers its native search (also on CPT archives), live search, REST API and shortcodes. On sites whose default visibility isn't public, archives, search and core feeds are served when they were filtered for the visitor; single views and anything unfiltered fall back to the site default as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The feed key still bypasses visibility checks on non-feed restricted URLs.
1 open finding
What changed in this PR
Hardens BCC Login content visibility across REST, feeds, endpoints, oEmbed, Yoast, and SearchWP while restoring Phrase access.
Changes:
- Adds visibility enforcement across REST and search integrations.
- Secures feed post types, translations, and endpoint dispatch.
- Refines query filtering and exemptions.
| File | Description |
|---|---|
class-bcc-login-visibility.php |
Expands visibility enforcement and query handling. |
class-bcc-login-feed.php |
Restricts feed types and translation metadata. |
class-bcc-login-endpoints.php |
Serves allowlisted endpoints before content rendering. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The key in ?id= skipped the login check on any URL, so it also opened restricted pages. has_feed_key() now requires a feed request as well, which covers the page check and the feed, embed and SearchWP exemptions alike. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The visibility filters use SearchWP's index and source separator when SearchWP is active. PHPStan doesn't load SearchWP, so it reported them as unknown; they're declared in dependencies.stub like other external symbols. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Restores Phrase's access to restricted posts, which stopped in 1.2.8, and closes several ways restricted posts could be read without logging in: the REST API, oEmbed, Yoast SEO's head route, feeds, bcc-login's endpoints and SearchWP. The changes are in bcc-login's visibility, feed and endpoints classes; no settings or database changes.
Changes
Query filters
the_postsbackstop from 1.2.8 only re-checks queries the visibility filter set up, so the queries it exempts (Phrase, editors, feeds read with the key) stay exempt.pre_get_postscallback switches to a supported post type are checked again.SearchWP
REST API
rest_forbidden(401/403). Editors are exempt, so the block editor is unaffected./wp/v2/searchleave out post types without visibility support for visitors below the default./oembed/1.0/embedfollows the same rules. Embeds of the site's own posts in content are decided per visitor when output, because the cached embed is shared by everyone./yoast/v1/get_headno longer returns the head (title, description) of a post the visitor may not view.rest_pre_echo_responsefilter is removed. Its single-post check never matched these routes, and its search post-filter is replaced by filtering in the query (it also turned error responses into PHP fatals).Feeds and endpoints
?post_types=is sanitised and limited to viewable post types (reusable blocks and contact forms excluded).translatedFromonly points to a published original with the same audience.template_redirect, so they can't be combined with a feed. Only the known endpoints skip the login check, and HEAD requests don't run them.Sites whose default visibility isn't public
Worth knowing
/wp/v2/search; the removed post-filter dropped some.Testing
On local copies of two sites, comparing the released plugin with this branch. One is public by default with site groups (WPML, SearchWP, Yoast); the other is logged-in by default (WPML, Flatsome, Contextual Related Posts, Yoast).
Not covered
wp_oembed_get()callers, such as ACF oEmbed fields.🤖 Generated with Claude Code