WP Manifestindependent plugin directory
manifest / admin / orbit

Orbit WP Registry grade D. High-severity findings · 5 findingsWP RegistryHigh-severity findings · 5 findingsOpen the reportD

Opinionated overrides for default WordPress behaviour.

★ 3stars
v2.7.1latest · 16d ago

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/eighteen73/orbit/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Orbit moulds WordPress default behaviour to simplify the CMS experience, protect users from changing settings that should be reserved for website developers, and reinforce areas of the CMS that tend to be fragile or noisy.

The plugin is unapologetically opinionated to fit the needs and preferences of our web agency.

For complete documentation, visit docs.eighteen73.co.uk/wordpress/plugins/orbit.

Installation

Assuming you are using a modern Composer workflow for WordPress development (such as our Nebula WordPress stack), install Orbit as a Must-Use plugin using:

composer require eighteen73/orbit

For manual installation or non-Composer environments, see the Installation Guide.

Features Overview

  • Synced Theme Patterns: Keeps block theme pattern files in version control while syncing them to real database patterns with block overrides.
  • Branded Emails: Wraps system emails and Gravity Forms notifications in responsive HTML with WooCommerce styling parity.
  • UI Cleanup: Simplifies admin menus, toolbar nodes, and dashboard widgets, with custom login logo and environment indicator badge support.
  • Security Hardening: Blocks REST API user enumeration, disables XML-RPC, strips head tags, and enforces baseline HTTP security headers.
  • Capabilities & Access: Granular permission management for Editors and Shop Managers across Site Editor, User management, Gravity Forms, and Privacy options.
  • Performance & Utilities: Fast 404 responses for missing static assets, remote media hotlinking from production, health check endpoint (/wp-json/orbit/up), and search engine index suppression on non-production.
  • Integrations: Performance and safety tweaks for WooCommerce, Action Scheduler, and Altcha CAPTCHA.

For a complete reference of filter hooks and constants, see the Filters & Hooks Reference.

Vendored Dependencies

Orbit ships a small number of vendored third-party libraries under includes/lib/, namespaced via Mozart into Eighteen73\Orbit\Dependencies\… to avoid collisions.

To refresh these dependencies after pulling updates:

composer install
composer update <vendor>/<package>
vendor/bin/mozart compose
composer dump-autoload

For security advisory notes, refer to the Installation Documentation.

Releases

Newest 25 of 29 recorded releases.

Tag
Published
v2.7.1 latest
Oct 6, 2026 16d ago
Jul 29, 2026 2mo ago
Jul 21, 2026 3mo ago
Jul 7, 2026 3mo ago
Jan 7, 2026 9mo ago
Jan 6, 2026 9mo ago
Jan 6, 2026 9mo ago
Dec 23, 2025 10mo ago
Dec 23, 2025 10mo ago
Dec 16, 2025 10mo ago
Dec 9, 2025 10mo ago
Nov 20, 2025 11mo ago
Nov 17, 2025 11mo ago
Oct 31, 2025 11mo ago
Oct 30, 2025 11mo ago
Oct 30, 2025 11mo ago
Sep 25, 2025 1 year ago
Aug 13, 2025 1 year ago
Aug 13, 2025 1 year ago
Aug 11, 2025 1 year ago
May 21, 2025 1 year ago
Apr 24, 2025 1 year ago
Jun 4, 2024 2 years ago
Mar 18, 2024 2 years ago
Mar 13, 2024 2 years ago
All releases on GitHub →

These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.

D grade

Security

Orbit 2.7.1 · audited by WP Registry

High-severity findings.

2 high 3 low
Audited release
2.7.1
Findings
5
Worst severity
high
Content hash
321d636cbd932f448c195a5a…

Findings

  • high Editors and shop managers can take over administrator accounts

    missing_capability

    By default orbit_enable_user_caps_access is true, and admin_init persists list_users, create_users, and edit_users onto the editor and shop_manager roles (delete_users is removed, promote_users is not added). On a single site WordPress maps edit_user for any other account, including an administrator, to the edit_users primitive only, and user-edit.php will save a new password and email. create_app_password also maps to edit_user, so the same role can mint an application password for an administrator. On multisite, edit of other users stays do_not_allow without manage_network_users, but allow_create_users_on_multisite forces create_users back to the primitive cap. user-new.php?action=createuser then accepts role from the request after wp_ensure_editable_role(), and get_editable_roles() is every role unless something else filters it, so an editor can sign up a new user as administrator and activate it from their own inbox. A subscriber or customer does not gain these caps; any visit to wp-admin re-applies them to the editor and shop_manager roles if an administrator had removed them. The consumer is WordPress user administration, which changes login credentials and role membership for the whole site.

    includes/classes/Capabilities/Users.php:33-107

    Recommendation

    Stop granting edit_users and the multisite create_users bypass by default. If editors must create users, map_meta_cap must refuse edit_user and promote_user when the target has manage_options or a role the actor cannot assign, and filter editable_roles so administrator is not assignable. Do not return the create_users primitive on multisite unless that same role check runs before wpmu_signup_user().

  • high Forged Host header bypasses non-live payment safeguards

    insecure_config

    is_nonlive_site() decides whether WooCommerce webhooks may send and whether WooCommerce Subscriptions is forced into duplicate-site mode. After optional environment-variable overrides, it classifies the request from $_SERVER['HTTP_HOST'] (localhost, .test, .local, .localhost, .dev, beta.*, staging.*, *.kinsta.cloud). If the host does not match and wp_get_environment_type() is production, which is WordPress's default when WP_ENVIRONMENT_TYPE is unset, the request is treated as live unless ORBIT_PRIMARY_DOMAIN is set and differs. An unauthenticated client whose vhost accepts the Host header can therefore send Host: localhost to a production site and, for that request, make woocommerce_webhook_should_deliver return false and woocommerce_subscriptions_is_duplicate_site return true, which drops inline webhook delivery and blocks subscription billing that runs in the request (including a direct wp-cron.php hit). The inverse is the case the safeguard exists for: a staging copy still typed as production is non-live only because its hostname matches the heuristic; Host: example.com (or any name outside the suffix list) makes is_nonlive_site() false, so staging will deliver copied production webhooks and will not force duplicate-site mode. Reachability depends on the web server passing the attacker Host through to PHP, which is common when the staging site is the default vhost.

    includes/classes/Environment.php:34-104

    Recommendation

    Do not use the request Host header as a security boundary. Treat the site as non-live only from WP_ENVIRONMENT_TYPE, a server environment variable, or a constant compared to the configured siteurl host, and fail closed (safeguards on) when the environment type is missing on a host that is not the configured primary domain. Apply the WooCommerce filters from that trusted signal, not from HTTP_HOST.

  • low Branded emails inject WooCommerce font and footer color into CSS

    missing_escaping

    When WooCommerce is active, a shop_manager (manage_woocommerce, not manage_options) can save WooCommerce email settings. Orbit then wraps every non-HTML wp_mail, including password resets and new-user mail, in templates/branded-emails/email-template.php. font-family is printed raw from the woocommerce_email_font_family option. WooCommerce stores that field with wc_clean() only, not the EmailFont whitelist it uses in its own templates, so a value such as Helvetica; } a { background-image: url(https://attacker.example/) } survives and is emitted in the style block. woocommerce_email_footer_text_color is a color field that WooCommerce's OptionSanitizer does not hex-check; Orbit prints it with esc_attr(), which does not stop a CSS breakout. Hex-sanitized WC color options are safe. The consumer is the HTML email, so the effect is restyling and remote CSS image loads in those messages, not script execution in a browser page.

    templates/branded-emails/email-styles.php:21-24

    Recommendation

    Whitelist font-family against a fixed map the way WooCommerce's EmailFont class does, and pass every color through sanitize_hex_color() before output. Escape any remaining CSS value so quotes, braces, and parentheses cannot leave the declaration.

  • low Author archive block still leaks usernames via redirect_canonical

    information_disclosure

    HideAuthor is on by default and, on template_redirect, marks author queries as 404. redirect_canonical is registered on the same hook from wp-includes/default-filters.php, earlier than Orbit's init registration, so it runs first. For /?author=1, when that user has a published post, canonical.php redirects to /author/{user_nicename}/ and exits before author_page_404(). An unauthenticated visitor still learns the nicename from the Location header. The later 404 only affects a direct author-archive URL.

    includes/classes/Security/HideAuthor.php:41-51

    Recommendation

    Remove the author query var on request, or hook template_redirect earlier than redirect_canonical (priority below 10) and exit on numeric author requests before the canonical redirect. Also disable the author rewrite so /author/slug/ cannot be probed.

  • low Production sites are forced searchable

    insecure_config

    disallow() is hooked to pre_option_blog_public and always returns an integer. On a production environment it returns 1, which short-circuits get_option() and ignores the database value. An administrator who set Settings → Reading to discourage search engines still gets blog_public=1, so core robots output and sitemaps treat the site as public. Non-production returns 0, which is the intended noindex behaviour. This is not attacker-triggered; the plugin overrides the owner's privacy setting whenever environment() is production.

    includes/classes/DisallowIndexing/DisallowIndexing.php:44-50

    Recommendation

    Return false from the pre_option filter on production so the saved blog_public value is used. Return 0 only when the site is actually non-production.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.