Jump to content

Session access intermittent failure


AdmiralQ

Recommended Posts

I built a functional login form 11 years ago and it has worked all of that time. My account goes offline for non-payment for a couple of days due to me forgetting to update new payment info after a bank card had been compromised, and suddenly the login script which has been 100% reliable for more than a decade now returns:

Warning: session_start(): open(/tmp/sess_{an alphanumeric string}, O_RDWR) failed: Permission denied (13) in /home/jandrews/public_html/admin_authenticate.php on line 2

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /home/jandrews/public_html/admin_authenticate.php:2) in /home/jandrews/public_html/admin_authenticate.php on line 2

 

And then the code returns me to the login page even though the username and password were valid. I wish to emphasize that this code hasn't changed since 2014! It is only in the last week that this problem has presented itself. The WEIRDEST PART OF THIS is that if I try and it fails to let me login, I can quit the browser and try again with about a 20% chance of it then working. You see ... it doesn't fail every time. About 4 out of 5 times.

Here is the code for admin_authenticate.php

<?
session_start();
extract($_REQUEST);

include 'r_open_link.php';

	$query = "SELECT * FROM inno_school_staff WHERE uname = '$uname' and pword = '$pword'";
	$result = mysql_query($query) or die("Could not perform query: ".mysql_error());
	$row = mysql_fetch_array($result);
		$_SESSION['staff']['uname'] = $row['uname'];
		$_SESSION['staff']['fname'] = $row['fname'];
		$_SESSION['staff']['lname'] = $row['lname'];
		$_SESSION['staff']['type']	= $row['type'];
		$_SESSION['staff']['school']= $row['school_name'];
		$_SESSION['staff']['email']=  $row['email'];
		$_SESSION['value_m'] = $row['value_m'];
		$_SESSION['value_p'] = $row['value_p'];
		$_SESSION['value_d'] = $row['value_d'];
		$_SESSION['value_b'] = $row['value_b'];

if ($_SESSION['staff']['uname'] == ""){
	print "<META HTTP-EQUIV=\"Refresh\" content=\"0;URL=admin_login.php?improper=1\">";
	print "SEC_VAR: ".$sec_var."<br>";
}
else
{
include 'r_declaration.php';
?>
	<link rel="stylesheet" type="text/css" href="ipad_new.css">
 <title>Innovative Educaiton Works</title>
</head>
<body bgcolor="000000" style="color: #ffffff">
<br><br><br>
<table align="center">
	<tr>
		<td valign="middle" align="center" height="400" width="600" style="color: white; font-size: 24pt;">Authenticating ...</td>
	</tr>
</table>	
</body>
</html>
<?
	$ip = $_SERVER['REMOTE_ADDR'];
	$stamp = date("U");
	$query = "INSERT INTO inno_login_track_staff (address, uname, lname, fname, stamp) VALUES ('$ip', '".$_SESSION['staff']['uname']."', '".$_SESSION['staff']['lname']."', '".$_SESSION['staff']['fname']."', '$stamp')";
	$result= mysql_query($query) or die("Could not perform query: ".mysql_error());

	if ($destino == 1){print "<META HTTP-EQUIV=\"Refresh\" content=\"1;URL=admin_panels.php\">";}
	else {print "<META HTTP-EQUIV=\"Refresh\" content=\"1;URL=admin_panels.php\">";}

}?>

 I double checked my php.ini file and the session save path is correctly listed as tmp. I've never changed it. And permissions are enabled on it for read, write and execute for owner, group and world. I am a high school teacher and I write my own code to use in my classroom. School starts for us on Monday and I am at a complete loss on how this could be happening after 11 years of perfect functionality!!!

I will admit that my PHP is very old. I am not good at maintaining the server side, nor with multiple children do I have time to keep up with new iterations of PHP. I know I'm going to pay for that one day, but I do not believe this is a result of that. Thank you for any help, and I can provide further details as needed.

Edited by AdmiralQ
Link to comment
Share on other sites

If you haven't already, reach out to the hosting company: clearly something changed while the account was offline and it hasn't been undone.

What's the hosting setup? Are there other users on that system, which you could tell by looking in /home for other usernames? Because it seems like there are, yet the save path is /tmp which would be shared with everyone and that's not good.

The error names a particular file - does it happen to exist?
What are the exact permissions and ownership on /tmp? It should probably be rwxrwxrwt, with that last letter "t" meaning sticky permissions and not "x" like normal, and probably be owned by root:root (and not, say, your own account).
When your retry logging in and it works, look at your cookies for the PHP session id, then track it to the file in /tmp. What are its permissions and ownership?

Link to comment
Share on other sites

admin_authenticate.php has some issues that should be noted:

Regarding headers already sent, I do not see the opening html and head tags in your code, so i am assuming that you have placed them before start of session.

to quote the php manual:
To use cookie-based sessions, session_start() must be called before outputting anything to the browser.
 

session_start() should be placed before any output to a browser (including html and head tags).

I have no idea as to why you wouldn't have had problems before now.

if ($destino == 1){print "<META HTTP-EQUIV=\"Refresh\" content=\"1;URL=admin_panels.php\">";}
else {print "<META HTTP-EQUIV=\"Refresh\" content=\"1;URL=admin_panels.php\">";}

the else should be different from the if branch, otherwise it doesn't make sense to me. Both uris point to admin_panels.php. Furthermore, you have a meta tag placed outside of the head element and outside of the html element.

it seems as though you should be showing more code than what you have posted as well. For example, what is the php code in r_open_link.php and r_declaration.php? where is the opening html and head tags? in another php file?

database gurus are going to trip over that db code laying in the middle of the floor... probably switching to pdo is a good place to begin again.
 

Link to comment
Share on other sites

All of the advice above is valuable, and I do plan on upgrading my PHP. I am a much better programmer now than when I started this project 11 years ago.

HOWEVER ...

Another variable I've noticed has come into play here. I've been getting server generated emails saying "Notification The service "ftpd" appears to be down." If there is intermittent failure of this process could that be causing the session variables not to get written in the tmp folder?

Also, I noticed a change in behavior between http calls and https calls. Once I forced http instead of the browser wanting to use https I no longer had the session variable problem ... even if I began switching between the two protocols (http / https). Now I'm really confused!!! AAAUUUGGGHHHH!

 

Below is a simple login script that I wrote to test session function. It worked with http, but when I put in https it gave the error messages without even submitting the form. But now, after having used both https and http it functions either way. It just feels like there's a monkey with a wrench living in my server!!! The kicker is that RIGHT NOW it's all working properly, but 1) I haven't done anything, and 2) how long will it continue to do so since I haven't "fixed" anything, and 3) what's up with that "ftpd" failure message?!?!? and is that ultimately the cause of all of this!!!

<?
session_start();
extract($_REQUEST);
?>
<body bgcolor="000000" style="color: #ffffff;">
<p>Innovative Education Works</p>

<form action="index_test2.php" method="post">

Username: <input type="text" name="uname" size="20"><br>
Password: <input type="text" name="pword" size="15"><br>
<input type="submit">

</form>
</body>

 

Link to comment
Share on other sites

Answers to my questions would be nice too.

 

8 hours ago, AdmiralQ said:

I've been getting server generated emails saying "Notification The service "ftpd" appears to be down." If there is intermittent failure of this process could that be causing the session variables not to get written in the tmp folder?

"ftpd" is very likely going to be an FTP server. If you need it then you should look into what's wrong, if you don't then you can shut it down.

8 hours ago, AdmiralQ said:

Also, I noticed a change in behavior between http calls and https calls. Once I forced http instead of the browser wanting to use https I no longer had the session variable problem ... even if I began switching between the two protocols (http / https)

It kinda sounds like the http and https sides are running with different user credentials. Except that's weird.

  • Like 1
Link to comment
Share on other sites

9 hours ago, AdmiralQ said:

Another variable I've noticed has come into play here. I've been getting server generated emails saying "Notification The service "ftpd" appears to be down." If there is intermittent failure of this process could that be causing the session variables not to get written in the tmp folder?

while this isn't the cause of the session data file open/permission error, it indicates there's something going on on the server. i'm going to guess something like the allocated disk space is full, causing the FTP service error and the session data file error. searching for - 'php session Permission denied (13)' gives a  number of results, most of them having to do with the actual permissions.

you haven't answered @requinix's question about - What's the hosting setup? If this is shared web hosting, you would typically have a session data folder within your account's directory tree for 'your' session data files.

the 2nd warning message about headers already sent has nothing to due with the problem. this warning is due to the 1st warning message being output. once the problem with the session data file open()/permissions is solved, both of these errors messages will go away.

 

Link to comment
Share on other sites

once you follow the advice of this forums experts to solve your problem, you should definitely upgrade php and your code.

I'm trying to be helpful and i hope that you take this advice, since your code has security issues involved.

so working off of the same input names $_POST['uname'] and $_POST['pword'], you could easily switch to pdo:

    $dbHost = '127.0.0.1';
    $dbName = 'iew';
    $dbUser = 'root';
    $dbPass = '';
    $dbAttr = array(
        PDO::ATTR_EMULATE_PREPARES => false,
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    );
    $dbConn = new PDO("mysql:host=$dbHost; dbname=$dbName; charset=utf8mb4", $dbUser, $dbPass, $dbAttr);
    $query = 'SELECT * FROM inno_school_staff WHERE uname = :PostUser';
    $iew = $dbConn->prepare($query);
    $iew->execute(array(':PostUser' => $_POST['uname']));
    $row = $iew->fetch();

keep in mind that you need to adjust the $dbHost, $dbName, $dbUser, and $dbPass variables to suit your working environment.

now, you can load your session variables the same as before but we switched to pdo.

$_SESSION['staff']['uname'] = $row['uname'];
$_SESSION['staff']['fname'] = $row['fname'];
$_SESSION['staff']['lname'] = $row['lname'];
$_SESSION['staff']['type'] = $row['type'];
$_SESSION['staff']['school'] = $row['school_name'];
$_SESSION['staff']['email'] = $row['email'];
$_SESSION['value_m'] = $row['value_m'];
$_SESSION['value_p'] = $row['value_p'];
$_SESSION['value_d'] = $row['value_d'];
$_SESSION['value_b'] = $row['value_b'];

however, i recommend that you hash user passwords before storing them in the database.
example php script to show how this works:

$formPass = "joDunn02024";
$showHash = password_hash($formPass, PASSWORD_BCRYPT);
echo $showHash;

Then, you can verify passwords without plaintext security issues:

if (password_verify($_POST['pword'], $row['pword'])) { /* user passwords match */ }


Meantime, your sessions could be intermittent if they are not properly coded. I've had this happen to me when i first started working with sessions.
Even if you were to find a patch to make your site function again, it does not excuse the fact that you need to update your code and programming methods. This forum has professional programmers that can help you with any upgrade issues. I recommend that you try to update your code.

Best wishes to you and i hope that you solve your problems soon.

Link to comment
Share on other sites

I really appreciate all the input here. Let me try to answer as much as I can.

So, the server is a VPN which I rent from GoDaddy. I run the WHM and the cPanel, though "run" is probably not the right word. I have little experience with that aspect. So, I have root access. The tmp folder in the root directory does have it's permissions set up properly ... 0755. I changed them to 0777 to see if that would correct the issue and it hasn't.

I also attempted to use session_save_path to another folder which I titled "sessions" in my cPanel directory. It ran exactly as it had before. It used the new folder but had the same intermittent issues as had the other folder. If I just sit there and try time and time again to login I get a success rate of about 1 in every 4 or 5 attempts. Each failure is met with the same message that it did not have permission to write to the sessions file. I have a friend helping me who has more experience than I but he is perplexed too. We DID see the session file being written each time whether there was failure or success, but the failure sessions variables contained zero bytes ... were completely empty, whereas the successful ones contained the data you would expect them to have. So in each case it appears the session variable was CREATED, but then the system was denied access to WRITE to it.

I have found several other instances online with problems matching this exact description but none of their stated solutions have worked. I have students walk into my classroom in 18 hours.

Also, upon further testing I don't believe there's a relationship (as I previously suspected) between the http call and the https one. And, yes, I'm sending sessions_start() before any other coding. The headers to these files are contained in the "include 'r_declaration.php';" statement, and the "include 'r_open_link.php';" is a call to open a link to the dB. And the if/else arguments render the same result because I use to send mobile devices to another page. I haven't deleted the code as I plan on re-implementing this at some point.

I just don't get it.

Link to comment
Share on other sites

it sounds like the session data files are being read and locked. the permission issue isn't due to the permission settings, but that some other instance/process is reading the file at the same time.

this would be either due to session garbage collection (you can temporarily configure it to not run as a test or perhaps it is configured to run on each session start?), some code that's reading/scanning the session data files (do you have some code that's trying to read and manage the session data, such as logging users out after a time?) , or multiple concurrent instances of your script accessing the same session data (this can occur when ajax requests are used.)

as to why this worked before and has now changed, I don't have any suggestions. it would take knowing everything your code is capable of doing, session related, uploaded file related, ...  are there currently a bunch of unusual requests being made to the site or just your requests for troubleshooting this problem?

Link to comment
Share on other sites

Let's start with this:

You are getting the header already sent because PHP is outputting the session file permissions error.  If you fix your session permission error, things will start working.

My suggestion is this:

  • Undo any changes you made to the session storage location.  Some linux operating systems (Notably Debian) come with alternatives to php session handling.

Depending on the setup of your server, you might need to 

The messages you are getting about ftpd being down seems to indicate an intrinsic problem with the server.  I'm assuming ftp is the way you update your files, which is insecure, antiquated, and in general, nothing anyone should be using in 2024 to maintain the working code for a website.  Do with that what you will, but if the ftpd process is being killed, there could be other processes that are also being killed that you don't even realize.

 

The reality with godaddy and many other hosting companies, is that you MUST rely on them for shared hosting problems.  

 

*IF* you really got to a point where you wanted an alternative for sessions, then I'd suggest you utilize the facility to store your session data in your mysql database.  It's somewhat involved, but completely doable, and for a small site with limited visitors, something you can control.  

With that said, trying to out think/out sysadmin a shared host on a server isn't something I'd suggest.  Get godaddy to fix this so that php works reliably with the default settings.  Anything YOU change will be pointed at by them as the source of your issues and you might as well pick up and go to a better hosting option, which I'm going to assume is the last thing you want to do right now.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.