Windows Phone 8 WordPress App Media Upload Error
A little while ago I purchased a Nokia Lumia 920 with Windows Phone 8 (currently the Amber release). The phone itself is great, but I had a problem with the Windows Phone WordPress app, it wouldn’t upload or post any content that contained an image.
- Phone: Nokia Lumia 920
- OS: Windows Phone 8 (amber – Australia)
- Connectivity: WiFi and 3G/4G
- Problem: WordPress App won’t complete submission of a post or page that contains an image.
- Server: Xen VDS hosted on Amazon AWS with Amazon Linux (Amazon’s version of CentOS 6)
In case it’s not obvious, the WordPress blog I was experiencing the problem with is a self hosted installation. We can assume I installed it and set it up correctly 😉
(for sake of this post, I have replaced all references to the host with ‘mokonamodoki.com’).
Whenever I attempted to submit a page or post that contained an image, I would get the follow error message:
Media Upload Error
The remote server returned an error: NotFound
Yes, extremely helpful. I knew what the solution was immediately. Thank you, Microsoft!
I tried all sorts of tricks. PHP settings, Apache settings, and WordPress settings. Nothing worked. What frustrated me even more; was that the iOS app worked fine! Something I did notice, was that the iOS app uploads images separately, and not as part of the post content… this got me thinking.
Is the problem the Windows Phone WordPress app or is the problem the server?
Turns out it was both!
Since I can’t fix the Windows Phone WordPress app, I fixed the server instead.
As part of my ‘best practices’ when I set up a server, I always install ‘mod_security’ (ModSecurity) and ‘Suhosin’. Neither of these two have ever caused me any grief, but have protected my web servers from many attacks (in conjunction with CSF). As a systems administrator, I often recommend these three (CSF, ModSecurity and Suhosin), to victims of website compromise… sadly only about 1 in 10 actually listen.
What I wasn’t aware of, was that the version of ModSecurity installed on Amazon Linux, actually has a default configuration that is quite restrictive. So, how did I find out that ModSecurity was the problem?
I checked the logs! What logs?
Let’s have a look at the Apache access logs first.
# cd /var/log/httpd # tail -f access_log
While tailing the log file, I attempted to post an entry with an image. I saw the following lines show up:
<my ip address> - - [06/Oct/2013:14:23:31 +1100] "POST /xmlrpc.php HTTP/1.1" 413 430 "-" "wp-windowsphone/2.2.0" <my ip address> - - [06/Oct/2013:14:23:34 +1100] "POST /xmlrpc.php HTTP/1.1" 413 430 "-" "wp-windowsphone/2.2.0" <my ip address> - - [06/Oct/2013:14:23:39 +1100] "POST /xmlrpc.php HTTP/1.1" 413 430 "-" "wp-windowsphone/2.2.0"
The lines above basically show the Windows Phone WordPress app attempting to post my content. However, during the submission stage, it is rejected (error 430) with an error code of 413. What the heck is 413? Lets check another log.
# cd /var/log/httpd # tail -f error_log
[Sun Oct 06 14:23:33 2013] [error] [client <my ip address>] ModSecurity: Request body no files data length is larger than the configured limit (131072).. Deny with code (413) [hostname "mokonamodoki.com"] [uri "/xmlrpc.php"] [unique_id "UlDXszb8l-4AAFCqIb0AAAAD"]
[Sun Oct 06 14:23:38 2013] [error] [client <my ip address>] ModSecurity: Request body no files data length is larger than the configured limit (131072).. Deny with code (413) [hostname "mokonamodoki.com"] [uri "/xmlrpc.php"] [unique_id "UlDXtjb8l-4AAFCrJO4AAAAE"]
[Sun Oct 06 14:23:41 2013] [error] [client <my ip address>] ModSecurity: Request body no files data length is larger than the configured limit (131072).. Deny with code (413) [hostname "mokonamodoki.com"] [uri "/xmlrpc.php"] [unique_id "UlDXuzb8l-4AAFCtKYsAAAAG"]
Now we’re getting closer. According to the error log, ModSecurity denied the post submission due to a configured limit. You can see that common error code: (413) again. Lets check one more log.
# tail -f modsec_audit.log
--7925195e-A-- [06/Oct/2013:14:33:45 +1100] UlDaGDb8l-4AAFCpHb0AAAAC <my ip address> 57498 <server ip address> 80 --7925195e-B-- POST /xmlrpc.php HTTP/1.1 Accept: */* Content-Length: 514188 Accept-Encoding: identity Content-Type: text/xml User-Agent: wp-windowsphone/2.2.0 Host: mokonamodoki.com Connection: Keep-Alive Cache-Control: no-cache
--7925195e-F-- HTTP/1.1 413 Request Entity Too Large Content-Length: 430 Connection: close Content-Type: text/html; charset=iso-8859-1
--7925195e-E--
--7925195e-H-- Message: Request body no files data length is larger than the configured limit (131072).. Deny with code (413) Apache-Handler: php5-script Stopwatch: 1381030424350749 727828 (- - -) Stopwatch2: 1381030424350749 727828; combined=48, p1=30, p2=0, p3=3, p4=1, p5=13, sr=0, sw=1, l=0, gc=0 Response-Body-Transformed: Dechunked Producer: ModSecurity for Apache/2.7.3 (http://www.modsecurity.org/). Server: Apache/2.2.25 (Amazon) Engine-Mode: "ENABLED"
--7925195e-Z--
--3ded3b52-A-- [06/Oct/2013:14:33:46 +1100] UlDaGTb8l-4AAFCoHTYAAAAB <my ip address> 64545 <server ip address> 80 --3ded3b52-B-- POST /xmlrpc.php HTTP/1.1 Accept: */* Content-Length: 514188 Accept-Encoding: identity Content-Type: text/xml User-Agent: wp-windowsphone/2.2.0 Host: mokonamodoki.com Connection: Keep-Alive Cache-Control: no-cache
--3ded3b52-F-- HTTP/1.1 413 Request Entity Too Large Content-Length: 430 Connection: close Content-Type: text/html; charset=iso-8859-1
--3ded3b52-E--
--3ded3b52-H-- Message: Request body no files data length is larger than the configured limit (131072).. Deny with code (413) Apache-Handler: php5-script Stopwatch: 1381030425325364 1560720 (- - -) Stopwatch2: 1381030425325364 1560720; combined=48, p1=30, p2=0, p3=3, p4=2, p5=12, sr=0, sw=1, l=0, gc=0 Response-Body-Transformed: Dechunked Producer: ModSecurity for Apache/2.7.3 (http://www.modsecurity.org/). Server: Apache/2.2.25 (Amazon) Engine-Mode: "ENABLED"
--3ded3b52-Z--
--889ef80e-A-- [06/Oct/2013:14:33:52 +1100] UlDaHDb8l-4AAFCqIb4AAAAD <my ip address> 64546 <server ip address> 80 --889ef80e-B-- POST /xmlrpc.php HTTP/1.1 Accept: */* Content-Length: 514188 Accept-Encoding: identity Content-Type: text/xml User-Agent: wp-windowsphone/2.2.0 Host: mokonamodoki.com Connection: Keep-Alive Cache-Control: no-cache
--889ef80e-F-- HTTP/1.1 413 Request Entity Too Large Content-Length: 430 Connection: close Content-Type: text/html; charset=iso-8859-1
--889ef80e-E--
--889ef80e-H-- Message: Request body no files data length is larger than the configured limit (131072).. Deny with code (413) Apache-Handler: php5-script Stopwatch: 1381030428117032 3892958 (- - -) Stopwatch2: 1381030428117032 3892958; combined=49, p1=30, p2=0, p3=2, p4=2, p5=14, sr=0, sw=1, l=0, gc=0 Response-Body-Transformed: Dechunked Producer: ModSecurity for Apache/2.7.3 (http://www.modsecurity.org/). Server: Apache/2.2.25 (Amazon) Engine-Mode: "ENABLED"
--889ef80e-Z--
So, ModSecurity is the culprit! There are two pieces of information we need to take from the last set of logs.
131072 and 413. If you’re even a little bit nerdy like me, you may recognise 131072 as the byte size representation of 128KB (that’s 1024 multiplied by 128). What about this error 413?
ModSecurity has it’s own website and reference manual. The section we are interested in is here. Specifically, the section: SecRequestBodyNoFilesLimit.
By default, the SecRequestBodyNoFilesLimit value in my ModSec configuration file was 131072 (bytes). That is to say, according to ModSecurity, a post submission (a submission of data posted to the web server, not to be confused with a WordPress post entry) can contain no more than 128KB of data. Pretty much any picture or photo will likely be larger than 128KB.
So why is this a problem? Normally, it wouldn’t be. If I was only using the iOS app, I would never have found this out. In short, the two apps work differently.
When you use the iOS WordPress app and add a photo or picture, the ‘image’ is uploaded separately and almost identically to the way you add an image when posting via the normal web based WordPress interface itself. When you complete and submit the post, the ‘post data’ is no where near 128KB (you’d be surprised how much plain text you can fit inside 128KB).
When you use the Windows Phone WordPress app, you are essentially completing a form, with the ability to ‘attach’ an image. That is to say, the Windows Phone WordPress app DOES NOT upload your image separately, but rather attaches it to the plain text (much like an email). This would of course, result in a ‘post data’ size much larger than 128KB.
How did I solve the problem? I changed the SecRequestBodyNoFilesLimit value from 131072 (128KB) to 10485760 (10MB).
# nano /etc/httpd/conf.d/mod_security.conf
Look for the line:
SecRequestBodyNoFilesLimit 131072
and change it to
SecRequestBodyNoFilesLimit 10485760
Save the file and restart Apache.
Now when I attempt to post content containing an image from the Windows Phone WordPress app, it works. Here are the logs:
# tail -f access_log
<my ip address> - - [06/Oct/2013:15:05:49 +1100] "POST /xmlrpc.php HTTP/1.1" 200 587 "-" "wp-windowsphone/2.2.0" <server ip address> - - [06/Oct/2013:15:06:00 +1100] "HEAD /wp-content/uploads/sites/2/2013/10/SavedPicture-201310615531.jpg HTTP/1.0" 200 - "-" "WordPress/3.6.1; http://mokonamodoki.com" <server ip address> - - [06/Oct/2013:15:06:00 +1100] "POST /wp-cron.php?doing_wp_cron=1381032360.2806169986724853515625 HTTP/1.0" 200 - "-" "WordPress/3.6.1; http://mokonamodoki.com" <my ip address> - - [06/Oct/2013:15:06:00 +1100] "POST /xmlrpc.php HTTP/1.1" 200 1324 "-" "wp-windowsphone/2.2.0" <my ip address> - - [06/Oct/2013:15:05:59 +1100] "POST /xmlrpc.php HTTP/1.1" 200 177 "-" "wp-windowsphone/2.2.0" <server ip address> - - [06/Oct/2013:15:06:02 +1100] "HEAD /wp-content/uploads/sites/2/2013/10/SavedPicture-201310615531.jpg HTTP/1.1" 200 - "-" "UnwindFetchor/1.0 (+http://www.gnip.com/)" <server ip address> - - [06/Oct/2013:15:06:02 +1100] "HEAD /wp-content/uploads/sites/2/2013/10/SavedPicture-201310615531.jpg HTTP/1.1" 200 - "-" "UnwindFetchor/1.0 (+http://www.gnip.com/)"
200 is the web server response indicating that the submission was successful.
# tail -f error_log
Nothing! (well, nothing new)
# tail -f modsec_audit.log
Nothing! (well, nothing new)
So. in summary, the Windows Phone WordPress app needs to be updated to include a native method of uploading images (like the iOS app), instead of including them as part of the post data.
Is the change I made to ModSecurity safe? In my opinion. Yes. I am also using Suhosin, and I have other mechanisms in place to aid in the protection of my web server. 10MB is possibly a little high though, so perhaps 5MB (5242880KB) is a little safer.
For reference: the default value (if you don’t see the SecRequestBodyNoFilesLimit line in your ModSec configuration file) is 1048576 (1MB). If you want to change the default, you’ll need to add the line with a value.
References:
Update: 29-12-2013: Today I encountered another issue with ModSecurity. I was trying to upload an image in WordPress via the Web Browser, which kept failing. Checking the ModSec audit log, I found the following:
Producer: ModSecurity for Apache/2.7.3 (http://www.modsecurity.org/). Server: Apache/2.2.25 (Amazon) Engine-Mode: "ENABLED" --f5061060-J-- 5,2876542,"filename.jpg","" Total,2876542 --f5061060-Z-- --2aa91520-A-- [29/Dec/2013:21:23:22 +1100] Ur-4FDb8l-4AAHKWdFsAAAAE 1.2.3.4 51017 5.6.7.8 80 --2aa91520-B-- POST /wp-admin/async-upload.php HTTP/1.1 Host: mokonamodoki.com Connection: keep-alive Content-Length: 2877183 Origin: http://mokonamodoki.com User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryFbNGzpfsilAXOBW5 Accept: */* Referer: http://mokonamodoki.com/wp-admin/post-new.php Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Cookie: wordpress_ff07abefea98ccaf9cd9f927ea2d0ad8=andrew%7C1389521209%7C427d004842c6ff979603fc8832e746e6; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_ff07abefea98ccaf9cd9f927ea2d0ad8=andrew%7C1389521209%7C41857ca5f99870bbd8cb5db4a1948292; wp-settings-2=hidetb%3D1%26libraryContent%3Dbrowse; wp-settings-time-2=1388311632 --2aa91520-I-- name=WP%5f20131228%5f13%5f02%5f07%5fPro%2ejpg&action=upload%2dattachment&%5fwpnonce=5b4fd52907&post%5fid=111 --2aa91520-F-- HTTP/1.1 500 Internal Server Error Content-Length: 625 Connection: close Content-Type: text/html; charset=iso-8859-1 --2aa91520-E-- --2aa91520-H-- Message: Access denied with code 44 (phase 2). Match of "eq 0" against "MULTIPART_UNMATCHED_BOUNDARY" required. [file "/etc/httpd/conf.d/mod_security.conf"] [line "40"] [id "200003"] [msg "Multipart parser detected a possible unmatched boundary."] Action: Intercepted (phase 2) Apache-Handler: php5-script Stopwatch: 1388312596944057 5145407 (- - -) Stopwatch2: 1388312596944057 5145407; combined=62, p1=19, p2=30, p3=0, p4=0, p5=12, sr=0, sw=1, l=0, gc=0 Response-Body-Transformed: Dechunked Producer: ModSecurity for Apache/2.7.3 (http://www.modsecurity.org/). Server: Apache/2.2.25 (Amazon) Engine-Mode: "ENABLED" --2aa91520-J-- 5,2876542,"filename.jpg","" Total,2876542 --2aa91520-Z--
Basically, I had triggered another security policy in ModSecurity. A quick Google for: MULTIPART_UNMATCHED_BOUNDARY indicated I had two options. I could modify the PHP code, or modify the ModSecurity policy. I had no intention of modifying the PHP code (WordPress) so I went for the policy. I looked for this line:
"id:'200003',phase:2,t:none,log,deny,status:44,msg:'Multipart parser detected a possible unmatched boundary.'"
And removed the ‘deny’ option. This allowed the file to still be uploaded, while still logging the exception / event.
"id:'200003',phase:2,t:none,log,status:44,msg:'Multipart parser detected a possible unmatched boundary.'"
Afterwards, I restarted Apache, and files uploaded normally again. I suspect this again, is an instance of the ‘Amazon’ version of ModSecurity being perhaps a little too secure. I wouldn’t exactly recommend this as the ‘best solution’, especially if security is paramount to you. It is, however, a good work around 😉