Current Release Candidate: RC 4
WP-Members 2.8.2 is both a feature release and a fix release. Continue Reading →
Home of WP-Members, The Original WordPress Membership Plugin
Chad Butler · ·
Current Release Candidate: RC 4
WP-Members 2.8.2 is both a feature release and a fix release. Continue Reading →
Chad Butler · ·
The WP-Members 2.8.1 release is an important security update for the plugin. It is highly recommended that you upgrade as previous versions of the plugin have a possible exploit that may be vulnerable. As soon as I became aware of this, I put all other items on the project list on hold.
While 2.8.1 is primarily a security fix, there are some additional features, as well as a few improvements as well. These are items that were already in the works when the security issue was made apparent.
Here is a list of what is included in the 2.8.1 release:
In previous versions, the front side page that was used to handle user functions such as reset a forgotten password, update registration info, change your password, and (in the PayPal addon) renew a subscription, was called with the shortcode [[wp-members page=”members-area”]].
It has been called that since the beginning of this plugin. Unfortunately, it has been a confusing issue because it has turned out that this is not intuitive. For users that do not necessarily read the plugin documentation and installation instructions (or do not read them thoroughly), the term Members Area gets interpreted as “area of my site that is restricted content” and not “area of my site for members to update their info”.
So beginning in 2.8.1, this is being changed to User Profile. The shortcode will be [[wp-members page=”user-profile”]] but the old shortcode will still work. As you can see in 2.8.0, the name was already changed in the options panel. If you continue to use the old shortcode, that is ok. Future releases will support it (for now). However, all references to the Members Area will be changed to User Profile in the plugin documentation and instructions as the use of the term is deprecated.
Chad Butler · ·
This is an idea that has been floated by a few users, which means there is probably a need for it. As is usually the case, I don’t like to make wholesale changes to the codebase that effects users in a way that requires them to make a change to accommodate an update. So I wouldn’t want to change the plugin to put in different classes, since users with a custom stylesheet would need to be paying attention when they update to accommodate the new classes in their stylesheet. But this is something that we can certainly do on the fly using the wpmem_msg_dialog filter. This article will show you how to do just that. Continue Reading →
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:
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.
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;
});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;
});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 );This is a filter hook that allows you to modify the spam score used by reCAPTCHA v3.
reCAPTCHA v3 returns a score (1.0 is very likely a good interaction, 0.0 is very likely a bot). Based on the score, you can take variable action in the context of your site.
The default value used in the WP-Members plugin is 0.5. Use the filter to allow registrations with a lower value, or restrict to registrations with a higher value as needed.
More information from Google’s documentation for reCAPTCHA version 3.
$score
(integer)(required) The score required to allow the captcha to pass (0.0 – 1.0). Use a lower value to allow more registrations, higher to restrict more registrations.
add_filter( 'wpmem_recaptcha_score', function( $score ) {
/*
* Return a score between 1 and 0.1.
* A lower score will let through more results.
*/
return 0.3;
});wpmem_recaptcha_score is located in /includes/class-wp-members-recaptcha.php
Ready to get started?