BoldGrid / w3-total-cache

GNU General Public License v2.0
151 stars 83 forks source link

cache groups: cookie group - no regex support even though stated on settings page #798

Open aheinzel opened 6 months ago

aheinzel commented 6 months ago

Is it possible that cookie groups do not actually support the use of regex?

Under Settings -> Cache Groups in the section manage cookie groups under the Cookies textarea field it is stated that regex are supported:

Specify the cookies for this group. Values like 'cookie', 'cookie=value', and cookie[a-z]+=value[a-z]+ are supported. Remember to escape special characters like spaces, dots or dashes with a backslash. Regular expressions are also supported.

However, when using a regex it appears that meta characters are escaped while generating mod_rewrite rewrite conditions, see: https://github.com/BoldGrid/w3-total-cache/blob/91e0b97b706e6fe9aa4dabecee9b62f34bafc025/PgCache_Environment.php#L657

To examplify this issue I created a cache group regtest1 with the following settings:

In return the following rewrite rule/condition was added to my .htaccess file by W3 Total Cache:

RewriteCond %{HTTP_COOKIE} ^(.*;\s*)?(cookie_\.\*_prefs\=a\.\*)(\s*;.*)?$ [NC]
RewriteRule .* - [E=W3TC_COOKIE:_regtest1]

In the rule generated all the metacharacters have been escaped. In consequence the condition does not match a request with cookie_1_prefs=a1. See following trace:

RewriteCond: input='cookie_1_prefs=a1' pattern='^(.*;\\s*)?(cookie_\\.\\*_prefs\\=a\\.\\*)(\\s*;.*)?$' [NC] => not-matched, referer: 

When manually adding the same condition without escaping of metacharacters the condition matches.

RewriteCond %{HTTP_COOKIE} ^(.*;\s*)?(cookie_.*_prefs=a.*)(\s*;.*)?$ [NC]
RewriteRule .* - [E=W3TC_COOKIE:_regtest1]
RewriteCond: input='cookie_1_prefs=a1' pattern='^(.*;\\s*)?(cookie_.*_prefs=a.*)(\\s*;.*)?$' [NC] => matched, referer: 

This issue does not only affect user defined cache groups but also applies to the built in cache group for logged in users, see https://github.com/BoldGrid/w3-total-cache/blob/91e0b97b706e6fe9aa4dabecee9b62f34bafc025/ConfigKeys.php#L720 To match this group the following two lines are added to .htaccess

RewriteCond %{HTTP_COOKIE} ^(.*;\s*)?(wordpress_logged_in_\.\*=.*)(\s*;.*)?$ [NC]
RewriteRule .* - [E=W3TC_COOKIE:_loggedin]

But a request with the cookie wordpress_logged_in_1234 will not be matched by this condition

RewriteCond: input='wordpress_logged_in_1234=1' pattern='^(.*;\\s*)?(wordpress_logged_in_\\.\\*=.*)(\\s*;.*)?$' [NC] => not-matched

Environment

aheinzel commented 6 months ago

Also worth noting is that the escaping does not only affect the rewrite conditions and thus delivery of cached files but also cache generation itself. The same method for escaping metacharacters in the cookies is used when assembling the suffix for the cache files, see https://github.com/BoldGrid/w3-total-cache/blob/91e0b97b706e6fe9aa4dabecee9b62f34bafc025/PgCache_ContentGrabber.php#L1264

So in case a regex is used to specify the cookie for a cookie group the group will not be detected when assembling the cache path and thus the content for the accessed URL will be cached as default (no group).