What rule can I use in ModSecurity to log POST payload for a specific site?

Similar to this question: How to get mod_security to log all POST data?

You are correct you cannot chain two rules in two different phases, however phase 2 has access to all phase 1 information so just move this to phase 2 if you want to do this in this way.

This rule that you gave:

SecRule REQUEST_METHOD "POST" "phase:2,log,id:22222223

Is kind of pointless. This will log (in the main log) that a POST request was received but without the POST body.

It will also log to AuditEngine depending on what your SecAuditEngine value is set to:

  1. If you have SecAuditEngine set to On then everything is logged to audit log and above rule is not needed. This fills up log files quickly so is not recommended.
  2. If you have SecAuditEngine set to RelevantOnly then it will also log here.
  3. If SecAuditEngine is set to Off then it will never be logged to the audit log.

It's usually best to have SecAuditEngine set to RelevantOnly (which I suspect is what you have already), but if that is not set to that, then the body may not be logged to the AuditLog

Perhaps a better way to do it is with that other rule you gave using ctl action:

SecRule REQUEST_METHOD "POST" "id:22222224,phase:2,ctl:auditEngine=On,log,pass"

This forces the AuditEngine to be on for post requests - even if the AuditLog is set to Off. This will also log that you have fired this rule to turn it in which isn't really necessary or useful, so I'd change the "log" to "nolog". The request will still log (as auditEngine has been set to yes), but this rule making that change won't. BTW when you use ctl, this only affects this request so the AuditEngine will reset back for the next request.

As you state this seems to work except you don't have the C part. This is set with SecAuditLogParts. By default this includes C parts so guess that means you must have changed the default? Was there any reason for this?

Anyway you can either set that to include C parts:

SecAuditLogParts ABCFHZ
SecRule REQUEST_METHOD "POST" "id:22222224,phase:2,ctl:auditEngine=On,nolog,pass"

Or, if you only want C parts logged when this rule fires, you can do this as part of the rule:

SecRule REQUEST_METHOD "POST" "id:22222224,phase:2,ctl:auditEngine=On,ctl:auditLogParts=ABCFHZ,nolog,pass"

The other thing to be aware of is that POST requests can log sensitive data (passwords, credit card numbers, social security numbers... Etc). Logging these is not advised and may also break company policy and/or any standards you are following (e.g. PCI compliance). Therefore it is recommended to set up sanitise rules to mask this data. See here for more info: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#sanitiseArg