I am currently creating a plugin for WordPress that will log errors in the admin area that may happen in a custom code. This log is not intended for PHP errors, which are already stored in debug.log.
It’s more to help find configuration errors, for example if I have a looper for posts and I expect the post image to be set. like:
$post_img = get_the_post_thumbnail_url(123, 'full');
if ($post_img == false)
{
my_error_log ('No featured image set for post 123');
}
I’m showing this errors in a admin WP_List style so even editors could handle and solve such configuration errors.
Everything works great until i tried to catch $wpdb->last_error messages! Like:
$query = $wpdb->query ('DDELETE FROM ' . $wpdb->postmeta . ' WHERE meta_key = "custom_meta";');
if ($query === false)
{
my_error_log ('Failure in wpdb->query!<br><code>' . $wpdb->last_error .'</code>');
}
The DELETE command is intentionally incorrect to generate an error message!
It is written correctly in the database with
Failure in wpdb->query!<br><code>You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DDELETE FROM wpdev_postmeta WHERE meta_key = "custom_meta"' at line 1</code>
But if i want to show the errors in the WP_LIST while getting the errors with function prepare_items and $wpdb->get_results(‘SELECT * FROM wp_my_error_log ….
i only get a 404 error and nothing is displayed!
While searching the server error log files (the right one 😉 ) I found the following line:
> [:error] [pid 803349:tid 139870349313792] [client 123.XXX.XXX.XXX:0]
> ModSecurity: Access denied with code 404 (phase 4). Pattern match "You
> have an error in your SQL syntax; check the manual " at RESPONSE_BODY.
> [file "/etc/modsecurity/conf.d/11_asl_data_loss.conf"] [line "96"] [id "361022"]
> [rev "2"] [msg "Atomicorp.com WAF Rules: Potential SQL Information Leakage"] [severity "ALERT"] [tag "no_ar"]
So does that mean ModSecurity thinks it’s an SQL injection? And how should I log my error then?
2
Answers
It seems that this aspect of security is really important. Even Stackoverflow have a solution for this. It nested my posted error message above into special elements:
My solution was to replaced all spaces with the HTML entity
. Then it also gets past the ModSecurity.I don’t think so.
Look at the log message:
The key is the phase, which is 4 and the target: RESPONSE_BODY.
You are right that this is because of the ModSecurity (even more the used rule set), but it does not assume it’s an SQL injection.
You should create an exclusion, which depends on URI/IP address/anything, and partially remove rule
361022
, or the targetRESPONSE_BODY
at the rule.