Apache DirectorySlash Off - Site breaks
Asked Answered
D

4

11

If i set DirectorySlash Off in my .htaccess file and call the directory without the trailing slash i get an 403-Forbidden from my server. If i call it with slash everything works fine.

Could anyone explain why? Here are my fully anonymized .htaccess:

# GLOBAL CONFIG
Options +FollowSymlinks
DirectorySlash Off
AddDefaultCharset utf-8
php_value post_max_size 256M
php_value upload_max_filesize 256M

# BEGIN WordPress
RewriteEngine On
RewriteBase /folder/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /folder/index.php [L]
# END WordPress

# REMOVE WWW
RewriteCond %{HTTP_HOST} ^([^.]+)\.domain\.com$ [NC]
RewriteRule ^(.*)$ http://domain.com$1 [R=301,L]
Duckling answered 15/7, 2010 at 18:51 Comment(0)
F
16

As you know per the documentation, when DirectorySlash is set to Off, requests to /folder do not have DirectoryIndex evaluated. This means that the request will not be automatically mapped to /folder/index.php.

mod_dir performs this check in the "fixup" phase of the request processing. mod_rewrite, which is responsible for your RewriteRule definitions, also performs its processing in this phase when you specify the rules in a .htaccess file.

However, it was programmed with an awareness of modules like mod_dir, and includes a check to make sure that the current directory was requested with a trailing slash. If not, it declines to handle the request, since doing so might lead to undefined behaviour.

The request then moves on to the content-generation phase, which, since the request was not mapped to a real file, is handled by mod_autoindex. Given that Indexes are disabled on your host by default, mod_autoindex returns 403 Forbidden which is what you see.

Note that since DirectoryIndex is not evaluated, even if mod_rewrite were to process the request, it would still fail, because no auto-resolution to index.php would occur, and your rule

RewriteRule . /folder/index.php [L]

wouldn't match, because the . requires a match on something (but the request would be blank).

Enabling DirectorySlash prevents this scenario by correcting the prevented actions in all of the previously mentioned scenarios except the last note, which is taken care of by the fact that DirectoryIndex maps the request to index.php anyway.

Feuillant answered 17/7, 2010 at 21:59 Comment(2)
Thank you very much! Easy to understand too, if i read your Answer.Duckling
But what if we want to obfuscate our directory structure and still use mod_rewrite for each request? Let's say I have a site with a /private directory. Apache would redirect me to /private/ if I request /private if DirectorySlash is On, thus letting information disclosure to take in. What if I just want to send /private to my index.php front controller?Alphonsa
O
12

With Apache 2.4 you can allow rewrites in .htaccess files by setting RewriteOptions AllowNoSlash.

 Changes with Apache 2.3.16
 ...
 *) mod_rewrite: Add the AllowNoSlash RewriteOption, which makes it possible
    for RewriteRules to be placed in .htaccess files that match the directory
    with no trailing slash. PR 48304.
    [Matthew Byng-Maddick <matthew byng-maddick bbc.co.uk>]
 ...

See Apache documentation of mod_rewrite

Obediah answered 23/2, 2012 at 8:47 Comment(0)
A
2

I think because when you turn DirectorySlash off, it disable the autocorrection of the url and it is trying to show the directory list but fortunately you have probably disabled this somewhere (or in file permissions) so it sends a 403-Forbidden. I guess that when you turn it on, it works normally. From what I understand from the docs, it is not very good to use DirectorySlash off for security. http://httpd.apache.org/docs/2.1/mod/mod_dir.html

Alfreda answered 15/7, 2010 at 19:15 Comment(3)
Laurent, thank you for your answer. I've read the security warning in the apache docs too but i need to understand what went wrong here. By the way directory listing is per default disabled at my webhost backend.Duckling
You rewriteBase is /folder/ so you need the ending slash on the url to match. You can set it to /folder and I think it should work without the ending slash.Alfreda
I get also an 403 if i follow your suggestion.Duckling
H
0

As Tom already answered, there is special option for RewriteOptions, but only for Apache 2.3.16+, so if you, like me, have an apache of the older version, then you cannot rewrite url for same directory, because apache doesn't know about this directory.

Example: "GET /somedir" will point to <Directory /var/www/html/public> in rewrite log, but(!) requested filename (%f) in access log will still /var/www/html/public/somedir/ - this is crazy apache logic. And apache will show you either 503 (without Options +Indexes) or directory listing (otherwise) with wrong urls such as /subdir/ instead of /somedir/subdir/

So, I've found only one worked solution for me - using aliases:

AliasMatch "/somedir$" "/var/www/html/public/somedir/index.html"

Hope this helps someone else in 2020+ :D

Hedi answered 11/6, 2020 at 9:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.