https://bz.apache.org/bugzilla/show_bug.cgi?id=63798

            Bug ID: 63798
           Summary: mod_headers-directives configured via .htaccess are
                    being ignored with Action-invoked CGI scripts
           Product: Apache httpd-2
           Version: 2.4.38
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: mod_actions
          Assignee: bugs@httpd.apache.org
          Reporter: and...@schlund.de
  Target Milestone: ---

Overview: The Action directive is a common way to launch CGI scripts based on
their MIME content type. Invoking a CGI script via a custom handler
functionally disables any mod_headers-directives present in the current
directory's .htacess. 

After some research, Apache does take only some .htaccess-directives from the
CGI script's directory, but combines headers with any .htaccess-directives from
the CGI script interpreter's directory.

Following steps and setup are used to reproduce this issue:

PHP is invoked via configuration in the "global" apache configuration file
(e.g. /etc/apache2/httpd.conf):

---cut
ScriptAlias "/cgi-bin/" "/usr/lib/cgi-bin/"

Action x-php /cgi-bin/php
AddHandler x-php .php
--cut

/usr/lib/cgi-bin/php is an executable PHP-CGI binary. Different websites owned
by different users are hosted on the same server, suexec is used to isolate
each users processes from each other. This example leaves out suexec, as it
does reproduce with and without suexec.

/home/user123/docroot/
is the DocumentRoot for a Virtualhost and contains at least test.php, test.html
and .htaccess.

test.html is static HTML content, 
test.php does successfully execute some PHP code.

.htaccess does add/edit/remove HTTP headers like

---cut
<If "%{HTTPS} == 'on'">
Header set Strict-Transport-Security "max-age=31536000"
</If>
Header always set Cache-Control: "private, pre-check=0, post-check=0,
max-age=0"
Header set X-Load-Indicator "%b %i %D %l" 
Header always unset X-Powered-By
---cut

Additionally, it does enable Basic Authentication:

---cut
AuthType Basic
AuthName "Access"
AuthUserFile /home/user123/htpasswd
Require valid-user
---cut

Actual result:

Invoking /test.html does prompt for username/password, returns the expected
content and both server-default and .htaccess-configured headers.

Invoking /test.php does prompt for username/password, returns the expected
content, but only has server-default and PHP's own HTTP-headers set. Any
header-configurations present in the .htaccess file are being ignored.

Expected result:
Invoking /test.html and /test.php does prompt for username/password, return the
expected content and headers provided by server configuration, .htaccess and
PHP for /test.php.


Additional information:

Moving the .htaccess configuration to the global configuration's virtualhost
context does enable all functionality as expected: /test.php returns both PHP's
own headers and the server-configured headers.

Embedding the .htaccess-directives into a "<Directory
/home/user123/docroot>"-section behaves the same way than having them in
.htaccess.

>From this point of view, Apache does behave somehow inconsistent (or at least:
hard to understand), as the .htaccess-configured directives all are eligble to
be run from .htaccess, but behave differently when being used in a VirtualHost
context.

My assumption: shortly before a CGI script is being launched, a range of
("early") .htaccess-directives are being evaluated and applied (e.g. Basic
Authentication). When a CGI script is being launched via Action, Apache does
perform an internal redirect, which does change the DOCUMENT_ROOT to
CONTEXT_DOCUMENT_ROOT and internally requests /cgi-bin/php/test.php instead of
/test.php. mod_headers needs to run "late", after the CGI output has been
returned; when doing so, Apache notices the changed DOCUMENT_ROOT and checks
for .htaccess in the CGI interpreter's directory (/usr/lib/cgi-bin), but no
longer the CGI script's directory (/home/user123/docroot).

After the custom Action handler makes Apache handle the CGI-request as an
internal redirect, so the request for /test.php becomes being treated as an
internal(!) request for /cgi-bin/php/test.php. From Apache's point of view, a
totally different .htaccess has to apply: if /usr/lib/cgi-bin/ is enabled via
AllowOverride, a present .htacess is actually being parsed.

Aside from setting headers from the PHP script (essentially duplicating the
.htaccess-configuration to PHP code), there's also the following workaround - 
the user can change the exact mode of CGI execution:
- prepend "#!/usr/lib/cgi-bin/php" to test.php
- chmod u+x test.php
- add "AddHandler cgi-script .php" to .htaccess

Doing so executes test.php as an "ordinary" CGI script, without any internal
redirect or changing CONTEXT_DOCUMENT_ROOT/DOCUMENT_ROOT, yet still executing
all effective directives from the script directory's .htaccess file (in this
case: both Basic Auth and Headers).

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscr...@httpd.apache.org
For additional commands, e-mail: bugs-h...@httpd.apache.org

Reply via email to