V230808 error using s2if shortcode

Worked for me.

1 Like

Yes, I know it’s worked that way for years, the line has not changed for years. Of course going back to the previous version of the line will work as it did.

But the new line is not a bug, the previous version had the bug… It worked, but in an incorrect way: it allowed using unsafe functions. It was a security vulnerability for some sites that have more than just the admin editing content.

This release fixed that vulnerability, with the effect of also preventing the undocumented use of the shortcode. You were using a custom function that shouldn’t have worked the way you used it, but it worked for you, so of course you kept it.

Now it doesn’t work as you were used to, so it feels like a bug, but it’s not, although I can understand it’s an inconvenience, and I’m really sorry for that. :pray:

The expected, and more controlled way, of using custom conditionals, was through enabling the php attribute of the shortcode in s2Member Pro (or filtering the whitelist of conditional functions), and there you have more flexibility with the conditionals used.

In s2Member Pro you enable the php attribute from here: WP Admin > s2Member Pro > Simple Shortcode Conditionals > Allow Arbitrary PHP Code

Screenshot%202023-08-09%20at%2022-59-01%20s2Member%20Restriction%20Options%20%E2%80%B9%20s2Member%20Membership%20Plugin%20for%20WordPress%20%E2%80%94%20WordPress

And then you can use your custom conditional as I mentioned earlier:

[s2If php="cmbEsStripe()"]

I hope that clarifies it. :slight_smile:

changing the Line 66 to:
$blog_farm_safe = apply_filters(‘ws_plugin__s2member_sc_if_conditionals_blog_farm_safe’,
array(‘is_user_logged_in’, ‘is_user_not_logged_in’,
‘user_is’, ‘user_is_not’, ‘user_can’, ‘user_cannot’,
‘current_user_is’, ‘current_user_is_not’, ‘current_user_can’, ‘current_user_cannot’,
‘is_admin’, ‘is_blog_admin’, ‘is_user_admin’, ‘is_network_admin’,
‘is_404’, ‘is_home’, ‘is_front_page’, ‘is_singular’, ‘is_single’, ‘is_page’,
‘is_page_template’, ‘is_attachment’, ‘is_feed’, ‘is_archive’, ‘is_search’,
‘is_category’, ‘is_tax’, ‘is_tag’, ‘has_tag’, ‘is_author’, ‘is_date’,
‘is_day’, ‘is_month’, ‘is_time’, ‘is_year’, ‘is_sticky’, ‘is_paged’,
‘is_preview’, ‘is_comments_popup’, ‘in_the_loop’, ‘comments_open’,
‘pings_open’, ‘has_excerpt’, ‘has_post_thumbnail’, ‘get_user_option’, ‘current_user_days_to_eot_less_than’ , ‘s2member_auto_eot_time’, ‘current_user_gateway_is’), get_defined_vars());

works. I’m not sure if s2member_auto_eot_time should be in that list, I guess not, but the three other addtions were surely missing. Hope those three and all others that were added later and are documented somewhere will make it into the list.

The most important thing is that the s2 shortcodes don’t work inside comments. That would be the biggest security risk. And they don’t. But Christian I’m really not sure if the php inside pages/posts without just referencing a shortcode with the php in the backend is allowed on worpdress.org plugins sections any longer. Basically if the php option is enabled, than anyone who has editing rights, can take over your full website as I see it by using some nifty php. So if that option is enabled, this new behaviour has no use.

shortcodes don’t work inside comments. That would be the biggest security risk. And they don’t.

It’d be bad if shortcodes worked in comments, or bbPress, but it’s still bad if someone other than the admin can use PHP, like Editors, who can edit posts and pages using shortcodes.

I’m really not sure if the php inside pages/posts without just referencing a shortcode with the php in the backend is allowed on worpdress.org plugins sections any longer.

The PHP option is not in the Framework, that’s a Pro feature that’s not in the Plugins Directory.

Basically if the php option is enabled, than anyone who has editing rights, can take over your full website as I see it by using some nifty php.

That’s why the PHP attribute is an option disabled by default, that the admin can decide if he wants enabled.

And there’s also the option to edit the array with the filter (better than the file directly, so it doesn’t get replaced with the updates).

Maybe I could create an option in the s2If admin panel, to enter the names of functions to whitelist, a UI to the filter…

Thank you.
I’ll try it.

1 Like

Actually just a link with an example on how to write a must-use-plugin adding an actual key would be enough. I wasn’t sure how exaxtly I would have had to write that mu-plugin based on the information in this thread.
And I missed that it’s only part of s2member pro.

The php attribute for s2If is a Pro feature, the filter can be used by anyone. An example using the filter would be:

<?php
add_filter('ws_plugin__s2member_sc_if_conditionals_blog_farm_safe', 
  function ($whitelist, $vars = array()) {
    // Add functions to use in s2If
    $whitelist[] = 'current_user_can_for_blog';
    $whitelist[] = 'current_user_cannot_for_blog';
    $whitelist[] = 'current_user_days_to_eot_less_than';
    $whitelist[] = 'current_user_gateway_is';
    $whitelist[] = 'current_user_is_for_blog';
    $whitelist[] = 'current_user_is_not_for_blog';
    $whitelist[] = 'has_term';
    $whitelist[] = 'in_category';
    $whitelist[] = 'is_active_sidebar';
    $whitelist[] = 'is_child_theme';
    $whitelist[] = 'is_customize_preview';
    $whitelist[] = 'is_main_site';
    $whitelist[] = 'is_multi_author';
    $whitelist[] = 'is_multisite';
    $whitelist[] = 'is_rtl';
    $whitelist[] = 'is_super_admin';
    $whitelist[] = 'is_trackback';

    // openmtbmap
    $whitelist[] = 'get_user_field';
    $whitelist[] = 'get_user_option';

    return $whitelist;
  }
);

You can put that code in a PHP file, e.g. s2if-whitelist.php, and upload it to /wp-content/mu-plugins/

That example shows functions I noticed in s2If’s article, and WP conditional tags, that are missing from the array in the code, so I’ll add them for next release. https://s2member.com/kb-article/s2if-simple-shortcode-conditionals/#toc-5bb69568

I’m not sure I’ll include get_user_field or get_user_option in the release, but you can have them in your whitelist. https://www.s2member.com/codex/stable/s2member/api_functions/package-functions/#src_doc_get_user_field()

:slight_smile:

1 Like

get_user_option(s2member_auto_eot_time)

Is very useful to show EOT time on user profile page (if user has EOT). I think it got documented a couple of times. It S2 made a mistake with payment or quite often if user paid without logging in that field was very useful for the user to contact me and tell me something is wrong. There is no other use I need it for. I’m not sure I use get_user_field . Think I don’t.

1 Like

This will be the updated whitelist in next release:

			//230811 Whitelist of conditional functions
			$blog_farm_safe = array(
				'comments_open',
				'current_user_can',
				'current_user_can_for_blog',
				'current_user_cannot',
				'current_user_cannot_for_blog',
				'current_user_days_to_eot_less_than',
				'current_user_gateway_is',
				'current_user_is',
				'current_user_is_for_blog',
				'current_user_is_not',
				'current_user_is_not_for_blog',
				'has_excerpt',
				'has_post_thumbnail',
				'has_tag',
				'has_term',
				'in_category',
				'in_the_loop',
				'is_404',
				'is_active_sidebar',
				'is_admin',
				'is_archive',
				'is_attachment',
				'is_author',
				'is_blog_admin',
				'is_category',
				'is_child_theme',
				'is_comments_popup',
				'is_customize_preview',
				'is_date',
				'is_day',
				'is_feed',
				'is_front_page',
				'is_home',
				'is_main_site',
				'is_month',
				'is_multi_author',
				'is_multisite',
				'is_network_admin',
				'is_page',
				'is_page_template',
				'is_paged',
				'is_preview',
				'is_rtl',
				'is_search',
				'is_single',
				'is_singular',
				'is_sticky',
				'is_super_admin',
				'is_tag',
				'is_tax',
				'is_time',
				'is_trackback',
				'is_user_admin',
				'is_user_logged_in',
				'is_user_not_logged_in',
				'is_year',
				'pings_open',
				'user_can',
				'user_cannot',
				'user_is',
				'user_is_not',
			);
			$blog_farm_safe = apply_filters('ws_plugin__s2member_sc_if_conditionals_blog_farm_safe', $blog_farm_safe, get_defined_vars());

Are you using s2If to show the EOT time? s2If conditionals should basically evaluate as true or false. The shortcode to show the value would be s2Get. https://s2member.com/kb-article/s2get-shortcode-documentation/

Auto EOT-Time for the current User (when applicable). Use date_format="" with any PHP date formatting chars you like. If you don’t pass this, a timestamp is given instead. See: http://php.net/manual/en/function.date.php

[s2Get user_field="s2member_auto_eot_time" date_format="M jS, Y, g:i a T" /]

If you’re using it so that the s2If evaluates as true when there is an EOT time and false when there isn’t, that’s fine, that’d work.

I’m looking at how to force, if possible, a boolen evaluation in the s2If conditional, so that it only computes as true or false.

Some examples how I use s2get. I think they are all documented. and yes I use s2if get_user_option. to show the EOT time for the user I simply use s2get without if. I think all these options really have to work as they are essential (also need to be sure to be able to cascade them).

  1. Hi [s2Get constant="S2MEMBER_CURRENT_USER_FIRST_NAME" /] it would be

  2. [s2If get_user_option(s2member_auto_eot_time)]
    …text
    [_s2If current_user_days_to_eot_less_than(8)] Your account will expire within this week - renew now in order not to lose access - [/_s2If]
    text
    [/s2If]

  3. [s2If !get_user_option(s2member_auto_eot_time) AND current_user_can(access_s2member_level1)]

[_s2If current_user_days_to_eot_less_than(8)] Your account will expire within this week - renew now in order not to lose access - [/_s2If]

[s2If get_user_option(s2member_auto_eot_time)]
Your account is paid and active until: [s2Eot date_format=“M jS, Y” /]
[/s2If]

So a Boean True/False is suficient for get_user_option. Because I use it in combination with s2if get_user_option… and s2if !get_user_option

2 Likes

That’s really neat! I surely need to do the same on my own site.

Right. You’d just need to whitelist get_user_option, though, because I don’t think it’ll be there by default. You can use the filter as I showed you above, and that won’t be affected by s2 updates. I’m also looking at adding an option in s2If’s admin panel, to whitelist functions from there.

So a Boean True/False is suficient for get_user_option.

Cool. I’m looking at a safe way to do this, as an extra safety measure, since there shouldn’t be any output from the conditional function, only a true/false. Probably with an output buffer, so the output doesn’t get out, but I could evaluate it as true if not empty…

1 Like

[s2If !get_user_option(s2member_auto_eot_time) AND current_user_can(access_s2member_level1)]

This one for example is needed to show content only to people with active subscription (vs people with active account but one time payment).

I’m fine with adding the mu-plugin. But actually this function is needed by everyone who has both subscription and one time payments.
That was you can show prolongation payments to everyone but people with subscription, while offering a clear donation without any reward for those with subscription.
Also this adds another advantage, donation without rewards is usually vat free, maybe even tax free because people who simply donate to a company without any reward/function while they already have a subscription clearly can pass like this. If you just call it donation without any specific reward but they like your website it’s actually not a donation (if you are not registered as NGO or similar) because people still profit - e.g. from enjoying your website (then you would need to prove you don’t earn money overall with what your doing so it’s a hobby)

1 Like

We have been stung by this too - our profile page (including member’s profile information, membership details, bookings etc.) currently crashes with an ugly critical error, rendering the whole page out of action - not just the section using the S2If conditional.

We’re using the current_user_days_to_eot_less_than() function, which you’re saying should have been included in the update. Are you able to give us an ETA for when the update re-adding that function will be out? We’d rather not hack around with the plugin, but if it’s going to be days then we’ll have to patch it in the mean time.

1 Like

Released an update with it today:

https://s2member.com/s2member-v230815-now-available/

It includes other improvements I mentioned earlier in the thread, too.

:slight_smile:

Hi Cristian,

I’m really sorry, but I’m struggling to understand this thread (my own fault, as I find anything like this really confusing). Apart from very simple s2 shortcode like “[s2If current_user_is(s2member_level0)]”, the only s2 shortcode that I use on my site is the following …

[s2Eot mode=“fixed” date_format=“d/m/Y” timezone=“Europe/London” /]
[s2Get user_field=“first_name” /]
[s2Get user_field=“last_name” /]
[s2Get user_field=“user_email” /]

… is any of the above affected by the issue in this thread? (I’m just wondering whether I need to make any changes to my website before I update s2Member).

Thanks,
Steve

yes s2get user_field - it’s even mentioned in the example.

Apart from very simple s2 shortcode like “[s2If current_user_is(s2member_level0)]”, the only s2 shortcode that I use on my site is the following …
… is any of the above affected by the issue in this thread? (I’m just wondering whether I need to make any changes to my website before I update s2Member).

No, you don’t need to worry about it, it doesn’t affect you. This only has to do with s2If, not other shortcodes, and you’re using there a current_user_is conditional that was in the whitelist, so it’d work as usual.

But that’s the s2Get shortcode, and with its user_field attribute, it’s not the get_user_field function used in an s2If shortcode. https://s2member.com/kb-article/s2get-shortcode-documentation/

:slight_smile:

Thanks very much Cristian :slight_smile:

1 Like