Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update post or page results in a 406 Not Acceptable error #1935

Closed
2 tasks
maxxwv opened this issue Jul 18, 2017 · 29 comments
Closed
2 tasks

Update post or page results in a 406 Not Acceptable error #1935

maxxwv opened this issue Jul 18, 2017 · 29 comments
Labels
[Status] Needs More Info Follow-up required in order to be actionable.

Comments

@maxxwv
Copy link

maxxwv commented Jul 18, 2017

Issue Overview

In version 0.5.0 on WordPress 4.8 (release version and nightly build as of 7/18/17), saving a new post or page works fine, but any attempt to update an existing post results in the server returning a 406 Not Acceptable error.

Steps to Reproduce (for bugs)

  1. Select 'Gutenberg' from the quick edit links under a post title in the list table
  2. Make any changes
  3. Click 'Update'

Testing on the twentyseventeen theme with no other plugins enabled. Seems to be browser anostic, as I've tested in Firefox, Chrome, and Safari.

Expected Behavior

Should save the modifications to the post or page.

Current Behavior

Server returns a '406 - Not Acceptable' error and site displays an 'Updating failed' notification.

Possible Solution

Related Issues and/or PRs

Seems like it could be a recurrence of issue 1416.

Todos

  • Tests
  • Documentation
@westonruter
Copy link
Member

The problem is most likely that your server is rejecting PUT requests. When you create a new post, it will send a POST request to /wp/v2/posts. When you update an existing post, then it sends a PUT request to /wp/v2/posts/:id.

The WP REST API does provide a workaround for this problem, in that you can send a POST request with a _method=PUT query parameter to override the method, or via the X-HTTP-Method-Override request header, but the WP API Backbone client doesn't provide a way to opt-in to this.

@karmatosed
Copy link
Member

I am unable to replicate this @maxxwv - are you using a particular browser? I ask as really would like to try and recreate this.

@karmatosed karmatosed added the [Status] Needs More Info Follow-up required in order to be actionable. label Jul 19, 2017
@maxxwv
Copy link
Author

maxxwv commented Jul 19, 2017

@karmatosed - Tried in Firefox 54.0.1, Chrome 59.0.3071.115, and Safari 10.1.1 on Mac - haven't had a chance to test it on Windows but will be able to get to that tomorrow.

@westonruter
Copy link
Member

It's surely a server issue not a browser issue.

@westonruter
Copy link
Member

@adamsilverstein has there been any discussion about detecting PUT request support on the server, and if so, having the Backbone client use POST with the _method override?

@maxxwv if you can DM me on WordPress Slack the URL for the site that is having the problem, I might be able to confirm if the PUT method is the problem.

@maxxwv
Copy link
Author

maxxwv commented Jul 20, 2017

@westonruter - I agree it's probably not a browser issue, but in an attempt to knock out as much noise as possible, I just tried in Firefox 54.0.1, Chrome 59.0.3071.115, IE11 (11.438.45063.0), and Edge (40.15063.0.0) on Windows 10 and had the same results - except for IE11. IE11 gave me a JavaScript error - "Unable to get property 'getItem' of undefined or null reference' in wp-api.min.js (1, 8895) when trying to access Gutenberg through either the menu sidebar admin menu or the quick link option on the posts page.

I'll check with the higher-ups about granting you access to the sandbox I'm testing on, but I can tell you it's a basic Inmotion VPS that we use for testing and development. I want to say it's running CentOS (6 maybe?) and PHP 5.4.x, but don't quote me on that - it's getting late after a long day here... As I said in the initial post, it's the twentyseventeen theme, Gutenberg is the only active plugin on the site, and I've switched from released 4.8 and nightly build just to see if that had any effect. The install lives in a sub-directory if that could make a difference (can't imagine how it would, but again less noise is better).

@maxxwv
Copy link
Author

maxxwv commented Jul 20, 2017

So it's definitely a server issue. Using the plugin in a WP install set up on a local Ubuntu server, updating works fine.

@westonruter
Copy link
Member

@maxxwv the same or related issue was posted in Trac: https://core.trac.wordpress.org/ticket/40886

Can you try the patch there and see if that fixes your issue?

Do you have “pretty permalinks” enabled?

@nylen
Copy link
Member

nylen commented Jul 25, 2017

@adamsilverstein has there been any discussion about detecting PUT request support on the server, and if so, having the Backbone client use POST with the _method override?

It is also always valid to use POST instead of PUT for updates.

Deletes are a little more tricky. It seems like kind of a shame to always send a method override for DELETE requests - I thought we were past the times of being restricted to GET and POST methods only.

@maxxwv
Copy link
Author

maxxwv commented Jul 25, 2017

@westonruter - My server is running HTTP/1.1 on Apache 2.2.29, and post name permalinks are enabled on the site.

@LinnightL
Copy link

LinnightL commented Jul 27, 2017

I had the same issue with my InMotion VPS hosting - impacting all my websites

After trying every possible researched solutions, restoring backups, I eventually found downloaded versions were working on local xampp - had to be server related so I finally contacted InMotion: cPanel/Security/ModSecurity - Disable

If concerned that you are reducing security then just turn it back on again after updating pages/posts.

  • yup - that is three days I will never get back...

Turning off MOD_SECURITY completely seems drastic/risky when I assume the issue probably lies with just one rule within. I did find:
Find and disable specific ModSecurity rules
http://www.inmotionhosting.com/support/website/modsecurity/find-and-disable-specific-modsecurity-rules

but looking into my WHM I see I can turn individual rules on and off within edit mode of ModSecurity™ Vendors and within the Rule Set in ModSecurity™ Tools but I am reluctant to go further as I am not sure how to identify the problem rule.

I will put these questions to InMotion and pass on whatever info I find.

@maxxwv
Copy link
Author

maxxwv commented Jul 27, 2017

@LinnightL - thanks for the information! I have to admit, though, not only do I think it's drastic to expect users to disable mod_security for their WP installs, I wonder how many every-day users will know they need to, let alone how to. No offense to the general public, but the point of WP is to allow anyone at any level to create and run a website or blog.

Given the universal server support for POST operations - which, as @nylen points out are valid for both update and insert operations - I think it's a reasonable request that the new system at least check for PUT support and switch to POST if and when necessary. If not just use POST requests until such time that PUT support is widespread enough to rely on, then change the update request method silently in the background.

@LinnightL
Copy link

LinnightL commented Jul 27, 2017

I have to admit I knew nothing about ModSecurity or the existence of it until a day ago. I know not much more as yet.

InMotion were helpful, tested and checked apache logs to come back tonight with several ModSecurity rules that were being triggered.

I can obviously now go in to WHM ModSecurity Tools and disable them one at a time to see what is delivering the false positive. I would rather turn off a single rule than turn off ModSecurity completely. One of my sites is a shop with several people contributing regular updates and I am not going to dish out cPanel access with instructions to turn ModSecurity off and on before and after website updates.

This impacted 6 of my websites. As yet I am not sure of the change that started this. I first noticed this on the 14th July. For one of my lesser frequented sites (up to date Twenty Fifteen theme Version: 1.8) I turned off everything and the problem still existed. Was it a wordpress update or updates for WHM & cpanel around that time? Is it particular to InMotion VPS setup or more widespread? In my search for answers I did come across many asking questions, nearly all were attempting to alter their wordpress installs and not succeeding.

I have just located
Handling False Positives with the OWASP ModSecurity Core Rule Set
https://www.netnea.com/cms/apache-tutorial-8_handling-false-positives-modsecurity-core-rule-set/

...the start of much reading...

@LinnightL
Copy link

I have to give a thumbs up for InMotion here. They came back today with even more information which offered more clarity - there is a possibility that this could relate to recent rules pushed out by OWASP - so if this is the case and the issue impacting as many as I suspect then hopefully there will be an update to these rules soon. I vaguely recall there was a security update offering in my WHM recently that I processed.

They also provided a list of how many times 8 of my domains triggered the same few rules. What is intriguing is that www and non www variants of the domains triggered the rules, also parked subdomains (no content) and simple non-wordpress html sites.

So in my case it is nothing to do with WordPress, WordPress plugins, WordPress themes and it certainly does appear to be with OWASP ModSecurity rules which is beyond InMotion's control. InMotion have been prompt and helpful to my requests.

@westonruter
Copy link
Member

The WordPress REST API does not require the use of the HTTP PUT method to make updates to a given post. It has a mechanism to workaround such server environments which don't support PUT. You can make a POST request with a _method=PUT query param or via the X-HTTP-Method-Override header: https://github.com/WordPress/wordpress-develop/blob/43fc92e4a9077d1c15740d2a143d92e3c1ac0151/src/wp-includes/rest-api/class-wp-rest-server.php#L307-L316

The problem is that the WP-API Backbone client library doesn't know that it needs to use this alternate method for your given server environment. I'm not sure of the best way to detect support for PUT before needing to make such a request, other than to try to make a PUT and if it fails to then re-try with a POST and the method override.

@nylen
Copy link
Member

nylen commented Jul 31, 2017

InMotion were helpful, tested and checked apache logs to come back tonight with several ModSecurity rules that were being triggered.

@LinnightL Which specific rules are these?

The problem is that the WP-API Backbone client library doesn't know that it needs to use this alternate method for your given server environment.

Note we don't know that this is actually a POST vs PUT issue. It's a different issue from the one reported earlier in the thread.

@LinnightL
Copy link

Turning ModSecurity off and on quickly proved the problem lay there for me. Since this began for me I have read this is a fairly common problem. The most offered solution is to turn it off completely which I am certainly not going to do.

@nylen
941100 (XSS Attack Detected via libinjection)
941160 (NoScript XSS InjectionChecker: HTML Injection)
949110 (Inbound Anomaly Score Exceeded (Total Score: 15)) and
980130 (Inbound Anomaly Score Exceeded (Total Inbound Score: 15 - SQLI=0,XSS=15,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0): NoScript XSS InjectionChecker: HTML Injection)

@maxxwv
Copy link
Author

maxxwv commented Aug 3, 2017

Confirming the issue persists on 4.8.1 with Gutenberg 0.6.0.

Note we don't know that this is actually a POST vs PUT issue. It's a different issue from the one reported earlier in the thread.

@nylen - I thought we were pretty convinced this was a POST vs PUT server setup issue?

I'm not sure of the best way to detect support for PUT before needing to make such a request, other than to try to make a PUT and if it fails to then re-try with a POST and the method override.

@westonruter - I'm sure it's been discussed, but would it be possible during installation of the plugin (or core when the plugin is rolled in) to attempt a simple PUT to the database, examine the return headers, then store the results in the options table? Load that value into (for instance) the global database object and use it from there.

Inserting a default option_value of 'POST' for option_name 'update_method' (or whatever makes sense), then attempting to update that option_value to 'PUT' using PUT method would allow the system to completely ignore the return headers - if the PUT is successful, the update is taken care of and the logic sorts itself out.

@nylen
Copy link
Member

nylen commented Aug 3, 2017

@maxxwv the POST vs PUT thing is a separate issue, related to internal behavior of the nginx web server. It's possible that switching to POST would resolve your issue too, but that would be for a different reason.

To help us track this down further, who is your hosting provider, and what type of server do you have with them?

I am generally not a fan of having to do a "trial" PUT request. There are many things that can go wrong there, including the "trial" request succeeding but follow-up requests failing. We would also want to do a trial DELETE request for the same reason.

@LinnightL
Copy link

@nylen maxxwv mentioned "it's a basic Inmotion VPS"
#1935 (comment)

This is why I weighed in. I had the same issue on an Inmotion VPS.

Looking up the Inmotion WHM cpannel change log:
Change Log for 63.9999.74Entry: 2017-06-09, 01:30 (UTC)
Fixed case CPANEL-10477: Update WHM to use the new ModSecurity ruleset.

I ran that update just before my issues started.

@maxxwv
Copy link
Author

maxxwv commented Aug 11, 2017

Sorry about the delay in response. Confirming the problem still exists in 0.7.1.

@nylen - A little more info, it's a VPS-2000S account at InMotion running Apache 2.2.29, PHP 5.4.36, and MySQL 5.6.35. I don't remember which flavor of Linux it's running, but can find out if it would help.

I've not mucked with the settings, and haven't touched the ModSecurity rules.

And thanks for the reminder - I'd forgotten the other issue you'd linked to earlier was related to nginx.

@LinnightL
Copy link

LinnightL commented Aug 11, 2017

@maxxwv - you are basically running an identical platform to me at inmotion. It will take two minutes to see is modsecurity is causing the issue. Go to a cpanel of any account with the issue. Security/ModSecurity then turn it off. Try to save a page that was previously failing - if it saves correctly then you have your answer - same modsecurity issue I have. Turn the modsecurity back on when finished.

I am very curious - if your issue is the same I would like to take this information back to inmotion techs.

@maxxwv
Copy link
Author

maxxwv commented Aug 11, 2017

@LinnightL - just tested on the sandbox sub-domain and mod security certainly appears to be the culprit. Tried to save, got the 406 error, turned off Mod Security and saved - success! Turned Mod Security back on, tried to save again, and boom - Error 406 once again.

@LinnightL
Copy link

LinnightL commented Aug 12, 2017

@maxxwv can I also suggest you take this info back to inmotion's techs as well - and give them a link to this forum thread - as I have done.

There has to be a lot more people trying to understand this issue as well. It is either a fault with the OWASP ruleset or something to do with the update mentioned below.

The issue came about after an update
Looking up the Inmotion WHM cpannel change log:
Change Log for 63.9999.74Entry: 2017-06-09, 01:30 (UTC)
Fixed case CPANEL-10477: Update WHM to use the new ModSecurity ruleset.

I have had great service from inmotion - so this is not a criticism - but "it must be a faulty ruleset from OWASP" is actually not my issue to resolve.

@ahmadawais
Copy link
Contributor

ahmadawais commented Sep 9, 2017

As Weston mentioned, I am facing a similar issue #2704. The VPS is custom built with EasyEngine script.

Looks like there's an issue with the PUT request as it returns a 403.

PUT https://a2podcast.com/wp-json/wp/v2/posts/44 403 ()

for

load-scripts.php?c=0&load[]=jquery-core,jquery-migrate,utils,underscore,backbone,wp-util,wp-backbone,media-models,plupload,wp-plupload,jquery-ui-core,jquery&load[]=-ui-widget,jquery-ui-mouse,jquery-ui-sortable,mediaelement,wp-mediaelement,media-views&ver=4.8.1:4

@ahmadawais
Copy link
Contributor

If I log XMLHttpRequests then this is the message I get.

XHR failed loading: PUT "https://a2podcast.com/wp-json/wp/v2/posts/46".

screenshot 2017-09-09 13 03 57

@maxxwv
Copy link
Author

maxxwv commented Sep 10, 2017

Just got a chance to test version 1.1.0 and updating a page is working now on the server described above, with no changes to the actual server. Thanks to all involved!

@karmatosed
Copy link
Member

Thanks from for testing and lad it's now working.

@megphillips91
Copy link

Alrighty, I rarely comment, and this is an oldy - but I've spent the past two days on this sucker and here is the solution (provided by Elena at InMotion so major props to Elena and InMotion!!!) ==> you MUST manually set the User Agent.

 `$headers = array('Content-type' => 'application/json', 'user-agent'=>$_SERVER['HTTP_USER_AGENT']);`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Status] Needs More Info Follow-up required in order to be actionable.
Projects
None yet
Development

No branches or pull requests

7 participants