Mod Security for Apache

We've taken a closer look at some of the most popular configurations for ModSecurity, an Open Source Web Application Firewall. For instance, we looked at the default ruleset that many hosts use from this source. Unfortunately, there are many Mod Security rules that can produce false positive results, and we've also found that each host runs with a little bit different combination of rules, based on what they consider to be most important to their clients; and perhaps tailored to the most common software applications they host for their clients.

In short, there's really no way for s2Member to work around everything Mod Security looks at from one host to another. If you're running Mod Security and you plan to continue to run it, you may need your hosting company or system administrator to tweak things for the applications that you run; e.g., by removing paranoid rules from your Mod Security configuration.

In the Core Rule Set Project we found several rules that would negatively impact even a default WordPress installation—even counting points against cookies set by the core WordPress framework. Anyway, you get the picture, paranoid!

Known Problematic Areas In s2Member

  • URL:[encrypted data string appears here]
  • URL:[encrypted data string appears here]
  • URL:[followed by GET/POST data from PayPal]
  • URL:[followed by GET/POST data from PayPal]
  • For that matter, any URL that contains: ?s2member_ and/or ?s2member_pro_ could be considered suspect under a paranoid Mod Security configuration.
  • Also, some data stored in cookie names starting with: s2member_ and/or wordpress_.

I don't personally care for Mod Security (I think it produces too many false positives and too many headaches). If configured properly it can be useful. The problem? It seldom is. That being said, I do understand that many hosts use this as a way to further protect the integrity of their servers. Given the degree of complexity associated with heuristic rule sets for Mod Security, all we can do with s2Member is follow best practices when it comes to what data we include in GET/POST/COOKIE/HEADER data (e.g., no HTML in query strings, no function/parameter names, no SQL keywords, etc).

Beyond that, if you are still experiencing what are seemingly random 403 errors (possibly associated with cookies, headers, query string variables, etc), please follow the instructions below.

Disabling Mod Security

Try adding SecFilterEngine Off and SecFilterScanPOST Off to an .htaccess file in the web root. Many hosts allow this to be disabled on a per-user basis. Some users are allowed to do this by default on WHM/cPanel-based servers.

If you run your own dedicated server and you want to save yourself headaches associated with Mod Security, you can disable it inside your httpd.conf file with something like this:

# Mod Security v1.x.
# May work in .htaccess too, on some hosts.
<IfModule mod_security.c>
    SecFilterEngine Off
    SecFilterScanPOST Off
# Mod Security v2.x.
# Will NOT work in .htaccess, use httpd.conf.
<IfModule mod_security2.c>
    SecRuleEngine Off

Warning: This solution is a tradeoff; i.e., security vs. usability. Please use this solution at your own risk. See also: this discussion thread.

Disabling Specific Mod Security Rules

If you run your own dedicated server and you want to keep Mod Security, but remove certain rules that are getting in your way (e.g., rules causing a problem for s2Member and/or other applications you run), check your Apache error.log file for Mod Security errors. Look for the rule ID associated with each of them. Then remove rule IDs that are causing problems, using your httpd.conf file.

# Mod Security v2.x only.
# Will NOT work in .htaccess, use httpd.conf.
<IfModule mod_security2.c>
    SecRuleRemoveById 960024 981173 981212 960032 960034

Warning: This solution is a tradeoff; i.e., security vs. usability. Please use this solution at your own risk. See also: this discussion thread.

Shared Hosting Suggestions for Mod Security

  • If you're on shared/managed hosting, ask your hosting company to disable Mod Security. Or, ask them to whitelist the s2Member application by disabling Mod Security for URLs that contain ?s2member_ in their query string, or are otherwise associated with your WordPress installation.
  • As yet another alternative, ask them to whitelist specific URLs that are causing problems for you. Hosts that run Mod Security are familiar with these requests, because Mod Security is so very picky. All you need to do is provide your host with the full URL that is failing (including any query string variables that appear after the ? mark in the URL) and/or point them to this article.
  • Or, ask your host to back down on the paranoia a bit overall with respect to Mod Security and/or the PHP Suhosin extension, which is yet another paranoid module (under certain configurations).

If you continue to have trouble, consider using a host that does not use Mod Security, or one that has a good flexible configuration; one which does not inhibit the functionality of trusted PHP applications and plugins for WordPress. Some hosts that just recently started using Mod Security, or have recently upgraded to Mod Security v2.x may still need time to work the kinks out of their default configuration. Try to be patient with your hosting company, but don't hang around forever waiting for a miracle either. We recommend MediaTemple® (gs) as a highly flexible solution in this regard.

Other Related Articles (Suggested Reading)

Security Plugins

It's also possible that a security plugin you're using, is preventing access to an s2Member URL. This is not a Mod Security issue, but the resulting behavior would be a similar 403 error. I've seen this happen particularly with s2Member's file for CSS and JS resources: s2member-o.php.

A plugin I've seen do this is iThemes Security, with the setting "Disable PHP in Plugins". You can try disabling that if you're having trouble loading s2's resources normally.

Another is SG Security, with the setting "Lock and Protect System Folders". You can disable that, and see if the problem goes away. SG Security has a filter to whitelist files, while leaving the feature enabled. You can use that in a code snippets plugin, your theme's functions file, or a must-use plugin, for example.

add_filter( 'sgs_whitelist_wp_content' , 'whitelist_file_in_wp_content' );
function whitelist_file_in_wp_content( $whitelist ) {
    $whitelist[] = 's2member-o.php';
    return $whitelist;