WordPress Comment Image plugin doesn't save uploaded image when Apache Requires are used

283 Views Asked by At

I've got an Apache 2.4.7 box with a WordPress 4.1 installation and a plugin added which allows users to add images to comments on pages/posts (https://wordpress.org/plugins/comment-images/). The image upload feature isn't working when Require statements are added to restrict access to the site (it's a development environment so limited access is required).

The image upload actually works with or without Require directives but when the directives are added, the reference to the uploaded image doesn't get saved to WordPress properly.

The error from the log is:

PHP Warning:  preg_match_all() expects parameter 2 to be string, object given in /var/www/html/wp-content/plugins/comment-images/class-comment-image.php on line 480

I dumped the object being passed into a file (serialized):

O:8:"WP_Error":2:{s:16:"^@WP_Error^@errors";a:1:{s:8:"http_404";a:1:{i:0;s:12:"Unauthorized";}}s:20:"^@WP_Error^@error_data";a:0:{}}

I outputted the print_debug_backtrace() as well to show the calls. I've had to delete the comment data from the arrays for privacy reasons:

#0  Comment_Image->save_comment_image(63)
#1  call_user_func_array(Array ([0] => Comment_Image Object ([] => 5000000,[] => ,[] => ),[1] => save_comment_image), Array ([0] => 63)) called at [/var/www/html/wp-includes/plugin.php:496]
#2  do_action(wp_insert_comment, 63, stdClass Object ()) called at [/var/www/html/wp-includes/comment.php:1941]
#3  wp_insert_comment(Array ()) called at [/var/www/html/wp-includes/comment.php:2083]
#4  wp_new_comment(Array ()) called at [/var/www/html/wp-comments-post.php:137]

The directives for the <Directory> with the WP install in are (with IPs obfuscated):

AllowOverride All
<RequireAny>
    AuthType Basic
    AuthName "Restricted Access"
    AuthBasicProvider file
    AuthUserFile /var/www/.htpasswd
    Require valid-user
    Require user dev www-data
    Require ip xx.xx.xx.xx/xx
    Require ip xx.xx.xx.xx
    Require local
</RequireAny>

If I add Require all granted (or just remove the Require directives), then the feature works as expected and uploaded images show up. Note Require local is there which as I understand it should cover everything for the local box.

Things I've checked:

  • Revised the configs in light of Apache 2.4 changes to auth modules and ordering importance etc.
  • WordPress install folder is recursively chown'ed correctly
  • Permissions on upload folder are 777'd, but shouldn't matter as the upload always succeeds

Where does this issue lie??

2

There are 2 best solutions below

1
On

Looks like the plugin does not handle well the fact that your server is unable to download an image on itself.

The warning (class-comment-image.php on line 480) corresponds to this snippet:

$img_url = media_sideload_image( $comment_image_file['url'], $post_id );

preg_match_all( "#[^<img src='](.*)[^'alt='' />]#", $img_url, $matches );

$comment_image_file['url'] = $matches[0][0];

The WP media_sideload_image function uses curl to get the image, and because of your restrictions it does not succeed, and then returns an error object that the preg_match_all function cannot handle.

The data is saved later in the metas; it explains why the reference is not saved even if the upload worked.

Require local probably does not work on your dev server, you may try to replace it with its local address.

0
On

I tried adding Require ip <local-ip-of-box> as per johansatge's suggestion. Whilst this didn't doesn't work, it made me think..

The box is in Azure which assigns a floating public IP. Annoyingly, the cURL request was bouncing out and using that public IP - because the domain used for the box wasn't added to the hosts file.

The solution was to add <domain-of-website-on-box> to the loopback (127.0.0.1) entry in /etc/hosts.