Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set an environment variable in .htaccess and retrieve it in PHP

I am trying to set an environment variable in an .htaccess file and retrieve it in PHP. I've looked through a bunch of other threads here on SO but everything I've tried so far has failed.

I've added this line to the .htaccess file:

SetEnv SPECIAL_PATH /foo/bin

I have tried retrieving this value using the getenv() PHP function:

<?php $specialPath = getenv('SPECIAL_PATH'); ?>

I have runned phpinfo() to see the list of available environment variables, SPECIAL_PATH is not there. I am puzzled as to why this is not working.

Thank you!

like image 639
Bruno Cloutier Avatar asked Jul 09 '13 14:07

Bruno Cloutier


2 Answers

Assuming your configuration has AllowOverrides with .htaccess, you must enable mod_env in Apache for this to work.

Apache - mod_env

like image 80
Jacob S Avatar answered Nov 01 '22 04:11

Jacob S


Apache Docs custom-error.html covers environment variables passed to error handling pages

Says "REDIRECT_ environment variables are created from the environment variables which existed prior to the redirect. They are renamed with a REDIRECT_ prefix, i.e., HTTP_USER_AGENT becomes REDIRECT_HTTP_USER_AGENT."

Says "None of these will be set if the ErrorDocument target is an external redirect (anything starting with a scheme name like http:, even if it refers to the same host as the server)."

Says about SetEnv: "The internal environment variables set by this directive are set after most early request processing directives are run, such as access control and URI-to-filename mapping. If the environment variable you're setting is meant as input into this early phase of processing such as the RewriteRule directive, you should instead set the environment variable with SetEnvIf."

On some servers, user-declared environment variables must start with 'HTTP_' for security purposes, e.g.: SetEnv HTTP_MY_VARIABLE "my value"

Here are some .htaccess ways of setting and using server environment variables, taken from my modifying the Perishable Press 5G Blacklist/Firewall http://perishablepress.com/5g-blacklist-2013/ to use environment variable reporting:

SetEnv myServerName %{SERVER_NAME}

RewriteCond %{QUERY_STRING} (base64_encode|localhost|mosconfig|open_basedir) [NC,OR]
RewriteCond %{QUERY_STRING} (boot\.ini|echo.*kae|etc/passwd) [NC,OR]
RewriteCond %{QUERY_STRING} (GLOBALS|REQUEST)(=|\[|%) [NC]
RewriteRule .* - [E=badQueryString:%0--%1--%2,F,L]

SetEnvIfNoCase User-Agent ^$ noUserAgent
SetEnvIfNoCase User-Agent (binlar|casper|cmsworldmap|comodo|diavol|dotbot|feedfinder|flicky|ia_archiver|jakarta|kmccrew|nutch|planetwork|purebot|pycurl|skygrid|sucker|turnit|vikspider|zmeu) badUserAgent=$1

<limit GET POST PUT>
  Order Allow,Deny
  Allow from all
  Deny from env=badUserAgent
</limit>

Notice the use of paramters, e.g. $0--%1--%2. %0 gives the full string, %1 gives the match from the 1st parenthesized statement, %2 the 2nd. The hyphens are literal display characters, to visually separate parameter results (don't think is any way to put spaces in there).


Here are some PHP methods of accessing the environment variables (in my case from 403.php and 404.php). Note that you don't look in phpinfo(), but in $SERVER, and that your variables get prefixed with REDIRECT Note also that with a 403/404 redirect, the QUERY_STRING becomes REDIRECT_QUERY_STRING This is stuff that could easily be server dependent, so check $_SERVER for your actual values. For example,

if (getenv("HTTP_REFERER") !== FALSE) {
    $httpref = getenv("HTTP_REFERER");
} else {
    $httpref = '';
}
if (isset($_SERVER['REDIRECT_STATUS'])) {
    $status = $_SERVER['REDIRECT_STATUS'];
} else {
    $status = '';
}
if (isset($_SERVER['REMOTE_HOST'])) {
    $remoteHost = $_SERVER['REMOTE_HOST'];
} else {
    $remoteHost = '';
}

if (isset($_SERVER['REDIRECT_QUERY_STRING'])) {
    $querystring = $_SERVER['REDIRECT_QUERY_STRING'];
} else {
    $querystring = '';
}

if (isset($_SERVER['REDIRECT_noUserAgent']) ) {
    $htaccessErrors[] = 'NoUserAgent';
}
if (getenv("REDIRECT_badQueryString") !== FALSE) {
/* must exactly match what shows up in $_SERVER, is case sensitive (e.g. badQueryString not BadQueryString) */
    $htaccessErrors[] = 'badQueryString:'.getenv("REDIRECT_badQueryString");
}

I cover in some depth in http://lcblog.lernerconsult.com/2013-server-alert-you-file-not-found-errors/

like image 31
George Lerner Avatar answered Nov 01 '22 03:11

George Lerner