• Resolved BERJAYADominik

    (@elexpress)


    Hi team,

    I noticed that backup archives generated by popular backup/staging plugins can remain directly downloadable via their URL, even if the filename contains a hash.

    From my perspective, adding a hash to the filename does not provide real access control. If the URL becomes known, guessed, leaked through logs, browser history, cache files, or any other mechanism, the archive can still be downloaded directly. For a backup file that may contain the database, wp-config.php, customer data, API keys, and other sensitive information, this is a significant risk.

    I would strongly recommend that backup downloads are not served as static files directly from the public web path. Instead, access to ZIP/archive files should be routed through a PHP endpoint that verifies whether the current user is authenticated and has sufficient WordPress admin capabilities, for example manage_options. If the check fails, the endpoint should return a 403 response.

    A possible approach would be:

    1. Block direct public access to backup archive files via .htaccess, Nginx rules, or equivalent server configuration.
    2. Serve downloads only through a controlled PHP route inside WordPress.
    3. Before streaming the file, verify that the user is logged in, has admin privileges, and passes a nonce/security check.
    4. Return HTTP 403 for all unauthorized requests.

    This would provide actual access control instead of relying mainly on non-guessable filenames.

    This is also problematic in light of applicable EU and German IT security and data protection requirements, including Article 32 GDPR, the NIS2 Directive, the German BSI Act/IT Security Act framework, and sector-specific BSI guidance, all of which require risk-appropriate technical and organisational measures to protect confidentiality, integrity, availability and resilience; a mere hash-based protection mechanism is therefore not an adequate substitute for properly authenticated access control, encryption and secure backup management.

    Best regards

Viewing 1 replies (of 1 total)
  • Plugin Author BERJAYARene Hermenau

    (@renehermi)

    Hi Dominik,

    Thank you for your detailed feedback. We agree with the general security principle: a hash in a filename is not the same as authenticated access control. Backup files can contain highly sensitive data, so they should be treated carefully and stored in a protected location whenever possible.

    The approach you suggest is technically valid in hosting environments where the server configuration is fully controlled. However, it is not something we can reliably enforce as the default mechanism in a WordPress plugin that must run on many different and uncontrolled hosting environments.

    The main issue is that large backup archives cannot always be safely served through a PHP endpoint. Backups can be several GB in size, and PHP-based downloads are affected by limits such as:

    • max_execution_time
    • PHP-FPM, FastCGI, web server, proxy, and CDN timeouts
    • memory limits
    • output buffering behavior
    • disabled PHP functions
    • client disconnect handling
    • unreliable support for partial downloads and resume requests

    On many shared or managed WordPress hosting environments, routing all backup downloads through PHP would cause large downloads to fail, time out, or become incomplete. Static file delivery by the web server is much more reliable for large files because that is exactly what the web server is designed to handle.

    There is also no universal way for a WordPress plugin to safely modify the server configuration. .htaccess only works on Apache-compatible setups. Nginx rules usually cannot be changed by a plugin. Managed hosts may block such changes entirely, and other environments behave differently depending on their configuration.

    For users who want to store backups outside the publicly accessible web root, we already provide a filter for this purpose. For example:

    add_filter('wpstg.backup.directory', function ($dir) {
        return '/var/www/my-backups';
    });

    This allows advanced users and site administrators to move the backup directory to a location that is not publicly served by the web server, provided the directory exists and is writable by the PHP/WordPress process.

    So the safest setup is usually:

    • store backups outside the public web root when the hosting environment allows it
    • delete backup files when they are no longer needed
    • use offsite or encrypted backup storage for sensitive production data
    • apply server-level access rules where the administrator controls the server

    For a plugin that must work across many different web hosts, we cannot make PHP-controlled streaming or server-level blocking the only default mechanism without breaking backup downloads for many users. But where the hosting environment supports it, moving the backup directory outside the public web root is the recommended solution.

    Best regards
    René

Viewing 1 replies (of 1 total)

You must be logged in to reply to this topic.