{"id":338995,"date":"2026-07-25T07:55:18","date_gmt":"2026-07-25T07:55:18","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/kw-members-fortress\/"},"modified":"2026-07-25T07:54:48","modified_gmt":"2026-07-25T07:54:48","slug":"kw-members-fortress","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/kw-members-fortress\/","author":13656071,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.8","stable_tag":"1.0.8","tested":"7.0.2","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"KW Members Fortress","header_author":"Kreiswolke","header_description":"Make your whole site private \u2014 every page, feed, REST endpoint and uploaded file requires login \u2014 and prove it isn't leaking. A self-contained members-only fortress for a standalone WordPress site.","assets_banners_color":"","last_updated":"2026-07-25 07:54:48","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/kreiswolke.com\/members-fortress","header_author_uri":"https:\/\/kreiswolke.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":39,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.8":{"tag":"1.0.8","author":"Basic777","date":"2026-07-25 07:54:48"}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.8"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"The branded login screen (background, overlay, accent colour, logo, and footer links).","2":"Lockdown tab \u2014 protection status, server type, public-asset folder, and the leak self-test result, plus the hardening toggles.","3":"Login Screen tab \u2014 background image, overlay, colours, and logo.","4":"Footer &amp; Pages tab \u2014 three slots for built-in legal pages or external links."}},"plugin_section":[],"plugin_tags":[267962,23569,41177,19898,31388],"plugin_category":[],"plugin_contributors":[270834],"plugin_business_model":[],"class_list":["post-338995","plugin","type-plugin","status-publish","hentry","plugin_tags-file-protection","plugin_tags-force-login","plugin_tags-login-required","plugin_tags-members-only","plugin_tags-private-site","plugin_contributors-basic777","plugin_committers-basic777"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/kw-members-fortress.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p><strong>KW Members Fortress<\/strong> turns a standalone WordPress site into a private, members-only space. Visitors who aren't logged in can't reach <strong>anything<\/strong> except the login screen and the legal pages you choose to publish \u2014 not your pages, posts, archives, search, feeds, REST API, sitemaps, XML-RPC, and crucially <strong>not your uploaded files<\/strong> either.<\/p>\n\n<p>Most \"force login\" plugins only gate the <em>pages<\/em> WordPress renders. They leave every file in <code>\/wp-content\/uploads\/<\/code> reachable by anyone who has (or guesses) the URL \u2014 PDFs, images, documents. KW Members Fortress routes those file requests through WordPress and serves them <strong>only to logged-in members<\/strong>, then continuously <strong>self-tests<\/strong> that the seal is holding.<\/p>\n\n<h4>What it does<\/h4>\n\n<ul>\n<li><strong>Whole-site gate<\/strong> \u2014 logged-out requests are redirected to login: pages, posts, archives, search, feeds, REST, sitemaps, XML-RPC.<\/li>\n<li><strong>Protected file URLs<\/strong> \u2014 direct hits to <code>\/wp-content\/uploads\/\u2026<\/code> are served only to members (Apache\/LiteSpeed handled automatically; nginx shows you the one snippet to paste).<\/li>\n<li><strong>Leak self-test (canary)<\/strong> \u2014 about once an hour the plugin makes a cookie-less request to one of its own upload URLs and raises a dashboard alarm if a file ever comes back without login. Silent misconfiguration becomes a visible warning.<\/li>\n<li><strong>Branded login screen<\/strong> \u2014 set a background image, overlay colour\/gradient, accent colour, and logo from the settings page. No file editing.<\/li>\n<li><strong>Footer &amp; legal pages<\/strong> \u2014 up to three footer items, each a built-in page (rendered theme-less and reachable while logged out) or an external link. Perfect for an Imprint \/ Privacy notice on an otherwise-private site.<\/li>\n<li><strong>Hardening (all optional, on by default)<\/strong> \u2014 block logged-out admin-ajax, block user-enumeration, no-cache headers on blocked responses, and a progressive login throttle that auto-recovers.<\/li>\n<\/ul>\n\n<h4>Good to know<\/h4>\n\n<ul>\n<li>No accounts, tiers, payments, or third-party services. One site, one membership wall.<\/li>\n<li>Runtime files are stored under <code>\u2026\/wp-content\/uploads\/kw-members-fortress\/<\/code> \u2014 never in the plugin folder.<\/li>\n<li>The leak self-test only ever contacts <strong>your own site's<\/strong> URL; it is not an external service.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin to <code>\/wp-content\/plugins\/<\/code> (or install it from your dashboard) and activate it.<\/li>\n<li>On <strong>Apache \/ LiteSpeed<\/strong> the upload-protection rule is written for you. On <strong>nginx<\/strong>, the plugin shows a short <code>location<\/code> snippet \u2014 paste it into your server block and reload nginx.<\/li>\n<li>Visit <strong>Members Fortress<\/strong> in the admin menu to brand the login screen, add footer\/legal pages, and review the <strong>Lockdown<\/strong> status (server type, public-asset folder, and the latest leak self-test result).<\/li>\n<li>Log out in a separate browser to confirm the site is sealed.<\/li>\n<\/ol>\n\n<p><strong>Caching:<\/strong> because every visitor must be checked individually, full-page caching of the front end must be turned off (or the gate can be bypassed by a cached copy). The plugin sends no-cache headers on blocked responses, but a page cache in front of WordPress should not store logged-in\/front-end pages.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20it%20really%20protect%20uploaded%20files%2C%20or%20just%20pages%3F\"><h3>Does it really protect uploaded files, or just pages?<\/h3><\/dt>\n<dd><p>Files too \u2014 that's the point. Requests to <code>\/wp-content\/uploads\/\u2026<\/code> are routed through WordPress and served only to logged-in members. The only exception is a small public sub-folder, <code>uploads\/kw-members-fortress\/public\/<\/code>, which holds just your chosen login background and logo so they can load on the logged-out login screen.<\/p><\/dd>\n<dt id=\"why%20does%20it%20edit%20my%20root%20%60.htaccess%60%3F\"><h3>Why does it edit my root `.htaccess`?<\/h3><\/dt>\n<dd><p>On Apache\/LiteSpeed the upload-protection rule is added to <code>.htaccess<\/code> using WordPress' own marker API (the same mechanism core uses for permalinks), inside a clearly-marked block. Deactivating the plugin removes the block and restores normal file serving.<\/p><\/dd>\n<dt id=\"what%20is%20the%20%22leak%20self-test%22%3F\"><h3>What is the \"leak self-test\"?<\/h3><\/dt>\n<dd><p>A tiny sentinel file lives in the plugin's folder inside uploads (<code>uploads\/kw-members-fortress\/canary.txt<\/code> \u2014 a location that must stay locked). About once an hour, while you're in the dashboard, the plugin requests that file's URL <strong>without<\/strong> sending your login cookies. If the file comes back, the gate isn't working and you get a red dashboard warning. It only ever contacts your own site \u2014 it is not a third-party service.<\/p><\/dd>\n<dt id=\"i%27m%20on%20nginx%20and%20files%20are%20still%20reachable.\"><h3>I'm on nginx and files are still reachable.<\/h3><\/dt>\n<dd><p>nginx configuration can't be edited from PHP, so the plugin shows the exact <code>location<\/code> snippet to add to your server block. Add it and reload nginx; the <strong>Lockdown<\/strong> tab and the self-test will confirm the seal.<\/p><\/dd>\n<dt id=\"can%20i%20show%20an%20imprint%20%2F%20privacy%20page%20to%20logged-out%20visitors%3F\"><h3>Can I show an Imprint \/ Privacy page to logged-out visitors?<\/h3><\/dt>\n<dd><p>Yes. Under <strong>Footer &amp; Pages<\/strong>, set a slot to <strong>Built-in page<\/strong>, give it a title and content, and it renders on its own theme-less page that's reachable without login (and <code>noindex<\/code>). Images embedded inside that content won't display to logged-out visitors, since uploads stay locked \u2014 use text and HTML.<\/p><\/dd>\n<dt id=\"the%20login%20throttle%20locked%20me%20out.\"><h3>The login throttle locked me out.<\/h3><\/dt>\n<dd><p>After several failed logins from one IP, a short, growing cool-down is applied; it expires on its own (no permanent lockout). Note that visitors sharing one office\/NAT IP share the counter. You can turn the throttle off on the <strong>Lockdown<\/strong> tab.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20i%20deactivate%20or%20delete%20it%3F\"><h3>What happens when I deactivate or delete it?<\/h3><\/dt>\n<dd><p>Deactivating removes the <code>.htaccess<\/code> rule and turns protection <strong>off<\/strong> \u2014 by design. Deleting honours the <strong>Advanced \u2192 \"remove all data\"<\/strong> option: leave it off to keep your settings, or turn it on to remove the settings and the public-asset folder on uninstall.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.8<\/h4>\n\n<ul>\n<li>The legal-page styles are now delivered through the enqueue API (registered handle + <code>wp_add_inline_style<\/code>).<\/li>\n<li>All runtime files now live under <code>uploads\/kw-members-fortress\/<\/code>: the leak-test sentinel moved there from the uploads root, and public login assets moved into the <code>public\/<\/code> sub-folder. Existing installs migrate automatically.<\/li>\n<li>The sentinel file is now written via the <code>WP_Filesystem<\/code> API.<\/li>\n<\/ul>\n\n<h4>1.0.7<\/h4>\n\n<ul>\n<li>Initial public release.<\/li>\n<\/ul>","raw_excerpt":"Make your whole WordPress site private \u2014 every page, feed, REST endpoint and uploaded file requires login \u2014 and prove it isn&#039;t leaking.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/338995","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=338995"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/basic777"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=338995"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=338995"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=338995"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=338995"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=338995"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=338995"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}