• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

RocketGeek

Home of WP-Members, The Original WordPress Membership Plugin

  • WordPress Plugins
    • WP-Members
      • FAQs
      • Quick Start
      • Documentation
      • Extensions
    • Advanced Options
      • Documentation
      • Purchase the Plugin
      • Get the Pro Bundle
    • Download Protect
      • Documentation
      • Purchase the Plugin
      • Get the Pro Bundle
    • Invite Codes
      • Documentation
      • Purchase the Plugin
      • Get the Pro Bundle
    • MailChimp Integration
      • Documentation
      • Purchase the Plugin
      • Get the Pro Bundle
    • PayPal Subscriptions
      • Documentation
      • Purchase the Plugin
      • Get the Pro Bundle
    • Salesforce Web-to-Lead
    • Security
      • Documentation
      • Purchase the Plugin
      • Get the Pro Bundle
    • Text Editor
      • Purchase the Plugin
      • Get the Pro Bundle
    • User List
      • Documentation
      • Purchase the Plugin
      • Get the Pro Bundle
    • User Tracking
      • Documentation
      • Purchase the Plugin
      • Get the Pro Bundle
    • Memberships for WooCommerce
    • WordPass
  • Blog
    • Basics
    • Tips and Tricks
    • Filters
    • Actions
    • Code Snippets
    • Shortcodes
    • Design
    • Release Announcements
  • Store
    • Cart
    • Checkout
  • Contact
  • Log In
  • Show Search
Hide Search
Home » Plugins » WP-Members » Documentation » FAQs » Obfuscating file upload fields

Obfuscating file upload fields

The plugin uses a general set of defaults for file fields. When file upload fields are used for non-private information, this is adequate. This is the case for using them for custom avatars, or shared public documents. This is not well suited to use for something more private and even though the plugin sets up index.php and .htaccess files to prevent directory browsing, user IDs and file names can be guessed and malicious actors can probe for these values.

To prevent a malicious actor from discovering potential user uploaded files, you can set up a few filters to obfuscate the directory and file names used. The examples in this FAQ will cover changing three components of the path from the defaults:

  1. The WP-Members file directory in the WP uploads (default value: “wpmembers”)
  2. The user upload directory within the WP-Members directory above (default value: user ID)
  3. The actual file name (obfuscating this to random values to prevent probing for names like “passport.pdf”, “drivers-license.pdf”, “application.pdf”, etc.

Putting together these three elements will change a file path from this:

wpmembers/user_files/134/my_file.pdf

to something like this:

userfiles_p28MEZeXIo1mC8OI3HI1QU0JqGTdIZgK/15NaHvFFoRbpD63O6DFCfysoI7dVY0yd6t5B/b691a2452ea1b529dcc2ad7e12d7474ed644.pdf

tldr; Each part of this is explained in detail below, but each of the three code snippets is copy/paste ready and will give you the above result.

Changing the WP-Members upload directory

This makes use of the main WP-Members settings filter hook wpmem_settings to change the name of the main WP-Members upload directory. The following code snippet will use a random hash value as part of the directory name. You can make this long or short – the example makes the hash 32 characters long.

/**
 * Use a random hash as the plugin's general upload directory name.
 * 
 * This example uses a random string length of 32 chars, but you
 * can change the value to whatever suits (longer or shorter).
 */
add_filter( 'wpmem_settings', function( $settings ) {
    
    // How long of a hash?
    $hash_len = 32;
    
    // Check if we already created a hash.
    $hash = get_option( 'wpmem_file_dir_hash' );
    if ( ! $hash ) {
        // If there is no existing hash, create with wp_generate_password().
        $hash = wp_generate_password( $hash_len, false, false );
        update_option( 'wpmem_file_dir_hash', $hash );
    }
    
    /*
     * What format of the main directory is desired?
     * This example makes it "userfiles_2NUMkyuWC08n09".
     * The directory does not need to include "wpmembers" in the name.
     * It can be whatever name is desired. Or, it can be just the
     * hash value as the name.  It's up to the site admin.
     */
    $settings['upload_base'] = "userfiles_" . $hash;
    
    return $settings;
});

Changing the WP-Members user directory names

When WP-Members uploads a user file, it uses the user ID to create the folder name. We can adjust this to a more random value similar to how we hashed the primary upload directory using the wpmem_user_upload_dir filter hook. However, in this case, we’re using a random hash for each user. The following code snippet creates a 32 character value, but it uses the user ID as the first part of the string, thus avoiding the need to test each hash for uniqueness. Like the first code snippet above, you can adjust the hash length as desired.

/**
 * Add a random hash to the user upload directory.
 * 
 * Change the default name of the user upload directory.
 * This example completely removes the user ID value from the
 * directory name, leaving it as a completely random string.
 * 
 * Change $hash_len to set the length. Example creates a random
 * string 36 characters long.
 */
add_filter( 'wpmem_user_upload_dir', function( $args ) {
    
    // How long of a hash?
    $hash_len = 36;
    
    // Check if user already has a directory hash.
    $hash = get_user_meta( $args['user_id'], 'wpmem_file_dir_hash', true );
    if ( ! $hash ) {        
        /*
         * If there is no existing hash, we need to create one.
         * 
         * To make sure it is unique without having to do a for/while loop
         * while checking the db, we can use the user ID in the string.
         * Since the random hash is already long, inserting the user ID
         * does not degrade the randomness.  Theoretically, one could just
         * add the user ID without this step, but I like to have everything
         * being the same length so that a one digit user ID results in the 
         * same directory name length as a four digit user ID.
         *
         * This example makes it user ID + hash.  For example, where the 
         * user ID is "234", the resulting direcotry would be like this:
         * 
         *     234LXd2B8SE31u19TAS0SnwQW6ji
         * 
         * For ultimate randomness in this example, consider switching to
         * add the user ID to the end rather than the beginning.  I did it
         * at the beginning to allow a user with file system access to be
         * able to browse the directory by user ID if they understood the
         * directory name construction being done here.
         */
        $uid_len = strlen( $args['user_id'] );
        $hash = $args['user_id'] . wp_generate_password( ($hash_len-$uid_len), false, false );
        
        update_user_meta( $args['user_id'], 'wpmem_file_dir_hash', $hash );
    }
    
    $args['user_dir'] = $hash;
    
    return $args;
});

Changing the file name to something random

The last part of this is to randomize file names. We can do this using the core WP filter sanitize_file_name.

/**
 * Completely randomize the filename of the upload.
 * 
 * Change the variable $hash_len based on the random
 * string length desired. Example creates a random
 * string 36 characters long.
 */
add_filter( 'sanitize_file_name', function( $filename ) {
    
    // How long a random string do we want?
    $hash_len = 36;
    
    // Get the file extension.
    $ext = pathinfo( $filename, PATHINFO_EXTENSION );
    
    if ( preg_match( '/^[a-f0-9]{'. $hash_len . '}-.*/', $filename ) ) {
        $filename = substr( $filename, $hash_len + 1 );
    }

    $key = sha1( random_bytes(32) );
    $key = substr( $key, 0, $hash_len );

    return "$key.$ext";
}, 10 );

  • Getting Started
  • Recommended WordPress® Settings
  • Plugin Settings
    • Options
    • Fields
    • Dialogs
    • Emails
    • New Feature Settings
  • Managing Content
    • Restricting Posts
    • Restricting Pages
    • Show Excerpts
    • Custom Post Types
  • Managing Users
    • Import Users
    • Export Users
    • Edit Users
    • Search Users
  • Login
  • Registration
    • Choosing Fields
    • Create a Registration Page
    • Moderating Registration
    • Using CAPTCHA
    • Removing Registration Options
  • User Profile
  • Memberships
    • Membership Properties
    • Membership Levels
  • Menus
    • Individual Menu Items
    • Logged In Menus
    • Login/Logout Menu Link
  • Customizing Emails
    • Email Address
    • Email Content
    • Email Format
    • Email Shortcodes
    • Email Troubleshooting
  • Customizing Forms
    • Create a Custom Stylesheet
    • Using the WordPress Customizer
    • Login Form HTML
    • Registration Form HTML
    • Widget Login Form HTML
  • Translation and Localization
    • Maintain a custom translation file
    • Filter untranslated strings
    • Multi-language Considerations
  • Shortcodes
    • Pages and Forms
    • Login Status
    • User Fields
    • Memberships
    • Email
    • Other Shortcodes
  • WP-CLI Commands
  • API Functions
  • Filter Hooks
  • Action Hooks
  • FAQs
    • Email troubleshooting
    • Passwords are not being included in Emails
    • The plugin isn’t blocking my content
    • Are files protected?
    • How can I prevent registration spam?
    • How to add a shortcode
    • How to apply login redirects
    • Why can’t users log in?
    • Why does reCAPTCHA v3 fail?
    • Troubleshooting Really Simple Captcha
    • Why do I get a 403 error?
    • How do I use code snippets?
    • My changes aren’t showing up
    • How to hide the “Admin Bar”
    • How to add a forgot password link
    • Password reset doesn’t show any fields
    • Domain not included in the password reset link
    • There was an error processing the form
    • Hidden vs. Restricted
  • Demo Videos
  • How to Request Support
  • Copy Settings for Support
  • Hosting Recommendations

Ready to get started?

Join Today!

© 2025 · butlerblog.com · RocketGeek is built using WordPress, WP-Members, and the Genesis Framework

  • butlerblog.com
  • WP-Members Support Subscription
  • Terms of Service
  • Privacy Policy
  • Refund Policy