{"id":395985,"date":"2026-11-09T19:40:31","date_gmt":"2026-11-09T19:40:31","guid":{"rendered":"https:\/\/de.wordpress.org\/plugins\/wirecore-rest-control\/"},"modified":"2026-11-09T19:40:19","modified_gmt":"2026-11-09T19:40:19","slug":"wirecore-rest-control","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/wirecore-rest-control\/","author":23504840,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.1.4","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"WireCore REST Control","header_author":"WireCore GmbH","header_description":"Disables the WordPress REST API selectively \u2013 globally, per namespace or per route, including routes of other plugins.","assets_banners_color":"111418","last_updated":"2026-11-09 19:40:19","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/wirecore.net","rating":0,"author_block_rating":0,"active_installs":0,"downloads":49,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"wirecore","date":"2026-11-09 19:40:19","revision":3793158}},"upgrade_notice":{"1.0.0":"<p>Initial release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3793158,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3793158,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3793158,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3793158,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3793158,"resolution":"1","location":"assets","locale":"","width":1440,"height":1000},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3793158,"resolution":"2","location":"assets","locale":"","width":1440,"height":1000},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3793158,"resolution":"3","location":"assets","locale":"","width":1440,"height":1000},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3793158,"resolution":"4","location":"assets","locale":"","width":1440,"height":1000},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3793158,"resolution":"5","location":"assets","locale":"","width":1440,"height":900}},"screenshots":{"1":"Every registered route, grouped by namespace, with the plugin or theme that registered it.","2":"Rules per namespace and route for reading and writing, with exceptions and the effective rule.","3":"The \"Advanced\" dialog: allow and deny IP addresses, roles and users per namespace or route.","4":"Settings: automatic allowances for front-end plugins, error response, hardening and log.","5":"Log of blocked requests with shortened IP addresses."}},"plugin_section":[],"plugin_tags":[125786,32184,396,23853,600],"plugin_category":[54],"plugin_contributors":[289089],"plugin_business_model":[],"class_list":["post-395985","plugin","type-plugin","status-publish","hentry","plugin_tags-disable-rest-api","plugin_tags-json-api","plugin_tags-privacy","plugin_tags-rest-api","plugin_tags-security","plugin_category-security-and-spam-protection","plugin_contributors-wirecore","plugin_committers-wirecore"],"banners":{"banner":"https:\/\/ps.w.org\/wirecore-rest-control\/assets\/banner-772x250.png?rev=3793158","banner_2x":"https:\/\/ps.w.org\/wirecore-rest-control\/assets\/banner-1544x500.png?rev=3793158","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/wirecore-rest-control\/assets\/icon-128x128.png?rev=3793158","icon_2x":"https:\/\/ps.w.org\/wirecore-rest-control\/assets\/icon-256x256.png?rev=3793158","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/wirecore-rest-control\/assets\/screenshot-1.png?rev=3793158","caption":"Every registered route, grouped by namespace, with the plugin or theme that registered it."},{"src":"https:\/\/ps.w.org\/wirecore-rest-control\/assets\/screenshot-2.png?rev=3793158","caption":"Rules per namespace and route for reading and writing, with exceptions and the effective rule."},{"src":"https:\/\/ps.w.org\/wirecore-rest-control\/assets\/screenshot-3.png?rev=3793158","caption":"The \"Advanced\" dialog: allow and deny IP addresses, roles and users per namespace or route."},{"src":"https:\/\/ps.w.org\/wirecore-rest-control\/assets\/screenshot-4.png?rev=3793158","caption":"Settings: automatic allowances for front-end plugins, error response, hardening and log."},{"src":"https:\/\/ps.w.org\/wirecore-rest-control\/assets\/screenshot-5.png?rev=3793158","caption":"Log of blocked requests with shortened IP addresses."}],"raw_content":"<!--section=description-->\n<p>WireCore REST Control restricts access to the WordPress REST API without breaking the block editor or the plugins your visitors rely on. Instead of an all-or-nothing switch, you decide per namespace and per route who may read and who may write.<\/p>\n\n<p>The route list shows <strong>every registered route<\/strong> \u2013 WordPress core, themes and all other plugins \u2013 and tells you which plugin or theme registered it.<\/p>\n\n<h4>Rules<\/h4>\n\n<ul>\n<li>A default rule plus overrides per namespace and per route. The most specific rule wins: route, then namespace, then automatic allowance, then default.<\/li>\n<li>Separate rules for reading (GET\/HEAD) and writing (POST\/PUT\/PATCH\/DELETE).<\/li>\n<li>Rule levels: Public, Logged-in only (optionally limited to selected roles), Admins only, Blocked, Inherit.<\/li>\n<li>Out of the box, logged-out visitors are blocked \u2013 except for the namespaces of known front-end plugins (see below).<\/li>\n<li>Quick actions: block everything for guests, block everything, restrict the user list (<code>\/wp\/v2\/users<\/code>) to admins, reset custom rules.<\/li>\n<li>Search and filter the route list by text, source plugin\/theme and status.<\/li>\n<\/ul>\n\n<h4>Advanced exceptions per namespace or route<\/h4>\n\n<ul>\n<li>Allow IP addresses \/ CIDR ranges (IPv4 and IPv6), roles and user IDs.<\/li>\n<li>Deny IP addresses \/ CIDR ranges and roles.<\/li>\n<li>Denials take precedence over allowances and also apply to administrators.<\/li>\n<li>All exceptions are visible in the route list at a glance.<\/li>\n<\/ul>\n\n<h4>Automatic allowances<\/h4>\n\n<p>Some plugins need the REST API for visitors on the front end. Their namespaces are public as long as you do not set a custom rule. Each of them can be switched off in the settings:<\/p>\n\n<ul>\n<li>Contact Form 7<\/li>\n<li>WooCommerce Store API (cart, checkout)<\/li>\n<li>oEmbed (embedding posts on other sites)<\/li>\n<li>LiteSpeed Cache (QUIC.cloud)<\/li>\n<li>WP Statistics<\/li>\n<\/ul>\n\n<h4>Global settings and hardening<\/h4>\n\n<ul>\n<li>Never block administrators (recommended \u2013 the block editor needs the REST API).<\/li>\n<li>Global allow lists for user IDs and IP addresses, global IP deny list.<\/li>\n<li>Custom error message and status code (401, 403 or 404 \u2013 the latter makes blocked routes look non-existent).<\/li>\n<li>Allow the REST API over HTTPS only.<\/li>\n<li>Disable JSONP.<\/li>\n<li>Remove REST links from HTTP headers, the HTML head and RSD.<\/li>\n<li>Hide blocked routes and namespaces in the REST index (<code>\/wp-json\/<\/code>).<\/li>\n<\/ul>\n\n<h4>Log and tools<\/h4>\n\n<ul>\n<li>Optional log of the last 200 blocked requests. The IP address can be stored in full, shortened or not at all.<\/li>\n<li>Self-test: shows what logged-out visitors get from the REST API.<\/li>\n<li>Export and import of all settings as JSON.<\/li>\n<li>WP-CLI: <code>wp wirecore-rest status|routes|set|default|export|import|log<\/code>.<\/li>\n<\/ul>\n\n<h4>Coverage<\/h4>\n\n<p>Rules apply to every real REST request, including embedded responses (<code>_embed<\/code>) and sub-requests of the batch endpoint (<code>\/batch\/v1<\/code>). Internal <code>rest_do_request()<\/code> calls made by PHP \u2013 for example when the block editor preloads data \u2013 are not affected.<\/p>\n\n<h4>Multisite<\/h4>\n\n<p>Settings are stored per site, because every site has its own routes and plugins. The plugin can be network-activated; uninstalling removes the settings of all sites.<\/p>\n\n<h4>For developers<\/h4>\n\n<ul>\n<li><code>wirecore_rc_error<\/code> \u2013 filters the <code>WP_Error<\/code> of a blocked request (parameters: error, route pattern, method). Returning <code>true<\/code> allows the request after all.<\/li>\n<li><code>wirecore_rc_client_ip<\/code> \u2013 filters the client IP, e.g. behind a reverse proxy.<\/li>\n<li><code>wirecore_rc_known_namespaces<\/code> \u2013 filters the plugins offered under \"Automatic allowances\" (array <code>key =&gt; [namespaces]<\/code>).<\/li>\n<\/ul>\n\n<h4>Privacy<\/h4>\n\n<p>The plugin does not send any data to external services and does not set cookies. If you enable the log, it stores the method, route, IP address (in full, shortened or not at all \u2013 configurable), user ID and the reason of blocked requests in the database of your site. The self-test sends requests from your server to its own REST API.<\/p>\n\n<h4>Source code and third-party resources<\/h4>\n\n<p>The settings page uses the <a href=\"https:\/\/github.com\/WireCore\/WireLayer\">WireLayer<\/a> component library (MIT). <code>assets\/wirelayer\/wirelayer.css<\/code> is generated from the npm package <code>@wirecore\/wirelayer-css<\/code> with <code>npm run build:css<\/code>; the source code of the plugin, including <code>package.json<\/code>, is available at <a href=\"https:\/\/github.com\/WireCore\/WP-Rest-Control\">github.com\/WireCore\/WP-Rest-Control<\/a>. Bundled with it:<\/p>\n\n<ul>\n<li>Tailwind CSS (MIT) \u2013 preflight and utilities compiled into <code>wirelayer.css<\/code><\/li>\n<li>Schibsted Grotesk and JetBrains Mono fonts (SIL Open Font License 1.1, <code>assets\/wirelayer\/fonts\/OFL.txt<\/code>), served from the plugin \u2013 no external font service<\/li>\n<li>Lucide icons (ISC)<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Install the plugin via <em>Plugins \u2192 Add New<\/em> or upload the plugin folder to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate the plugin. From now on, logged-out visitors can no longer use the REST API, except for the automatically allowed namespaces.<\/li>\n<li>Go to <em>Settings \u2192 REST API<\/em> to review the route list and adjust the rules.<\/li>\n<\/ol>\n\n<p>With Composer, the plugin can be installed from WPackagist: <code>composer require wpackagist-plugin\/wirecore-rest-control<\/code>.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"a%20rule%20locked%20me%20out%20of%20the%20admin%20area.%20what%20can%20i%20do%3F\"><h3>A rule locked me out of the admin area. What can I do?<\/h3><\/dt>\n<dd><p>Add the following line to your <code>wp-config.php<\/code>. It disables all rules until you remove it again:<\/p>\n\n<pre><code>define( 'WIRECORE_RC_OFF', true );\n<\/code><\/pre><\/dd>\n<dt id=\"will%20administrators%20be%20blocked%3F\"><h3>Will administrators be blocked?<\/h3><\/dt>\n<dd><p>Not by default: the option \"Never block administrators\" is enabled after activation, because the block editor needs the REST API. Deny lists (IP addresses, roles) always apply, also to administrators.<\/p><\/dd>\n<dt id=\"my%20contact%20form%20or%20shop%20checkout%20stopped%20working.\"><h3>My contact form or shop checkout stopped working.<\/h3><\/dt>\n<dd><p>Check <em>Settings \u2192 REST API \u2192 Settings \u2192 Automatic allowances<\/em>. If the plugin is not listed there, search for its namespace in the route list and set it to \"Public\".<\/p><\/dd>\n<dt id=\"does%20it%20also%20restrict%20routes%20of%20other%20plugins%3F\"><h3>Does it also restrict routes of other plugins?<\/h3><\/dt>\n<dd><p>Yes. The route list contains every registered route and shows which plugin or theme registered it. Some plugins only register routes during REST requests; the list is therefore loaded through the REST API itself so that these routes are included as well.<\/p><\/dd>\n<dt id=\"how%20can%20i%20check%20what%20visitors%20see%3F\"><h3>How can I check what visitors see?<\/h3><\/dt>\n<dd><p>Use <em>Tools \u2192 Self-test<\/em> on the settings page, or open <code>\/wp-json\/<\/code> in a private browser window.<\/p><\/dd>\n<dt id=\"is%20the%20plugin%20translated%3F\"><h3>Is the plugin translated?<\/h3><\/dt>\n<dd><p>The plugin ships with German translations (formal and informal). Further translations are welcome on translate.wordpress.org.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Disable the WordPress REST API selectively \u2013 per namespace, route and HTTP method, including routes of other plugins, with IP and role exceptions.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/395985","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=395985"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/wirecore"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=395985"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=395985"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=395985"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=395985"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=395985"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=395985"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}