WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.57k stars 4.23k forks source link

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

Closed ahmadawais closed 6 years ago

ahmadawais commented 7 years ago

[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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

This may be a duplicate of #1935.

ahmadawais commented 7 years ago

@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 commented 7 years ago

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 commented 7 years ago

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

JustinSainton commented 7 years ago

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 commented 7 years ago

@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 commented 7 years ago

What is the response payload that accompanies this?

ahmadawais commented 7 years ago

@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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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

https://cloudup.com/cUJByQ-troP
rmccue commented 7 years ago

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 commented 7 years ago

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

BE-Webdesign commented 7 years ago

@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 commented 7 years ago

@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 commented 7 years ago

@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 commented 7 years ago

@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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

@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 commented 7 years ago

This is fairly certainly a duplicate of #2565

CantonJester commented 7 years ago

@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 commented 7 years ago

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. πŸ”₯

ahmadawais commented 6 years ago

I'd like to reopen this issue as the CloudFlare basic security (with default setup) is blocking Gutenberg! It just doesn't work.

image image

I have an open support ticket at CoudFlare but need more support there to push it to the priority list.

pento commented 6 years ago

@ahmadawais: Would you be able to test if the change in #4396 fixes this problem on your CloudFlare setup?

pento commented 6 years ago

On digging through some of the history for the security issue that CloudFlare's WP0025B rule blocks, I don't think #4396 will work to fix it. I'll look into it some more.

ahmadawais commented 6 years ago

@pento Sure, I can test that if you want?

And you're right that it's a rule called WP0025B by CloudFlare that's doing this β€” I wrote about it in a comment above. It was fixed after a lot of back and forth between me and the CloudFlare Engineering team. I provided them with the HAR file and all. But it's again like that.

🎯 I think if more people than just me would talk to CloudFlare we'll be able to get it fixed for a millions of sites out there that use CloudFlare with WordPress. Otherwise, WP REST API is potentially broken when we are using CloudFlare.

Let me know how I can help you proceed! πŸ’―

pento commented 6 years ago

@ahmadawais: It's worth testing, just to be sure. We're reaching out to a few people we know at Cloudflare, to see if they can help address it.

ahmadawais commented 6 years ago

@pento Sure thing.

❌ Gutenberg Plugin

So, I went ahead and installed the latest Gutenberg plugin from WP.org repo at one of my blogs. Then I went the Gutenberg menu in the left-bottom and tried to update the post, by clicking Save Draft and this is what I got.

http://on.ahmda.ws/omCo/c http://on.ahmda.ws/ollg/c http://on.ahmda.ws/omEk/c

❌ CloudFlare

At CloudFlare this is what got triggered this time

http://on.ahmda.ws/om4N/c

❌ After Applying the Patch

And I tried the same steps after applying the patch in #4396 no luck. It's the same response as above. This error is prominent when you're updating a prewritten post, earlier (before CloudFlare fixed it) it was much more worse. Though, I can create new posts right now just fine, after that it gets blocked when I try to save the draft. β€” CloudFlare's trying to test the user with Google reCaptcha in the response of an API call is bad.

Event Details

Here're the exported event details from CloudFlare (minus my domain name). ```json { "id": "3db5cdc34fdc9df7", "country": "PK", "ip": "182.181.23.252", "protocol": "HTTP/2", "method": "POST", "host": "****.com", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36", "uri": "/wp-json/wp/v2/posts/11798", "request_duration": 0, "triggered_rule_ids": [ "950001", "950901", "958011", "959073", "960024", "973300", "973304", "973306", "973308", "973333", "973334", "973335", "973338", "981133", "981136", "981176", "981231", "981243", "981245", "981246", "981248", "981256", "981257", "981301", "981310" ], "action": "challenge", "cloudflare_location": "ATH", "occurred_at": "2018-01-11T06:26:18.76Z", "rule_detail": [ { "id": "960024", "description": "OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION-ARGS:JSON_ARG_0002=\n
" }, { "id": "973304", "description": "OWASP_CRS/WEB_ATTACK/XSS-2000000408_136=src=" }, { "id": "973306", "description": "OWASP_CRS/WEB_ATTACK/XSS-2000000408_136=style=" }, { "id": "973308", "description": "OWASP_CRS/WEB_ATTACK/XSS-ARGS:JSON_ARG_0002=background-image:" }, { "id": "973335", "description": "OWASP_CRS/WEB_ATTACK/XSS-2000000412_217=\",\"align\":\"wide\"} -->

Of Mountains & Printing Presses

Of Mountains & Printing Presses

T" }, { "id": "960024", "description": "OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION-ARGS:JSON_ARG_0002" } ], "rule_message": "Inbound Anomaly Score Exceeded (Total Score: 98, SQLi=24, XSS=45): Last Matched Message: IE XSS Filters - Attack Detected.", "type": "waf", "rule_id": "981176", "zone_id": "5ea7ee45ad8481b404d5fb3e3cda83da", "cookie": "" } ```

pento commented 6 years ago

Cool, thanks for testing that. Having the rule name that was triggered is a useful bit of information.

ahmadawais commented 6 years ago

Event Details

Here're the exported event details from CloudFlare (minus my domain name). (CLICK TO EXPAND!) ```json { "id": "3db5cdc34fdc9df7", "country": "PK", "ip": "182.181.23.252", "protocol": "HTTP/2", "method": "POST", "host": "****.com", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36", "uri": "/wp-json/wp/v2/posts/11798", "request_duration": 0, "triggered_rule_ids": [ "950001", "950901", "958011", "959073", "960024", "973300", "973304", "973306", "973308", "973333", "973334", "973335", "973338", "981133", "981136", "981176", "981231", "981243", "981245", "981246", "981248", "981256", "981257", "981301", "981310" ], "action": "challenge", "cloudflare_location": "ATH", "occurred_at": "2018-01-11T06:26:18.76Z", "rule_detail": [ { "id": "960024", "description": "OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION-ARGS:JSON_ARG_0002=\n
" }, { "id": "973304", "description": "OWASP_CRS/WEB_ATTACK/XSS-2000000408_136=src=" }, { "id": "973306", "description": "OWASP_CRS/WEB_ATTACK/XSS-2000000408_136=style=" }, { "id": "973308", "description": "OWASP_CRS/WEB_ATTACK/XSS-ARGS:JSON_ARG_0002=background-image:" }, { "id": "973335", "description": "OWASP_CRS/WEB_ATTACK/XSS-2000000412_217=\",\"align\":\"wide\"} -->

Of Mountains & Printing Presses

Of Mountains & Printing Presses

T" }, { "id": "960024", "description": "OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION-ARGS:JSON_ARG_0002" } ], "rule_message": "Inbound Anomaly Score Exceeded (Total Score: 98, SQLi=24, XSS=45): Last Matched Message: IE XSS Filters - Attack Detected.", "type": "waf", "rule_id": "981176", "zone_id": "5ea7ee45ad8481b404d5fb3e3cda83da", "cookie": "" } ```

pento commented 6 years ago

Oh, that's glorious. I don’t think this is WP0025B. I think the raw blocks look too much like a combination of SQLi and XSS attacks, and it triggers some threshold.

ahmadawais commented 6 years ago

Exactly! Can also be related to the blocks + PUT request combination.

WP0025B is what I think they fixed when I first reported it. Which is why I can create a simple post with one para and as it grows in complexity CloudFlare blocks it.

jeffpaul commented 6 years ago

This ticket was mentioned in Slack in #core-editor by jeffpaul. View the logs.

JustinSainton commented 6 years ago

I see this title change and just want to hearken back to my comment: https://github.com/WordPress/gutenberg/issues/2704#issuecomment-329565058

This seems to be common enough on Cloudflare, but it's definitely not exclusive to Cloudflare.

jeffpaul commented 6 years ago

This ticket was mentioned in Slack in #core-editor by jeffpaul. View the logs.

robbiet480 commented 6 years ago

I've escalated this ticket internally at Cloudflare (i'm a customer). They should be getting deeper into it shortly and may be able to provide some generic feedback.

caraya commented 6 years ago

FWIW, I had a ticket opened with Cloudflare since February. I got the following message yesterday

Thanks for your patience here - I just wanted to let you know our WAF has been updated to specify more compliant default WordPress protections that should now allow the newer versions of the WordPress editor to operate without triggering false positives.

It worked for me after I deleted all my firewall rules. when working from an IP address that had exhibited problems.

I'd suggest you try it after purging the cache.

pento commented 6 years ago

Awesome, thanks for the update, @caraya!

ahmadawais commented 6 years ago

Seems to e working for me. I'll keep testing :)

roylindauer commented 6 years ago

I have installed the latest version of Gutenberg (3.4.0) and this issue still exists. Cloudflare is blocking wp-json requests. I am unable to use the Preview functionality.

Specifically getting the following in the firewall activity logs:

"Prevent abuse against wp-json api Type B"

I have submitted a ticket to Cloudflare.

roylindauer commented 6 years ago

Cloudflare has responded.

It looks like I have to apologize because I may have been mistaken. After having a chance to follow up with our Firewall team here, it appears that the this particular rule cannot be bypassed using Page Rules.

The only way it appears that this particular rule can be bypassed is by specifically disabling it after upgrading to a paid Cloudflare Plan either Professional, Business or Enterprise.

Once you have upgraded your account, you would be able to disable the firewall rule by going to your Firewall page >> selecting Web Application Firewall >> under Cloudflare Rule Set >> click on Cloudflare Wordpress >> Select the rule WP0025B >> set to Disable

I was hoping to find a way to help you resolve this issue without needing to upgrade your account, but it appears that that won't be the case.

The only resolution then, with a free Cloudflare account, is to whitelist all of the IP addresses that will be using the JSON api.

roylindauer commented 6 years ago

@pento I believe this is still an issue that should be addressed. Gutenberg breaks out of the box when using a free Cloudflare account.

pento commented 6 years ago

Thank you for the update, @roylindauer. I'll see if we can reach out to CloudFlare, but please mention in your ticket with them that this is about to become a critical issue: we just released WordPress 4.9.8, which encourages millions of sites to install the Gutenberg plugin.

pento commented 6 years ago

Update for anyone visiting this issue: it's been escalated within CloudFlare, I'll hopefully have an update in a few hours.

roylindauer commented 6 years ago

@pento I have informed Cloudflare via my support ticket.

ahmadawais commented 6 years ago

@pento this shouldn't be a closed issue. It's still as real of a problem as it gets. I have done so much for Gutenberg but even I can't use it on my sites without having to disable CloudFlare β€” which in itself is a scary thought since I use CF to provide me with security and reduction in bandwidth bills.

I think it's high time now to make CloudFlare realize how big of a problem it's going to be. Happy to help anyway here.

P.S. I still can't use Gutenberg.

The irony of the post I am trying to publish with Gutenberg in the image below

image

The same old story again

image

Peace! ✌️

pento commented 6 years ago

The issue is closed, as there's nothing we can do about it from the Gutenberg end. This shouldn't be seen as a "we don't care" flag, it's a "we have a lot of issues to manage, and ones that can't be directly actioned in this repo need to be closed" flag. πŸ™‚

CloudFlare have informed me that they plan to deploy a WAF fix on Monday, so hopefully that will take care of it.