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

CloudFlare blocking REST API PUT Request (Draft Doesn't Get Saved) (solved by an update from Cloudflare) #2704

Closed
ahmadawais opened this issue Sep 8, 2017 · 104 comments
Labels
Core REST API Task Task for Core REST API efforts [Type] Bug An existing feature does not function as intended [Type] Plugin Interoperability Incompatibilities between a specific plugin and the block editor. Close with workaround notes.
Milestone

Comments

@ahmadawais
Copy link
Contributor

ahmadawais commented Sep 8, 2017

[UPDATE: Cloudflare rolled out a fix for problems with the WP0025B rule 8-Aug-2018, please update.]

I have started to try Gutenberg on a production site and it is not working. The site is new and has no other plugin installed. Looks like the PUT request is not working.

https://i.imgur.com/tElNhnU.png

I am using the latest version of Gutenberg 1.1.0 available in the WP Repo.
I have also tried this on two other sites and same error.
I thought I should report it here?

@toddhalfpenny
Copy link

I have a sneaking suspicion that this is actually not a Gutenberg fault, but a deeper one with the REST api.
Do you have the basic permalinks set? If so, try swapping to a custom permalink and give it another go.
I wrote up some details (with links to tracs etc) when I ran into this symtom.

@ahmadawais
Copy link
Contributor Author

Yeah, I have pretty permalinks set up. I even used a front end post submission plugin that's built with REST API and it works.

@westonruter
Copy link
Member

This may be a duplicate of #1935.

@ahmadawais
Copy link
Contributor Author

@westonruter I'm afraid you're right. 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 Author

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

@rmccue
Copy link
Contributor

rmccue commented Sep 10, 2017

What is the request/response data for the API request?

@JustinSainton
Copy link
Contributor

JustinSainton commented Sep 10, 2017

Tried logging the actual API req/res objects via REST API Log plugin, but no dice. Maybe this is insightful in the meantime?

https://cloudup.com/cL5lSmvZize

@ahmadawais
Copy link
Contributor Author

ahmadawais commented Sep 12, 2017

@rmccue I have the similar log as of @JustinSainton

https://i.imgur.com/hRi9cWJ.png
https://i.imgur.com/ZXcRBgJ.png

It still doesn't work.

@rmccue
Copy link
Contributor

rmccue commented Sep 12, 2017

What is the response payload that accompanies this?

@ahmadawais
Copy link
Contributor Author

ahmadawais commented Sep 12, 2017

@rmccue Thanks for asking the right question. I haven't looked at the response payload.

Turns out CloudFlare is the reason why this is happening.

The response payload is this
https://i.imgur.com/nZWecJR.png

I disabled CloudFlare on one of my domains to check if this works and it did. But this again is a big problem. So many sites are hosted on CloudFlare. I am currently looking into what is causing CloudFlare to ban the IP for adding a draft via Gutenberg. Looks like the Browser Integrity Check where it's banning a headless call. Which shouldn't be banned.

I have no page rules set. Nothing. Looks like default configurations of CloudFlare are banning the API from posting via Gutenberg.

@ahmadawais
Copy link
Contributor Author

ahmadawais commented Sep 12, 2017

Looks like CloudFlare has a globally enabled rule set in WAF — even for free users — that no one can even disable (AFAIK).

Here are the details https://blog.cloudflare.com/protecting-everyone-from-wordpress-content-injection/

https://i.imgur.com/8SbZpYK.png

https://i.imgur.com/EJ7S5O4.png

I wonder if @aaroncampbell could help with this — I can see his comments on the post.

Looking forward!

@JustinSainton
Copy link
Contributor

I'm not using Cloudflare, but this is interesting. I suppose something at the server-level with the host (We're on Siteground) could be blocking PUT requests. I'll ask them about this.

@JustinSainton
Copy link
Contributor

JustinSainton commented Sep 12, 2017

@rmccue And my response payload is the CPanel 403 HTML response, fwiw:

https://cloudup.com/cUJByQ-troP

@rmccue
Copy link
Contributor

rmccue commented Sep 13, 2017

Interesting. Based on this, it seems like it may be a REST API issue with these hosts. We may need to reach out and see about fixing this.

If you switch Gutenberg to use POST instead of PUT, does this still occur? (The API accepts POST everywhere it accepts PUT, but you can also do POST ?_method=PUT to simulate an actual PUT on the backend.)

@ahmadawais
Copy link
Contributor Author

@rmccue How do you propose would one switch from PUT to POST in Gutenberg?

@BE-Webdesign
Copy link
Contributor

BE-Webdesign commented Sep 13, 2017

@ahmadawais

Do the same PUT request you are doing as a POST request instead and add the request arg _method=PUT. This will trigger the x-http-method-override header so that the REST API will know you really mean PUT even though the server can't handle PUT and only wants to use POST requests. You can do the same for DELETE. For Gutenberg you can monkey patch the wp.api requests to use the method override. That would be a temporary solution, while this is figured out for the larger context of how the REST API will be used in this project and other areas of core.

@JustinSainton
Copy link
Contributor

JustinSainton commented Sep 13, 2017

@rmccue Found the source. In our case, Siteground had put the following block in our .htaccess file

    # Block Request Method #
    RewriteCond %{REQUEST_METHOD} ^(connect|debug|delete|move|options|put|trace|track) [NC]
    RewriteRule .* - [F]

This was the root cause of the issue. I hadn't had the opportunity to attempt anything to prove the case, but I assume the DELETE and OPTIONS methods would have also failed.

@rmccue
Copy link
Contributor

rmccue commented Sep 14, 2017

@JustinSainton Nice digging! DELETE, OPTIONS, and PUT all need to be whitelisted for the API (OPTIONS is used by browsers automatically for cross-origin requests).

Was this specific to your site, or a SiteGround-wide thing? If the latter, I'll try and follow up with them.

@JustinSainton
Copy link
Contributor

@rmccue I'm not certain whether or not this is SiteGround-wide or not - I vaguely recall their support team modifying our htaccess file years ago, for some reason. So it may not be that widespread, but certainly feels like something to account for and educate hosts on.

@m
Copy link

m commented Sep 19, 2017

This definitely gives pause when you consider what it means for broader use of the REST API.

First-party use of all the API methods in core in wp-admin (with helpful error messages) would expose and get these fixed very quickly.

@rmccue
Copy link
Contributor

rmccue commented Sep 20, 2017

This has come up once or twice before (IIRC, GoDaddy and WP Engine), and the hosts are usually pretty responsive. Luckily, blocking methods tends to be a thing that only the big hosts do for "protection". Will definitely follow this up with SG to find out if it's a local or global thing.

(A bigger concern there is authentication, which is much worse, but not relevant to built-in stuff like Gutenberg.)

@ahmadawais
Copy link
Contributor Author

@rmccue

A bigger concern there is authentication, which is much worse, but not relevant to built-in stuff like Gutenberg.

Couldn't agree more.

But as Matt suggested, having Gutenberg depend on WP REST API will lay the groundwork for better REST API enabled future for WordPress apps.

@lkraav
Copy link

lkraav commented Sep 28, 2017

This is fairly certainly a duplicate of #2565

@CantonJester
Copy link

@JustinSainton - I'm on SiteGround myself and was kicking the tires on Gutenberg earlier this evening on my development site: After an initial publishing of a post, I cannot update the post for the life of me. While I do not think I had my htaccess file edited the way yours was, I'm wondering if something similar is going on.

Looks like I'm off to open a ticket with SiteGround.

@ahmadawais
Copy link
Contributor Author

Hey, folks! 🙌
I'm closing this issue based on the fact that after working with CloudFlare's support for two months, I've got it fixed and now CloudFlare sites are able to use Gutenberg without any issues.

Feel free to reopen it if there are other similar issues. 🔥

@moyvera
Copy link

moyvera commented Nov 2, 2018

@caraya please keep this thread updated if you have any news. I'm facing the same issue trying to use instagram embedded photos or something from a trusted source. It makes sense to block those requests for cloudflare but should be a section where we can add trusted sources.

[Related to XSS attack]

@bartclaeys
Copy link

bartclaeys commented Dec 18, 2018

Issue seems not resolved yet, I am experiencing it today with the latest Wordpress version:

  • Wordpress: v5.0.1
  • Cloudflare plugin: v3.3.2.
  • Gutenberg plugin: v4.7.0

Update: Solved! Problem was caused by custom rule in .htaccess

@ensemblebd
Copy link

ensemblebd commented Dec 18, 2018

I have read in several places that the fix is to use a paid ssl cert from cloudflare, not their universal free one.
I'm unsure how precisely that correlates.
My site doesn't have an htaccess rule to remove that would resolve this. httpd.conf is standard as well.
And I do not have any firewall rules, page rules, or other non-basic settings in the pro cloudflare account.
Turning off cloudflare's DNS for the site at a whole doesn't even solve the issue.

Am not using the CloudFlare wordpress plugin.

Server response headers still indicate a cloudflare response:

cache-control: no-cache, must-revalidate, max-age=0
cf-ray: 48b2d7269******-DFW
content-encoding: br
content-security-policy: upgrade-insecure-requests;
content-type: text/html; charset=UTF-8
date: Tue, 18 Dec 2018 16:00:09 GMT
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
expires: Wed, 11 Jan 1984 05:00:00 GMT
link: <https://some.website/wp-json/>; rel="https://api.w.org/"
server: cloudflare
status: 404
vary: Accept-Encoding,User-Agent

@ensemblebd
Copy link

ensemblebd commented Dec 18, 2018

For the api request:
POST -> /wp-json/wp/v2/pages/1234 (page/post update operation, note: autosave has the same issue)

Problem is here:
/<root>/wp-includes/rest-api.php for rest_api_loaded() on Line 274
It exits immediately due to:
if ( empty( $GLOBALS['wp']->query_vars['rest_route'] ) )

Therefore the request never executes.
Contents are:

["query_vars"]=>
  array(2) {
    ["attachment"]=>
    string(2) "v2"
    ["pages"]=>
    string(4) "1234"
  }
  ["query_string"]=>
  NULL
  ["request"]=>
  string(24) "wp-json/wp/v2/pages/1234"
  ["matched_rule"]=>
  string(30) ".?.+?/([^/]+)/pages(/(.*))?/?$"
  ["matched_query"]=>
  string(24) "attachment=v2&pages=1234"
  ["did_permalink"]=>
  bool(true)

On a working site, it looks like this:

["extra_query_vars"]=>
  array(0) {
  }
  ["query_vars"]=>
  array(1) {
    ["rest_route"]=>
    string(16) "/wp/v2/pages/857"
  }
  ["query_string"]=>
  NULL
  ["request"]=>
  string(23) "wp-json/wp/v2/pages/857"
  ["matched_rule"]=>
  string(14) "^wp-json/(.*)?"
  ["matched_query"]=>
  string(33) "rest_route=/wp%2Fv2%2Fpages%2F857"
  ["did_permalink"]=>
  bool(true)

Am working on digging deeper. Would appreciate any insights from those that know what they're doing.

  • Edit:
    Solution was to modify the wp_options database table value for option_name = 'rewrite_rules', simply moved the offending serialized regular expression below the position in the array of the wordpress default api routes.
    I tried flushing, both using this, and this, and by using the frontend permalinks [Save Changes] op. To no avail. Had to manually modify it myself in the database.

@mike-pt
Copy link

mike-pt commented Jan 15, 2019

I'm not sure what changed but I had to whitelist a few rules and yet this still is getting blocked now it the following rules::
image

And was worst before:
image

I can't simply go about disabling every of this rules, most are not even listed as possible false positives :/

@mike-pt
Copy link

mike-pt commented Jan 15, 2019

Aslo the draft is autosaved, its only updating that fails now

@caraya
Copy link

caraya commented Jan 21, 2019

@mike-pt do the Cloudflare error logs show anything? how about the server logs? Check that before disabling rules as it may not be the reason why it's not working.

Try disabling your plugins and test if it works.

If it does try activating the plugins one by one until it stops working.

If it doesn't then developers will need logs from Cloudflare and your server to see if they can troubleshoot it further.

@mike-pt
Copy link

mike-pt commented Jan 22, 2019

Error logs from cloudflare? I don't think they provide that, however I have pasted the screenshot from cloudflare blocking this, and I do see a 403 on the browser none of this are the WP WAF rules, but OWASP, and a lot of those are not common false positives!

This as to do with how gutenberg uses the JSON API when updating posts, so maybe the problem is on the API side still it hits at least the rules I've pasted above! I don't think plugins have anything to do with this, since its clear that the request is made when using gutenberg, as a workaround the classic editor is in use, no issues there!

@caraya
Copy link

caraya commented Jan 24, 2019

It's the Web Application Firewall event log, not error log, my bad.

  • Under Firewall scroll down
  • Select Web application firewall
  • Look at the Firewall Event Log.
  • Does it report anything under that tab that doesn't appear in the images you pasted?

If the JSON API is not working that's usually a WAF issue, not IP firewall issue. At least it was for me before the Gutenberg team solved it. It may also be related to PHP Security plugins that are blocking things without you realizing they are (this has also been reported as an issue in this and other threads)

@mike-pt
Copy link

mike-pt commented Jan 24, 2019

Yeah and that's exactly what I've pasted above... I never mentioned IP blocks only WAF rules.

This still happens, I have to disagree on the PHP security plugins cause the screens I posted are from Cloudlfare WAF log and its clearly blocking things, based on a few OWASP rules (note that none are from the Wordpress specific rules in this screenshot)

@mike-pt
Copy link

mike-pt commented Jan 24, 2019

@caraya I feel like you took this too personal, I'm not rejecting any solutions (but so far no solution was really provided, but you did provide useful opinions on possible issues that could be related, and let me thank you for that).

With that sad if I disagree with something and provide an explanation as to why I don't see why that means I'm disagreed in every possible solution, and if it felt like so that was surely not my intention, I do have the right to disagree and I think it would be unfair to not be honest about it, now obviously there needs to be a reasoning for it and I did provide it.

Now still back to the PHP security Plugins, the screens I posted are from cloudflare, NOT wordpress, cloudflare is blocking the request based on the rules I've posted as a screenshot, the request doens't even get to the host, so how could a php security plugin do it?

I'm happy to share more examples / more details on what cloudflare is blocking to try to understand the problem.
Cause really my question is only about WHY this requests are blocked and match this many WAF rules, is many cloudflare being nuts and the plugin is not really "doing anything wrong" or are this actually legit and the way gutenberg does the update (via the API should be more safe) ?
That's the real question here, we are still in the phase where I'm just want to clarify why cloudflare blocks it (which again might even be a cloudflare issue not gutenberg) .

P.S. If you felt offended at any point it was honestly never my intention, I simply was replying directly and honestly to you're comments, I hope this helps clarify things!

@caraya
Copy link

caraya commented Jan 24, 2019

@mike-pt

If you follow these and other issues with the plugin not updating you'll see that there are multiple reasons why this happens. Your screen is not what I expect to see when I troubleshoot this type of issues and I don't think I mentioned you're disagreeing, it's your right :).

Since you've confirmed that this is the web application firewall then, to me, it's a new error but, like the others, I'm guessing it doesn't like the way Gutenberg is mixing comments and JSON and considers it an attempt at SQL injection. So yes, it's likely that new modsecurity rules are making it not work but I'm surprised other people are not having the same issue... it still may be something being injected between your client and the firewall (ads, malware, long etc)

@pento

This is a new type of WAF error in Cloudflare, It's reporting a different type of error for protection against SQL injection but it's none of the previously reported errors. It is triggering OWASP core rules, specifically something in the APPLICATION-ATTACK-SQLI group of rules (Github link),

Don't know why it would be triggering now, but Cloudflare uses OWASP as their default module

@mike-pt
Copy link

mike-pt commented Jan 24, 2019

To clarify that screen is form:

Firewall Event Log

Requests affected by both IP Firewall and Web Application Firewall (WAF) rules.

[From Cloudflare] After selecting the corresponding block.... I did crop it to filter out the IP etc... and simply show the "triggered/matched" rules.

But yeah what surprised me is that cloudflare lists APPLICATION-ATTACK-SQL (and this didn't not happen in past releases, unfortunately I can't say precisely when, I test gutenberg when it was beta and it trigger some cloudflare WordPress specific waf rules, which back then was their own issue and they fixed ) and after updating this WP install, changing form classic editor to Gutenberg this start happening, but with the rules that are posted, and as you say are core OWASP rules!
So it seems to be a bit more serious (or maybe cloudflare bug!?!), so I defiantly appreciate if someone can look into it and make sure all is good. And I'm also surprised no one else commented with the same results yet.

Also I haven't tried gutenberg again after the day I posted this, it was disabled in the prod but I should probably check again if this is still happening to clear out the possibility of a cloudflare bug analyzing this.

@jordif
Copy link

jordif commented Feb 26, 2019

Hi,

I'm facing the same issue with Cloudflare and the OWASP ruleset. If i turn the OWASP rule set off (while keeping the Cloudflare rule set on), everything works fine.

I've done some tests adjusting the OWASP sensitivity (high/medium/low): the longer the post content, the greater the chances of the request being blocked.

I haven't really tested this super thoroughly, but I also think that having a lot of markup increases the chances. I had a page with a table and many links in it. I could not update it (OWASP rule was triggered). After cleaning it up a little bit (removing target="_blank" an rel="noopener" from the links) it did get saved.

Cheers,

@jordif
Copy link

jordif commented Feb 26, 2019

I have noticed something else: autosaves do work (and the json is almost the same), it's the publish/update request that gets blocked...

@mike-pt
Copy link

mike-pt commented Feb 26, 2019

@jordif out of curiosity which rules does it it for you?

@jordif
Copy link

jordif commented Feb 27, 2019

@mike-pt Mainly "SQL Injection" and "XSS attack" rules.

It seems the OWASP team are already aware of this and working on a solution.

SpiderLabs/owasp-modsecurity-crs#1232

So I'm afraid we'll have to wait (and whitelist IPs in the meantime)

@ausworkshop
Copy link

Hi Guys, any news on this?
I haven't been able to edit or preview since Guttenberg came along and really messed up my life.
I'm with Cloudflare and WpEngine, was chatting to them for about an hour last night then today found this post. In the meantime I still have no idea how to fix or if it will one day fix itself. So after 15 years with my website I now can no longer edit it or update it but hey at least it's still working for now!

I have a business to run, it relies entirely on my website working and don't have time for all this tech stuff slowing me down all the time. I've almost lost hope in WordPress altogether after the trouble I'm having now and I really can't afford to have my site totally re-built on another platform. It's times like these I wish I was still using a simple Godaddy builder or something. I can't afford the amount of time I'm spending on WordPress just to keep it working. I don't ask too much, just a simple site that I can edit and update. What year are we living in?

Any advice or direction on what I need to do or who I need to reach out to for help would be appreciated. Or should I just go back to classic and forget about Guttenberg until it works one day with my existing setup? If Cloudflare are still working on it then how much longer will it take?

@ensemblebd
Copy link

ensemblebd commented Mar 21, 2019

All this banter about the politics of problem solving and who is to blame is ridiculous.
This is GitHub, not youtube.
People writing drivel on here does nothing but hurt people like @ausworkshop

The problem is that Gutenberg has an absolutely useless generic error message, offering a wide array of solutions.

Identification of issue

1.) Identify the network request in Chrome developer console (big red line).
2.) Copy the url it requested into your web browser.
3.) 500? 403? 401?
4.) Is it wordpress derived, or external (cloudflare)?
4.1.) Look at Step 1's network response headers. Do you see Apache, PHP, or IIS headers from your server? How about the CF ray?
--> If no: Turn off cloudflare (DNS level or global switch on dash, and disable firewall). Recheck 1-5.
--> If yes: Problem very likely has nothing to do with cloudflare (as was my case).
Why not edit your index.php and throw out a header() call followed by a die() temporarily to verify (against same previously failed url)?
That by itself verifies your entire host apparatus (web.conf / htaccess rewrite, cloudflare dns + firewall + routing, php)
For POST op requests, use Postman. Same process.

Recap

To clarify, this is a closed issue, and you likely will not find help on here.
Plus the original issue was resolved long ago.

But the above generic self-help debugging steps are a first step to identifying the actual problem for Gutenberg's useless error message.
Good luck

@ausworkshop
Copy link

Thanks ensemblebd, I've passed your debugging steps on to WPEngine who were looking into it further for me and have opened a support ticket. I'll get back on here and let you know if I find out what they did to solve it.

@chrissy-dev
Copy link

@ausworkshop Did you ever get this sorted? I've been working with WPEngine for over a month on the exact same problem.

@ausworkshop
Copy link

I'm not sure if it was ever fixed sorry, don't think so, I've been struggling along with the classic editor, stopped using Gutenberg months ago but I am planning to build a whole new site using Beaver Builder, even that I'm struggling with. Sick of trying to get my head around all this crap. Here I am at midnight trying to work out how to import and display custom post types in a new theme. I had to hire someone in the end. I'm hopeless with all this and it never seems to get easier, just more confusion and more expenses. Was quoted $6k to fix my site, I refused so am doing it all myself. Wish me luck! :) Have fun people.

@chrissy-dev
Copy link

chrissy-dev commented Sep 14, 2023

@ausworkshop Who's your host? I'm with AWS and had to add /wp-admin/admin-ajax.php to the Cloudfront WAF whitelist.

@ausworkshop
Copy link

I'm with WPEngine, not sure what was done to fix this as it was so long ago but I am still getting used to using Gutenberg. I had to hire someone from Codeable back in May as I found it difficult to continue to work things out by myself. It seems the more things 'improve' with updates and upgrades in this world the less I am able to figure out by myself.

@chrissy-dev
Copy link

I'm with WPEngine, not sure what was done to fix this as it was so long ago but I am still getting used to using Gutenberg. I had to hire someone from Codeable back in May as I found it difficult to continue to work things out by myself. It seems the more things 'improve' with updates and upgrades in this world the less I am able to figure out by myself.

Glad you got it sorted in the end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Core REST API Task Task for Core REST API efforts [Type] Bug An existing feature does not function as intended [Type] Plugin Interoperability Incompatibilities between a specific plugin and the block editor. Close with workaround notes.
Projects
None yet
Development

No branches or pull requests