Require login for the WordPress Media Folder


  • While this solution is designed to work across all systems, there may be specific circumstances where it does not function as expected on your setup.

Usage When you enable this option, WPO365 blocks direct access to your WordPress site's Media Library, i.e. the /wp-content/uploads folder. Every request for a file in /wp-content/uploads is routed to WPO365's so-called secure download proxy instead. WPO365 does this by adding rewrite rules to your website's .htaccess file (see info box immediately below the "Usage" section if your site uses another web server that ignores WordPress' default .htaccess file.

The proxy first tries to serve the requested file using its built-in fast path. It checks a cookie named "wordpress_wpo365_mlda" (or "wordpress_wpo365_mlda_<blog id>" on WordPress Multisite), which WPO365 issues to a user who is signed in. The cookie is valid for 24 hours and contains no information about the user. It's signed with a secret key that is unique to your website. If the cookie is missing or cannot be recreated or validated, the proxy switches to its slow path: it loads WordPress to check whether the user is signed in. If the user is not signed in, WPO365 sends them to Microsoft to sign in, or denies access.
To check the cookie without loading WordPress, the proxy needs access to a secret key, used to sign it and. When you enable the option, WPO365 therefore generates a random key and stores it in the database. It also writes a copy of the key to your server, in /wp-content/wpo365/mlda-key-<blog id>.php (e.g. mlda-key-1.php). The file starts with "<?php exit;", so requesting it in a browser returns nothing, and the proxy only reads it; it never runs it.
The proxy ships as part of WPO365 | LOGIN, but the access check itself is provided by your WPO365 premium plugin. If no active premium plugin provides it, your files are not protected, and WPO365 shows a warning in the WordPress admin instead.

IMPORTANT

  • When you enable this option on a WordPress installation that runs on an Apache web server, then the plugin will attempt to automatically add rewrite rules to your site's so-called ".htaccess" file. If your site uses another web server - for example NGINX or IIS or Azure App Service, then please scroll down for instructions below to update the rewrite rules manually.
  • If WPO365 cannot write to /wp-content/wpo365, your files stay protected, but every request takes the slow path, and WPO365 shows a warning in the WordPress admin.
  • When you disable the option or deactivate WPO365 | LOGIN, WPO365 removes the file again.
  • Every time you enable the option, WPO365 generates a new key. That invalidates all cookies issued before.
  • Media Library Protection is not working as expected when WordPress is installed in a folder e.g. https://<host>/<folder>/.

Secure Download Mode

The Secure Download Mode setting allows the plugin to hand off file delivery to the web server after access has been authenticated and authorized. Depending on your server environment, this can improve download performance and provide more reliable handling of large files.
The following modes are available:
  • PHP This is the default mode. Files are served directly by PHP after the plugin has verified that the user is authorized to access the requested file.
  • Use X-Sendfile (Apache) When enabled, the plugin instructs the Apache web server to serve the file using the X-Sendfile response header. This can significantly reduce PHP memory usage and improve the handling of large downloads.
  • Use X-LiteSpeed-Location (LiteSpeed) When enabled, the plugin instructs the LiteSpeed web server to serve the file using the X-LiteSpeed-Location response header. This can improve performance and allows the web server to handle file delivery directly.

IMPORTANT Only enable a hand-off mode if your server is configured to support the corresponding response header. For example, when using X-Sendfile with Apache, the mod_xsendfile module must be installed and enabled. If the required server support is not available, file downloads may fail. A good indication that the header is not supported by your server is when you see the X-Sendfile as part of the raw response.

Instructions for Apache (.htaccess)

Please try and operate the toggle as illustrated below first.

If an error is returned, then please try and update your site's .htaccess manually instead, by adding the lines below to the end of the file.

Single Site

<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_URI} ^/wp-content/uploads/
RewriteRule ^wp-content/uploads/(.*)$ /wp-content/plugins/wpo365-login/Services/Secure_Download_Proxy.php?file=$1 [L,QSA]
</IfModule>

Multi-Site

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(?:[_0-9a-zA-Z-]+/)?wp-content/uploads/(.*)$ /wp-content/plugins/wpo365-login/Services/Secure_Download_Proxy.php?file=$1 [L,QSA]
</IfModule> 

Instructions for NGINX

Single Site

In your server block, add the following config.

location ~* ^/wp-content/uploads/(.*)$ {
    rewrite ^/wp-content/uploads/(.*)$ /wp-content/plugins/wpo365-login/Services/Secure_Download_Proxy.php?file=$1 last;
}
Multi-Site
location ~ ^/(?:[_0-9a-zA-Z-]+/)?wp-content/uploads/(.*)$ {
    rewrite ^/(?:[_0-9a-zA-Z-]+/)?wp-content/uploads/(.*)$ /wp-content/plugins/wpo365-login/Services/Secure_Download_Proxy.php?file=$1 last;
}
NGINX tries regex locations in the order they appear and uses the first match. Therefore ensure the following.
  • Put it before any location that matches static files by extension, e.g. location ~* \.(jpg|jpeg|png|gif|webp|svg|pdf)$ { expires max; }. Most WordPress NGINX configs have one. If that block comes first, images and PDFs are served directly and aren't protected.
  • Put it after any location that denies access to part of uploads, e.g. WooCommerce's woocommerce_uploads folder, or a rule that blocks PHP in uploads. Otherwise, this rule overrides them.
  • Don't use location ^~ /wp-content/uploads/ to avoid the ordering problem: it also skips those deny rules.

Instructions for IIS / Azure App Service

<rewrite>
  <rules>
    <rule name="Secure Uploads" stopProcessing="true">
      <match url="^wp-content/uploads/(.*)$" />
      <action type="Rewrite" url="/wp-content/plugins/wpo365-login/Services/Secure_Download_Proxy.php?file={R:1}" />
    </rule>
  </rules>
</rewrite>
Default value FALSE (not enabled)

Versions ESSENTIALS, PROFESSIONAL, INTEGRATE, CUSTOMERS (SYNC, INTRANET)

Visit the website https://www.wpo365.com/

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us