WordPress.org

Make WordPress Core

Opened 5 years ago

Last modified 5 months ago

#36177 new enhancement

default htaccess should include security measures

Reported by: lelutin Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Security Keywords:
Focuses: Cc:

Description

Wordpress has some code that automatically creates a .htaccess file for users. This file however includes no security measures whatsoever, meaning that users who do not tighten security by themselves are left with an install that lets upload files that contain random php code and then execute them.

The real problem is that most wordpress users don't do any security tightening by themselves, either because they didn't see it in the install procedure or (more likely) because they don't have the knowledge necessary to know what measres are appropriate or not.

This is a bane to all shared hosting providers who will either need to figure out ways to tighten security for the users, while not knowing what they are or will be hosting.

This lack of basic security was already pointed out in ticket #9185 seven years ago but was discarded for reasons that I believe are not valid:

blocking php evaluation for all files in wp-content would only affect direct php file access through a URL, not inclusion of code by other php files. This means that only direct access to files would get blocked for some plugins, but plugins should not require users to load plugin-specific php files directly in the first place: those files should get included through wordpress itself.

finally, since wordpress has php code that generates these .htaccess files, there is no good reason to avoid addding some security measures in there. Some measures for htaccess are even suggested in https://codex.wordpress.org/Hardening_WordPress . It doesn't make sense to not include them by default

Drupal does include a good host of default security measures to help users have a good security level by default. More can be done by users of course depending on the requirements, but default drupal installs will not get hacked as badly as default wordpress installs frequently do. see: https://github.com/drupal/drupal/blob/8.1.x/.htaccess

What I'm suggesting is the following. Have wordpress include the following blocks in generated .htaccess files:

<IfModule mod_rewrite.c>
  RewriteRule ^wp-admin/includes/ - [F,L]
  RewriteRule !^wp-includes/ - [S=3]
  RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
  RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
  RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>

<files ~ "^.*\.([Hh][Tt][Aa])">
  order allow,deny
  deny from all
</files>

<files wp-config.php>
  order allow,deny
  deny from all
</files>

<LocationMatch "/wp-content/">
  php_flag engine off
  <files ~ ".php">
    order allow,deny
    deny from all
  </files>
</LocationMatch

note that the above example might need to be adapted to the multisite layout.

note also that the "order" and "deny" lines are only fit for apache 2.2. It's however easy to have both sets for instructions of 2.2 and 2.4 with <IfModule mod_authz_core.c> blocks (see drupal 8.1 default .htaccess file linked above for examples)

Change History (16)

#1 @makeonlineshop
5 years ago

Hello, I am sorry, I am new to wordpress, but if what you say is true it means that most wordpress in the world have no security ? As I guess that most users do not have any knowledge about this ?

Seems really weird to me.

#2 @lelutin
5 years ago

@makeonlineshop it's not so much that wordpress has no security, more that by default there could be some basic protections added.

mind you, the proposed protections also only affect users that are using apache, which I would guess are the majority. nginx doesn't have dynamically loaded configuration files for individual sites like apache does (which arguably is a better model) so the better strategy is to have good documentation on how to setup nginx for wordpress, including some protection measures for file/directories access.

#3 @makeonlineshop
5 years ago

Thank you for your explanation, but you understand that even talking about Apache or Nginx is already too complicated for people like me ?

So if it really means that most WP have not enough security it seems as stupid as something as I could have done myself :-)

#4 follow-up: @SergeyBiryukov
5 years ago

blocking php evaluation for all files in wp-content would only affect direct php file access through a URL, not inclusion of code by other php files. This means that only direct access to files would get blocked for some plugins, but plugins should not require users to load plugin-specific php files directly in the first place: those files should get included through wordpress itself.

This seems like it would break plugins that submit AJAX requests to their own files.

Admittedly, they should have used admin-ajax.php instead, but not everyone does.

#5 in reply to: ↑ 4 @jorbin
5 years ago

Replying to SergeyBiryukov:

Admittedly, they should have used admin-ajax.php instead, but not everyone does.

Or better yet, they should leverage the rest API infrastructure and create a custom endpoint.

#6 @lelutin
5 years ago

oh my this is really embarrassing <.<;

Location is not at all permitted in .htaccess.. so the part about disabling php for wp-content is not functional.

something could be done with mod_rewrite instead to deny access to .php files under that directory.

#7 @bendoh
5 years ago

Having just dealt with a site hacked because of Revolution Slider (*fist shake*); this sprang to mind and I'm glad there's a ticket for it.

So <Location> may not be usable in .htaccess, but it appears <Files> is. Since wp-content/uploads should presumably never have executable code, perhaps adding wp-content/uploads/.htaccess with the following rule
will work:

<Files *.php>
deny from all
</Files>

This works for me, but it may break existing plugins that would (stupidly) rely on executing uploaded PHP files.

But how does this particular .htaccess file get locked down? Presumably wp-content/uploads is writable by the webserver, so it doesn't completely prevent vulnerable code from manipulating or deleting this file entirely. What springs to mind is using a sticky bit on wp-content/uploads so that as long as .htaccess isn't owned by the webserver, that file can't be manipulated from vulnerable PHP code.

Unfortunately, sticky bits aren't a thing on Windows, AFAIK.

Last edited 5 years ago by bendoh (previous) (diff)

#8 @swissspidy
3 years ago

#42917 was marked as a duplicate.

#9 @swissspidy
3 years ago

#44663 was marked as a duplicate.

#10 @swissspidy
3 years ago

#44700 was marked as a duplicate.

#11 @swissspidy
2 years ago

#45773 was marked as a duplicate.

#13 @dd32
15 months ago

#48049 was marked as a duplicate.

This ticket was mentioned in Slack in #core by helen. View the logs.


5 months ago

#15 follow-up: @peterwilsoncc
5 months ago

#43459 was marked as a duplicate.

#16 in reply to: ↑ 15 @bjne
5 months ago

Replying to peterwilsoncc:

#43459 was marked as a duplicate.

I think that a permission/file information map should be written in a format that would be easy to both verify and parse into various rules or code, be it either htaccess or any other format.

I think writing this ruleset in a"unparsable" format like htaccess, links wordpress and apache too tightly together.

Note: See TracTickets for help on using tickets.