Skip to content

Azure WAF custom rules for PHP2Shell mitigation

Written in collaboration with Gunjan Jain​ and yuvalpery​ 


As described in our earlier blog, Addressing PHP2Shell CVE-2026-109618 and CVE-2026-109619: upgrade guidance and Azure WAF mitigations, we strongly recommend upgrading to a patched version of PHP as soon as possible. Upgrading PHP remains the recommended and complete remediation for these vulnerabilities. 


For customers who are unable to upgrade immediately, this guidance provides WAF custom rules that can help reduce exposure to selected request patterns associated with exploitation techniques for these vulnerabilities.  


WAF custom rules 


The following three custom rules can be considered based on your application configuration and traffic patterns. Because custom rules can affect legitimate application traffic, review the potential application impact and validate the rules before enabling enforcement. 


Restrict PHP session upload progress


PHP supports session upload progress for tracking file uploads. For applications that do not depend on this functionality, customers can use a custom rule to restrict multipart form requests containing PHP_SESSION_UPLOAD_PROGRESS. 


The rule checks for multipart/form-data requests whose inspected request body contains the PHP session upload progress token. 


Custom rule definitions:

Azure Front Door WAF


{ 
  “name”: “BlockPhpSessionUploadProgress”, 
  “priority”: 100, 
  “enabledState”: “Enabled”, 
  “ruleType”: “MatchRule”, 
  “action”: “Block”, 
  “matchConditions”: [ 
    {  
      “matchVariable”: “RequestHeader”,  
      “selector”: “Content-Type”,  
      “operator”: “Contains”,  
      “negateCondition”: false,  
      “transforms”: [“Lowercase”],  
      “matchValue”: [“multipart/form-data”]  
    },  
    {  
      “matchVariable”: “RequestBody”,  
      “operator”: “Contains”,  
      “negateCondition”: false,  
      “matchValue”: [“php_session_upload_progress”],  
      “transforms”: [“Lowercase”]  
    } 
  ] 
}

Application Gateway and Application Gateway for Container (AGC) WAF 


{
“name”: “BlockPhpSessionUploadProgress”,
“priority”: 90,
“ruleType”: “MatchRule”,
“action”: “Block”,
“state”: “Enabled”,
“matchConditions”: [
{
“matchVariables”: [ { “variableName”: “RequestHeaders”, “selector”: “Content-Type” } ],
“operator”: “Contains”,
“negationConditon”: false,
“matchValues”: [ “multipart/form-data” ],
“transforms”: [ “Lowercase” ]
},
{
“matchVariables”: [ { “variableName”: “PostArgs” } ],
“operator”: “Contains”,
“negationConditon”: false,
“matchValues”: [ “php_session_upload_progress” ],
“transforms”: [ “Lowercase” ]
}
]
}

This rule reduces exposure through the PHP session-upload-progress path but does not address all exploitation paths associated with the vulnerabilities. 


Potential application impact: Applications that legitimately use PHP session upload progress will also match this rule. A substring match may also detect the token when it appears as harmless text or in uploaded content exposed to inspection.


Limit deeply nested form parameters


Customers can use a custom rule to identify unusually deep parameter nesting in application/x-www-form-urlencoded requests. 


The proposed rule detects request field names containing 20 or more levels of bracket nesting after URL decoding. 


Because the 20-level threshold is an application policy choice rather than a vulnerability-defined boundary, legitimate applications using deeply nested parameters may also match this rule. 


Custom rule definitions:

Azure Front Door WAF: 


{ 
  “name”: “PhpFormNesting20”, 
  “priority”: 110, 
  “enabledState”: “Enabled”, 
  “ruleType”: “MatchRule”, 
  “action”: “Log”, 
  “matchConditions”: [ 
    { 
      “matchVariable”: “RequestHeader”, 
      “selector”: “Content-Type”, 
      “operator”: “BeginsWith”, 
      “negateCondition”: false, 
      “transforms”: [ 
        “Trim”, 
        “Lowercase” 
      ], 
      “matchValue”: [ 
        “application/x-www-form-urlencoded” 
      ] 
    }, 
    { 
      “matchVariable”: “RequestBody”, 
      “operator”: “RegEx”, 
      “negateCondition”: false, 
      “transforms”: [ 
        “UrlDecode” 
      ], 
      “matchValue”: [ 
        “(?:^|&)[^&=\\[]+(?:\\[[^&=\\]]*\\]){20}” 
      ] 
    } 
  ] 
} 

Application Gateway and Application Gateway for Container (AGC) WAF 


{
“name”: “PhpFormNesting20”,
“priority”: 91,
“ruleType”: “MatchRule”,
“action”: “Log”,
“state”: “Enabled”,
“matchConditions”: [
{
“matchVariables”: [ { “variableName”: “RequestHeaders”, “selector”: “Content-Type” } ],
“operator”: “BeginsWith”,
“negationConditon”: false,
“matchValues”: [ “application/x-www-form-urlencoded” ],
“transforms”: [ “Trim”, “Lowercase” ]
},
{
“matchVariables”: [ { “variableName”: “RequestBody” } ],
“operator”: “Regex”,
“negationConditon”: false,
“matchValues”: [ “(?:^|&)[^&=\\[]+(?:\\[[^&=\\]]*\\]){20}” ],
“transforms”: [ “UrlDecode” ]
}
]
}

Recommended deployment: Start with the rule in Log mode and review matches against legitimate application traffic. Consider moving the rule to Block only after validating application compatibility. 


Limit deeply nested multipart parameters


Customers can apply a similar control to multipart/form-data requests by detecting deeply nested field names. 


The proposed rule detects multipart field names containing 20 or more levels of nesting where the relevant request content is available to WAF inspection. 


As with deeply nested URL-encoded parameters, legitimate applications may use complex multipart field structures. 


Custom rule definitions:

Azure Front Door WAF


{ 
  “name”: “PhpMultipartNesting20”, 
  “priority”: 111, 
  “enabledState”: “Enabled”, 
  “ruleType”: “MatchRule”, 
  “action”: “Log”, 
  “matchConditions”: [ 
    { 
      “matchVariable”: “RequestHeader”, 
      “selector”: “Content-Type”, 
      “operator”: “BeginsWith”, 
      “negateCondition”: false, 
      “transforms”: [ 
        “Trim”, 
        “Lowercase” 
      ], 
      “matchValue”: [ 
        “multipart/form-data” 
      ] 
    }, 
    { 
      “matchVariable”: “RequestBody”, 
      “operator”: “RegEx”, 
      “negateCondition”: false, 
      “matchValue”: [ 
        “(?i)(?:^|\\r?\\n)content-disposition:[ \\t]*form-data[^\\r\\n]*;[ \\t]*name[ \\t]*=[ \\t]*(?:\”(?:\\\\[\”\\\\]|[^\”\\r\\n\\[])+(?:\\[(?:\\\\[\”\\\\]|[^\”\\r\\n\\]])*\\]){20}|[^ \\t\\r\\n;\”\\[]+(?:\\[[^ \\t\\r\\n;\”\\]]*\\]){20})” 
      ] 
    } 
  ] 
} 

Application Gateway and Application Gateway for Container (AGC) WAF 


{
“name”: “PhpMultipartNesting20”,
“priority”: 92,
“ruleType”: “MatchRule”,
“action”: “Log”,
“state”: “Enabled”,
“matchConditions”: [
{
“matchVariables”: [ { “variableName”: “RequestHeaders”, “selector”: “Content-Type” } ],
“operator”: “BeginsWith”,
“negationConditon”: false,
“matchValues”: [ “multipart/form-data” ],
“transforms”: [ “Trim”, “Lowercase” ]
},
{
“matchVariables”: [ { “variableName”: “PostArgs” } ],
“operator”: “Regex”,
“negationConditon”: false,
“matchValues”: [ “^[^\\[\\]]+(?:\\[[^\\]]*\\]){20}” ],
“transforms”: []
}
]
}

This rule targets deeply nested multipart field names. It does not restrict every multipart upload or provide complete mitigation for the underlying vulnerabilities. 


Recommended deployment: Start in Log mode, review matching traffic, and consider moving to Block only after validating the impact on your application. 


Deployment and validation considerations


We recommend applying these custom rules only to affected PHP application domains and routes, including extensionless routes handled by PHP, rather than broadly applying them to unrelated applications. 


Before enabling enforcement: 



  • Review the potential impact on legitimate application traffic. 



  • Test each custom rule independently before deploying the rules together. 



  • Start applicable rules in Log mode and review legitimate matches. 



  • Verify the WAF policy scope and custom-rule precedence. 



  • After changing a rule to Block, validate both application behavior and the corresponding WAF events. 



  • Continue to prioritize upgrading PHP even when these controls are deployed. 


Custom rules may produce false positives, and WAF request-body inspection boundaries can affect coverage. An earlier terminal Allow rule in the WAF policy can also bypass subsequent custom-rule checks. 


The custom rules described above target selected request patterns associated with exploitation techniques for CVE-2026-109618 and CVE-2026-109619. They reduce selected attack surfaces but do not provide complete protection against either vulnerability. 


You can find more information about Custom Rules on Azure WAF for Application Gateway here or for Azure Front Door here.  


Upgrading to a patched version of PHP remains the recommended and complete remediation.  

Microsoft Tech Community originally posted this article on 22 October 2026 at 4:24 AM.

Leave a Reply