silverstripe / silverstripe-cms

Silverstripe CMS - this is a module for Silverstripe Framework rather than a standalone app. Use https://github.com/silverstripe/silverstripe-installer/ to set this up.
http://silverstripe.org/
BSD 3-Clause "New" or "Revised" License
516 stars 333 forks source link

SS4.3.0 "Forbidden" error message arises when trying to edit a page #2357

Open SpiritLevel opened 5 years ago

SpiritLevel commented 5 years ago

When trying to edit a page in the CMS, a "Forbidden" error message appears and the page edit form does not get displayed. This occurs for SS4.3.0 and SS4.2.2 in PHP7.0 and PHP7.2. Everything else in the CMS appears to be working. Am I missing something during the install process? It would be great to get some help diagnosing this.

screenshot from 2018-12-26 00-15-02

maxime-rainville commented 5 years ago

Hi, thanks for taking the time to post to our issue tracker.

At first glance, I would look at any custom canView() methods you might have implemented.

The issue tracker is reserved for reporting bugs and we don't provide support via the issue tracker. There are great community support options where you can get help including our forum, Stack Overflow (remember to tag as silverstripe) and even Slack.

Sorry we can't be of more help and good luck resolving your problem!

SpiritLevel commented 5 years ago

Thanks @maxime-rainville

It was an untouched, fresh install of SS.

maxime-rainville commented 5 years ago

I've reopen the issue, since it looks like something that should work.

If you open the "Network" tab in your browser debug tools, you should be able to see the exact request that gets "forbidden". Can you let us know what you are seeing there?

Also, make sure SS_ENVIRONMENT_TYPE is set to dev in your .env file.

SpiritLevel commented 5 years ago

Hi @maxime-rainville

I've tried to reproduce the error to inspect request with browser debug tools but cannot :\ SS was in dev mode when it happened.

The only change in my environment since the above screenshot was taken is that I recently upgraded from php7.0 to php7.2. But the old and new php.ini files have identical settings.

I'll close this issue. Sorry for the trouble!

SpiritLevel commented 5 years ago

Hi @maxime-rainville

This error has arisen again :( I have attached a screenshot of chrome debug tools. It looks like something to do with tinymce : it is giving a 403 error when trying to access tinymce-cms-60ac20aba0.js in the folder public/assets/_tinymce. The js file is present and has read permissions. The query parameter is just an underscore which is a bit odd; should it be an "m" instead?

Thanks.

screenshot from 2019-02-04 17-50-50

ScopeyNZ commented 5 years ago

Hi @SpiritLevel. What page type is this?

SpiritLevel commented 5 years ago

Hi @ScopeyNZ

This happens immediately after a fresh install so it is occurring with the type "Page".

I tried deleting the _tinymce folder but that doesn't solve the problem.

maxime-rainville commented 5 years ago

Can you double check that your web server has write access to your assets folder and that the file that it's trying to access actually exists?

Silverstripe caches a config file for tinymce in assets. We have a few bugs we're this is causing some issue. Might be worthwhile making the error a big more explicit or providing a fallback.

SpiritLevel commented 5 years ago

Hi @maxime-rainville

OK. I double checked my server. I am running my local apache server under my username and public/, public/assets, and public/assets/_tinymce are all readable by me. The .js file exists and is also readable by me. Note that this problem seems to be intermittent; sometimes I do not have this problem.

SpiritLevel commented 5 years ago

OK. I think I narrowed it down. When I install into a folder with a "." in the path name (ie: domains/site.nz/public_html) , I get the tinymce read error. When I repeat exactly the same steps but remove the "." from the path (ie: domains/sitenz/public_html), all works fine.

Hopefully this is easily fixable; I would really like to be able to use "." in my paths :)

maxime-rainville commented 5 years ago

Interesting. I'm not getting this behaviour with a dot in my project path.

Have you tweak your configuration to use public_html instead of public as your web root? You should have a .htaccess in your assets folder. Can your share the content of the file with us?

SpiritLevel commented 5 years ago

No, I haven't changed my configuration; my provider has a public_html folder as the site root so I am just mimicking that locally, and public is a subfolder of that (ie: /my/path/to/sites/domains/site.nz/public_html is the webroot and contains app, public, vendor etc.). I'll try some more experiments to confirm that it is due to the "." in the path.

By the way, this is all happening with completely fresh installs of SS4.3.0 under php7.2.

Here is my (unaltered) public/assets/.htaccess:

#
# Whitelist appropriate assets files.
# This file is automatically generated via File.allowed_extensions configuration
# See AssetAdapter::renderTemplate() for reference.
#

# We disable PHP via several methods
# Replace the handler with the default plaintext handler
AddHandler default-handler php phtml php3 php4 php5 inc

<IfModule mod_php5.c>
    # Turn the PHP engine off
    php_flag engine off
</IfModule>

<IfModule mod_rewrite.c>
    <IfModule mod_env.c>
        SetEnv HTTP_MOD_REWRITE On
    </IfModule>

    RewriteEngine On

    # Allow error pages
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule error[^\\/]*\.html$ - [L]

    # Block invalid file extensions
    RewriteCond %{REQUEST_URI} !^[^.]*[^\/]*\.(?i:css|js|ace|arc|arj|asf|au|avi|bmp|bz2|cab|cda|csv|dmg|doc|docx|dotx|flv|gif|gpx|gz|hqx|ico|jpeg|jpg|kml|m4a|m4v|mid|midi|mkv|mov|mp3|mp4|mpa|mpeg|mpg|ogg|ogv|pages|pcx|pdf|png|pps|ppt|pptx|potx|ra|ram|rm|rtf|sit|sitx|tar|tgz|tif|tiff|txt|wav|webm|wma|wmv|xls|xlsx|xltx|zip|zipx|graphql)$
    RewriteRule .* - [F]

    # Non existant files passed to requesthandler
    RewriteCond %{REQUEST_URI} ^(.*)$
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule .* ../index.php [QSA]
</IfModule>
SpiritLevel commented 5 years ago

I just repeated the installation with and without a "." in the path and I get the same result as before.

I wonder if it matters where the "." is located in the path. Here is the complete path I am using for the project root:

/SpiritLevel/Clients/ANZTAA/domains/anztaa.nz/public_html

Hey, I just noticed in the developer tools that the path that SS is trying to get the tinymce file is missing the "public" part of the path. It is giving a 403 on

http://localhost/SpiritLevel/Clients/ANZTAA/domains/anztaa.nz/public_html/assets/_tinymce/tinymce-cms-60ac20aba0.js?_=154930984

I wonder if there is a redirect rule that is getting confused?

Edit: the web developer tools is showing a path missing "public" for the site that works and the site that doesn't work; I suppose the main redirect

^(.*)$ public/

takes care of the missing "public".

Edit 2: I took a site that had a "." in the path, and hence didn't work, and simply renamed the path to one without a ".", performed a dev/build?flush and the site works fine.

maxime-rainville commented 5 years ago

I think I know what's going on. The "Block invalid file extensions" is being triggered because of the dot in the URL. This rule is there to prevent people from uploading PHP files in assets and getting them running. Unfortunately, it gets triggered even if the dot is not in the asset path at all.

It's related to this old issue https://github.com/silverstripe/silverstripe-assets/issues/141

My guess right now is that this is bigger than tinymce. All of your assets should be throwing forbidden errors.

SpiritLevel commented 5 years ago

Thanks @maxime-rainville

Here is a weird twist: I get the forbidden error on my local installation of SS (when in any of dev, test, or live modes) but when I push the site up to my test server (in test mode) and my live server (in live mode) I don't get the forbidden error. The path on my local installation has a dot in it as do the paths on my test and live installations (they all include the domain name of the site so have .nz in them).

I also get a forbidden error when I try to directly access the 404 error page at URL assets/error-404-html in my local installation. However, on my test and live installations I can access error-404.html just fine.

This strange difference between local and remote behaviour has also been observed here https://forum.silverstripe.org/t/unable-to-edit-pages-on-a-fresh-install-local-environment/538. My local and remote apache versions are both 2.4. I can confirm that the workaround in https://forum.silverstripe.org/t/unable-to-edit-pages-on-a-fresh-install-local-environment/538 works on my local installation (ie: editing the rewrite condition regex in vendor/silverstripe/assets/templates/SilverStripe/Assets/Flysystem/PublicAssetAdapter_HTAccess.ss)

I read through silverstripe/silverstripe-assets#141. It was suggested there that folders with dots in their names not be allowed. That seems really restrictive to me; I hope a regex can be found that allows dots in folder names while at the same time is secure :) On the other hand, the fact that it works on my server but not locally suggests something more than the regex is at play.

maxime-rainville commented 5 years ago

Are your other environments configured to allow overrides? If not, the rule in the .htaccess file will be ignored.

SpiritLevel commented 5 years ago

OK, my provider has

AllowOverride AuthConfig FileInfo Indexes Limit Options=Indexes,IncludesNOEXEC,MultiViews,SymLinksIfOwnerMatch,FollowSymLinks,None

set for test and live environments. Wouldn't SS fail to work at all if the .htaccess rewrite rules were ignored (due to AllowedOverride being set incorrectly)?

I think I have worked out why there is different behaviour on the server and my local machine. It appears to be due to how apache document roots are set: On my provider, the apache document root is /home/anztaa/domains/anztaa.nz/public_html so the dot is not part of the URL. Locally, my apache document root is /home/dra and I then navigate the browser to /home/dra/SpiritLevel/Clients/ANZTAA/domains/anztaa.nz/public_html to view the site, which means the dot is part of the URL for the site. To test this, I changed my local apache document root to /home/dra/SpiritLevel/Clients/ANZTAA/domains/anztaa.nz/public_html and the forbidden error no longer arises. Secondly, I put a site on the server in /home/anztaa/domains/anztaa.nz/public_html/test.folder.with.dots and the forbidden error arises.

So, it appears that the regex is the only source of trouble and all that remains is to choose a regex that doesn't choke on paths with dots while at the same time doesn't open up security holes :)

maxime-rainville commented 5 years ago

Yes that would make a difference. REQUEST_URI contains the public path to your files. The system path shouldn't make a difference.

NightJar commented 5 years ago

I'm having issues with TinyMCE not loading in a clean 'Vanilla'' install of SS4.3.2. Have tracked the problem down to a 403 error with /Public/assets/_tinymce/tinymce-cms-9a0ff8de32.js?_=1553045079110 which I believe stems from a 'permissions' issue. In my local (Mac OS) development environment the nested folder permissions are as follows:

  • /public 'owner' R/W, 'staff' R, 'everyone' R
  • /assets 'owner' R/W, 'staff' R, 'everyone' R
  • /_tinymce 'owner' R/W, 'staff' R, 'everyone' R

I can change the first two folders for R/W for everyone. When I change permissions on /_tinymce and admin?flush=all the settings on _tinymce revert to 'write only' for user 'everyone'. Is this the root of the problem?


Should have clarified: I’m running this in my development environment (MacPro running OS 10.11.6). Development stack is MAMP 5.0.1, PHP 7.2.7

Bringing over issues with TinyMCE as reported by @mhenden in https://github.com/silverstripe/silverstripe-framework/issues/8228 - which is a slightly different issue, this is the more appropriate place to discuss permissions based issues with this functionality.

guci0 commented 2 years ago

My best solution for this is, change one line:

.../vendor/silverstripe/assets/templates/SilverStripe/Assets/Flysystem/PublicAssetAdapter_HTAccess.SilverStripe

# Allow specific file extensions
#RewriteCond %{REQUEST_URI} !^[^.]*[^\\/]*\\.(?i:css|js<% loop $AllowedExtensions %>|$Extension<% end_loop %>)$
RewriteCond %{REQUEST_URI} !^.*\\.(?i:css|js<% loop $AllowedExtensions %>|$Extension<% end_loop %>)$
RewriteRule .* - [F]