Tell Apache if PHP should be run on requests
I am using PHP with Apache and am wondering if there is a way to indicate from the client side that the requested PHP file should not be executed / parsed. By standard, I want all PHP files to be executed on demand, but I want to indicate from the client side that the file should not be executed.
A good solution would be to provide an extra header in the request using JavaScript and then write code in the file .htaccess
to check if the header is present and if it says apache is not executing the file and just serve in the text.
Using GET parameters or whatever should be fine.
Is it possible? If so, how?
source to share
provide an extra header in the request [using JavaScript] and then write some code in the .htaccess file to check if the header is present
You can force Apache to check this (secret) header and internally rewrite the request to a file of type viewAsSource.php
, which then reads REQUEST_URI
(or a passed query string parameter) and returns the file source instead. Similar to @LucasKrupinski's suggestion, except you don't need to include anything in the PHP file.
For example, in your root file .htaccess
:
RewriteEngine On
# Block direct access to any file in the /tools directory
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^tools/ - [F]
# Display PHP source...
RewriteCond %{HTTP:X-Action} ^display-source$
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (.+\.php)$ tools/display-source.php?url=$1 [L]
For all requests, .php
this checks the X-Action
HTTP request header with the value "display-source" and that the requested file exists. If these conditions are met, the request is internally written to the /tools/display-source.php
script, passing the url as a parameter url
. You can check superglobal instead $_SERVER['REQUEST_URI']
, but note that this also includes any query string that is passed on request.
Then into display-source.php
something like:
<?php
$url = isset($_GET['url']) ? $_GET['url'] : null;
if (isset($url)) {
$file = $_SERVER['DOCUMENT_ROOT].'/'.$url;
// Validate $file....
// :
highlight_file($file);
}
source to share
You can also set the handler in file .htaccess
(or in server config):
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
Require all granted
</FilesMatch>
Then you need to set a symlink to the php file on Linux systems:
ln -s filename.php filename.phps
filename.phps
You will get a highlighted syntax source when prompted .
Require all granted
is the syntax in Apache 2.4. Older versions use Allow from all
and Deny from none
.
source to share
Can your PHP files have one extra line?
Line 1: <?php include('viewAsSource.php'); ?>
viewAsSource.php:
<?php
if(isset($_GET['src'])) {
$self = $_SERVER['SCRIPT_FILENAME'];
$lines = file($self);
$output = '';
foreach ($lines as $line) {
$output .= nl2br(htmlspecialchars($line));
}
echo $output;
}
So if they ask for "sample.php" they get the parsed version, but if they ask for "sample.php? Src" they get the source?
source to share