The Problem

While deploying a Laravel API on a Webuzo-powered server (Apache + ModSecurity + OWASP CRS 3.3.5), I kept hitting 403 Forbidden on PUT, PATCH, and DELETE requests. GET and POST worked perfectly fine.

ModSecurity: Warning. Match of "within %{tx.allowed_methods}"
against "REQUEST_METHOD" required.
[id "911100"]
[msg "Method is not allowed by policy"]
[data "PUT"]

Laravel was not the issue. ModSecurity was.

Root Cause

The server runs OWASP CRS 3.3.5, which ships with Rule ID 911100. The rule checks:

SecRule REQUEST_METHOD "!@within %{tx.allowed_methods}"

By default, tx.allowed_methods only includes: GET HEAD POST OPTIONS. So any PUT, PATCH, or DELETE request raises the anomaly score and returns a 403.

What Not To Do

⚠️
Don't weaken your firewall

Disabling ModSecurity, removing OWASP CRS, or lowering anomaly thresholds all expose your server unnecessarily. There's a better way.

  • Do NOT disable ModSecurity globally
  • Do NOT disable OWASP CRS
  • Do NOT remove rule 949110
  • Do NOT reduce anomaly scoring thresholds

The Correct Fix

This requires root SSH access. You'll edit the VirtualHost config file directly.

1

SSH in as root

ssh root@your-server-ip
2

Open the Webuzo VirtualHost config

nano /usr/local/apps/apache2/etc/conf.d/webuzoVH.conf
3

Extend the allowed HTTP methods

Inside each <VirtualHost> block, replace the ModSecurity section:

<IfModule security2_module>
    SecRuleEngine On
    SecAction "id:1000001,phase:1,nolog,pass,t:none,
    setvar:'tx.allowed_methods=GET HEAD POST OPTIONS PUT PATCH DELETE'"
</IfModule>
4

Restart Apache

/usr/local/apps/apache2/bin/apachectl restart

Gotcha: The Webuzo UI Silently Reverts Your Fix

⚠️
When does this revert happen?

Any time you disable or re-enable the OWASP CRS from Webuzo's Security → ModSecurity Vendors panel, webuzoVH.conf is regenerated. Your manual edits are overwritten without warning.

Making the Fix Truly Persistent

The right place to extend tx.allowed_methods is the CRS configuration file that the method enforcement rule itself reads:

1

Open crs-setup.conf

nano /usr/local/apps/apache2/etc/conf.d/modsec_vendor_configs/OWASP3/crs-setup.conf
2

Add the SecAction to extend allowed methods

SecAction \
    "id:1000001,\
    phase:1,\
    nolog,\
    pass,\
    t:none,\
    setvar:'tx.allowed_methods=GET HEAD POST OPTIONS PUT PATCH DELETE'"
💡
Why this works here

crs-setup.conf is loaded before the rules files, so this SecAction runs in phase:1 and sets tx.allowed_methods before rule 911100 ever evaluates it. Webuzo's UI never touches this file, so the setting survives any CRS toggle.

3

Restart Apache

/usr/local/apps/apache2/bin/apachectl restart

Result

All green — firewall fully intact

ModSecurity enabled. OWASP CRS active. No protections weakened. REST API working.

  • PUT, PATCH, DELETE requests go through
  • ModSecurity remains fully enabled
  • OWASP CRS remains active
  • Anomaly scoring is unchanged
  • Fix survives Webuzo UI CRS toggles

Which Fix Should You Use?

ApproachFile editedSurvives Webuzo UI toggle?
VirtualHost fix (original)webuzoVH.confNo — file gets regenerated
CRS config fix (persistent)crs-setup.confYes — Webuzo never touches it

TL;DR

ModSecurity rule 911100 blocks REST verbs because tx.allowed_methods doesn't include them by default. The VirtualHost fix works — but the Webuzo UI regenerates webuzoVH.conf on any CRS toggle, silently wiping your changes. For a fix that actually sticks, add the SecAction to crs-setup.conf instead.