The text botter in a field causes PHP to crash

Username (e.g. epiz_XXX) or Website URL


(please specify the website or account you are asking about)

Error Message

No error message, just a blank screen, when the string ‘botter’ or ‘boter’ is part of a field. Without these problematic string, the screens work as expected eg ‘b0tter’ with a zero works fine.

Other Information

It did my head in finding it.
(other information and details relevant to your question)
Is there some setting that needs to be changed to prevent this from occurring- as this string is part of a surname.

Your login fields are working fine for me when I enter botter.

Thats strange, it does not for me ! which browser are you using ?
I’ve tried firefox, opera, edge and chrome. they all do the same- show a blank screen after entering botter .

I’m seeing a functional login form on Chrome
Try recording the process and sending it here?

1 Like

I cant see the recorder option, but I pasted the screen shoots with the dev tools open:

and then after clicking on GO

Its just bizarre. The screen has nothing on it. But any other username (except ‘boter’) , will come back with appropriate error messages- like password missing/wrong etc.

BTW: Thanks for your attention/help.

can you turn on PHP Errors in the control panel? You can find it under the PHP Config section.


I thought i had already done that , But I’ll give it a go when the control panel starts to work again.

Control Panel is working again and it is set:

Can you upload the file /htdocs/index.php here, or copy and paste it’s contents?

Make sure to hide any sensitive information like passwords.



// Script to logon to DB, and log user on- has no security.
ini_set('date.timezone', 'Australia/Melbourne');
if (!isset($_SERVER['HTTPS'])) {
    // we are not using encryption- make it so
    //die("<br/>Incorrect address, Please use");
    //echo '<pre> ' ;   
    //print_r(__FILE__) ;   
    //echo ' </pre> <br>'; 
    if (strpos(__FILE__ ,"pellysoft/hsamtest") == false ) {
        //die("<br/>Incorrect address, Please use");
session_start(); // ensure we have a session
//clear old values
$logoff_msg ='';

if (isset($_SESSION['logoff_msg'])) {$logoff_msg = $_SESSION['logoff_msg']; }
if (isset($_GET['msg'])) {$logoff_msg = $_GET['msg']; }
//if (isset($_COOKIE['user'])) {$output_debug= 'cookie=' . $_COOKIE['user']; }
if (isset( $_COOKIE['user'])) setcookie("user",  $_COOKIE['user'], time()-3600);  /* expired */
if (isset($user_row))               unset($user_row); // dont save password in $global_rec
if (isset($global_rec))             unset($global_rec);
session_start(); // start a new session;
//$_SESSION['output_debug'] = 'Start time=' . time();

//include ("includes/header.php"); //set header and get global record
$output = '<!DOCTYPE HTML><html><head>';
$output .= '<title>HSAM(Health Services Advocates and Mediators)</title>';
$output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> ';
$output .= '<link href="stylesheets/public.css" media="all" rel="stylesheet" type="text/css" />';
$output .= '</head>';

$output .= '<div id="header">';
$output .= '<br><h2>';
$output .= 'HSAM(Health Services Advocates and Mediators)';
$output .= '</h2>';

//$output .= '</d1>';
$output .= '</div>';

$output .= '<div id="main">';
//Navigation panel
$output .= '<table id="structure"> ';
$output .= '<tr> ';
$output .= '<td id="navigation"> ';

$output .= '<ul class=main>';

$output .= '<li><a href="" title="Public Website">Public Website</a> </li>';

$output .= '</ul>'; // end list
$output .= '		</td> ';
$output .= '	<td id="page"> ';
//########################################### end of header.php

require_once ("includes/field_validator.php"); //validation routines
require_once ("includes/functions.php"); //routines
// Security check not required for logon screen.
//Check security- divert to logon page if insuffient authority

$goto = '';
if (isset($_REQUEST['$db']) && ($_REQUEST['$db'] == 'hsam' || $_REQUEST['$db'] == 'training' || $_REQUEST['$db'] == 'testing')) {
    $_SESSION['$db'] = $_REQUEST['$db'];
if (!isset($_SESSION['$db'])) {
    $_SESSION['$db'] = 'hsam';   

$output .= '<form action=' . backtrace_short() . '?db=' . $_SESSION['$db'] . ' name="Logon" method="POST">';
$output .= '</p></h2> ';
$errors = '';

$errors = '';

//Do the update?
//echo '<pre> ' ;
// print_r($_GET) ;
// echo ' </pre> <br>';
if (!isset($_SESSION['failed_logon_attempts'])) {
    $_SESSION['failed_logon_attempts'] = 0;

if (isset($_POST['submit'])) {
    $errorflag = 'n';
    $errors .= validate_U_email($_POST['U_email']);
    $errors .= validate_user_password($_POST['user_password']);
    if ($errors != '') { // invalid email address
        $_SESSION['failed_logon_attempts'] += 1;
        // $sleep_time = pow($_SESSION['failed_logon_attempts'], 2); // delay multiple attempts
        if ($sleep_time > 25) {
            $sleep_time = 25;
        } // Dont go over timeout period
        //echo 'waiting ' . $sleep_time ;
        $output .= $errors;
        $errorflag = 'y';
    } else {
        //save username,password
        if (isset($_SESSION['signon_email']) && $_SESSION['signon_email'] != $_POST['U_email']) {
            //changed userid, so clear password
        $_SESSION['signon_email'] = $_POST['U_email'];
        $_SESSION['$u_password'] = $_POST['user_password'];
        $errors .= check_user_ip($_POST['U_email']); // check that the email and ip is not bannned.
    if ($errors == '') { // not banned email or ip
        global $connection;
        $errors .= dblogon(); //Attempt to login.
    if ($errors == '') {
        //Logon to db successful
        //echo ' logon to db successfully';
        if (!isset($_SESSION['global_rec'])) {
            require_once ("includes/set_global_rec.php"); //set the global record
        //echo '<pre> ' ;
        //print_r($_SESSION['global_rec']) ;
        //echo ' </pre> <br>';
        $unit_of_work = db_query('START TRANSACTION;'); // turns off autocommit, starts a unit of work
        $sqlquery = "SELECT * FROM User WHERE `U_email` = '" . mysqli_prep($_POST['U_email']) . "';";
        $user_set = db_query($sqlquery);
        confirm_query($user_set, $sqlquery);
        $num_users = mysqli_num_rows($user_set);
        $unit_of_work = db_query('rollback;'); //rollback any changes- none should be made, but better safe
        if ($num_users == 1) {
            $user_row = mysqli_fetch_array($user_set);

            if (check_password($user_row['U_passwordhashed'], $_POST['user_password'] . $_POST['U_email'])) {
                // userid and password correct, check other
                if ($user_row['U_nbrfailedloggins'] > 10) {
                    $errorflag = 'y';
                    $errors .= ' <p align="center"><br> User has been suspended. Please confer with site Administrator to reset user.';
                    $output .= $errors;
                } else {
                    if ($user_row['U_expiry'] < date("Y-m-d")) { // expired userid?
                        $errorflag = 'y';
                        $errors .= ' <p align="center"><br> User expiry date of ' . $user_row['U_expiry'] .
                            ' has passed. Please confer with site Administrator to reset user.';
                        $output .= $errors;
                    } else {
                        // 86400 = 60*60*24 ie no seconds in a day
                        if (($user_row['U_lastlogintime'] + $_SESSION['global_rec']['param']['P_usernonuseexpiry'] * 86400) < strtotime('now')) {
                            //user has not logged in recently- he is suspended
                            $errorflag = 'y';
                            $errors .= ' <p align="center"><br> User has been suspended due to inactivity(' . date($_SESSION['global_rec']['date_format'],
                                $user_row['U_lastlogintime']) . '). Please confer with site Administrator to reset user.';
                            $output .= $errors;
                        } else { //user passed-allow signon
                            unset($user_row['U_passwordhashed']); // dont save hashed password in $global_rec
                            unset($user_row[4]); // dont save hashed password in $global_rec
                            if (isset($global_rec['user'])) {
                            $global_rec['user'] = $user_row;
                            $_SESSION['global_rec']['user'] = $global_rec['user'];
                            //echo 'login success';
                            $sqlquery = "UPDATE User SET  `U_nbrfailedloggins` = 0 ";
                            if ($user_row['U_lastlogintime'] < time()) {
                                //only set lastlogin time if less than current time.
                                $sqlquery .= ", `U_lastlogintime` = " . time();
                            $sqlquery .= " WHERE `U_email` = '" . mysqli_prep($_POST['U_email']) . "';";
                            $user_set = db_query($sqlquery);
                            confirm_query($user_set, $sqlquery);
                            //setcookie("user", $_SESSION['global_rec']['user']['U_email'], time() + 3600);
                            setcookie("user", $_SESSION['global_rec']['user']['U_email']); //dont expire
                            /* expire in 1 hour */
                            //    echo '<pre> ' ;
                            //    print_r($_SESSION) ;
                            //    echo ' </pre> <br>';
                            reset_user_ip($_POST['U_email']); //reset failed count in txt file
                            if ((strtotime($user_row['U_lastpasswordchangedate']) + $_SESSION['global_rec']['param']['P_usernonuseexpiry'] * 86400) <
                                strtotime('now')) {
                                //password needs to be changed- redirect to change password screen.
                                redirect_to('user_change.php?db=' . DB_NAME . '&fromlogon=yes');
                            } else {
                                redirect_to('issue_view.php?db=' . DB_NAME);
            } else { //invalid password- update failed count
                $errorflag = 'y';
                $output .= ' <p align="center"><br> User email or password is invalid. Try again';
                $sqlquery = "UPDATE User SET  `U_nbrfailedloggins` = `U_nbrfailedloggins` + 1 " . "WHERE `U_email` = '" . mysqli_prep($_POST['U_email']) .
                $user_set = db_query($sqlquery);
                confirm_query($user_set, $sqlquery);
                $sleep_time = pow($user_row['U_nbrfailedloggins'], 2); // delay multiple attempts
                if ($sleep_time > 25) {
                    $sleep_time = 25;
                } // Dont go over timeout period
            //echo '<pre> ' ;
            //print_r($user_row) ;
            //echo ' </pre> <br>';
        } else {
            // cant find userid or too many records effected!- so can't update counts
            $_SESSION['failed_logon_attempts'] += 1;
            $sleep_time = pow($_SESSION['failed_logon_attempts'], 2); // delay multiple attempts
            if ($sleep_time > 25) {
                $sleep_time = 25;
            } // Dont go over timeout period
            $errorflag = 'y';
            $output .= ' <p align="center"><br> User email and password combination is invalid. Try again';
        $unit_of_work = db_query('commit;'); // ensure valid changes are committed, and back to autocommit
    } else {
        // cant logon to db!- so can't update DB counts
        $_SESSION['failed_logon_attempts'] += 1;
        $sleep_time = pow($_SESSION['failed_logon_attempts'], 2); // delay multiple attempts
        if ($sleep_time > 25) {
            $sleep_time = 25;
        } // Dont go over timeout period
        $errorflag = 'y';
        $output .= $errors;

    if ($errorflag == 'n') {
        //no errors, exit if errors where encountered- redisplay the screen by bypasing the exit.
        $goto = 'endit';
    } //else { // invalid signon- }
} //if isset($_POST)

if ($goto == '') {
    unset($user_row); // clear it
    $output .= $logoff_msg; // display the logoff message.
    $output .= ' <p align="center"><br> Enter User email and password, then click GO to logon.<br>';
    //Go button
    $output .= '<input type="submit" name="submit" value="Go" />';

    $output .= '<table id="box-table-a" align="center" summary="Menu Update" width="100%"';
    $output .= '<thead> ';

    $output .= '<tr> ';
    $output .= '<th>User Email address:</th> ';
    $output .= '<td> <input type="text" name="U_email" value="" size="25" maxlength="150"/></td>  ';
    $output .= '</tr> ';

    $output .= '<tr> ';
    $output .= '<th>User Password:</th> ';
    $output .= '<td> <input type="password" name="user_password" value="" size="15" maxlength="40"/></td>  ';
    $output .= '</tr> ';

    $output .= '<tr> ';
    $output .= '<th>Db name:</th> ';
    $output .= '<td>    <select name="db" title="Database name" >';
    $output .= '<option >' . 'hsam' . '</option>';
    $output .= '<option >' . 'training' . '</option>';
    if (strpos(__FILE__ ,"pellysoft/hsamtest") == false ) {
        $output .= '<option >' . 'testing' . '</option>';
    } else {
        $output .= '<option selected >' . 'testing' . '</option>';

    $output .= '</tr> ';

    $output .= '</thead> ';
    $output .= ' <tbody> ';
    $output .= '</table>';
    //Reset button
    //$output .= '<p align="center"><br> <input type="submit" name="reset" value="Forgot password?" />';

$output .= '</form>';
include ("includes/footer.php");
echo $output;

It’s because you have a banned IP/user/word/domain in this file

btw. you have some kind of problem here

Warning: require_once(includes/functions.php): failed to open stream: No such file or directory in /home/vol15_7/ on line 3

Fatal error: require_once(): Failed opening required ‘includes/functions.php’ (include_path=‘.:/usr/share/pear/’) in /home/vol15_7/ on line 3


Nope. That’s not it. That file is only used to check the logon. The issue first appeared on a screen that is not checked against this file. The logon screen was then checked and it too exhibited the same issue- ie a blank screen. After too many failed attempts, botter was added to that file.
Had it been an issue with that banned file, it should have displayed an error message, not a blank white screen,

However, that:
Fatal error: require_once(): Failed opening required ‘includes/functions.php’ (include_path=‘.:/usr/share/pear/’) in /home/vol15_7/ on line 3

possibly could be the cause. I’ll check it/ test it tonight.
I’ll keep you posted.
Thanks for your help

You know your code

It is possible that the ban is recorded somewhere in the DB and this file is for information only or log.

I see the same all-white as you (I don’t see it as in your title → that PHP crashes) there is no E500.
So it could be some form of the ban so the script just doesn’t want to continue
or your code didn’t catch the error and doesn’t know what to display.

It reacts to anything containing the word “botter” such as 1234botter

1 Like

yep as you pointed out, it also fails (white screen) even when BOTTER or BOTER is surrounded by other text.
Don’t be stuck on the banned functionality as the logon screen is only a quick way to demonstrate the issue. It was first reported on a client surname - once a user was already logged in. And also showed up when trying to view the log.
As its also occurring on the logon screen, it proves that the issue is not related to the database, it has not connected yet.

I commented out the line, that had the Fatal error: require_once(): Unfortunately it made no difference and botter still fails. Without botter, some of the site works - but some pages complain about the missing require_once. So I put it back in, as its not the issue.

Its a real head scratcher.

In the firefox console log, i see this error message:
Unknown category for SetEventRecordingEnabled: page_load
could it be the starting place to look?

If I were in your place…

For example notepad++ has the option to search for a term in all files in a directory,
so if you have those php files locally, try searching for “botter” (inside dir) and see the results…

Unless maybe some stupid thing happened and the two terms were combined through codes

for example :one part is bot
and some other codes add ter to it
so you get that botter

The fastest solution is for the user to change his last name and make a new ID card :smile:

1 Like

We do have some blocked keywords, but as far as I know “botter” isn’t one of them. As far as I can tell, this is due to your code.

I tried to find the solution and did a little bit of debugging. But strangely enough when I added a little debug statement after line 92, it didn’t print the debug statement and instead redirected me back to the home page.

What is actually supposed to happen in this case? Is the page supposed to redirect or show contents?

Also, probably unrelated, but you may be interested to know PHP has Output Buffering functions. That way, you can use all your regular echo statements or even close the PHP tag to write HTML, and at the end call ob_flush() to send the content. It’s up to you whether you want to use it, but it may be a bit easier to work with than writing everything to a string.


I did search for Botter, but not on the split term. I now have for BOT but nothing relevant showed up - except lots of BOTH and BOTTOM. I did ignore case. Searching TER is more problematic as its everywhere as in criteria, center etc.

1 Like

Hi Admin. You wont be able to change the code. It will detect the change and reverse it. I saw 4 attempts to alter the code.
I have had an issue in the past where a compromised trusted user had an infection that altered the site.
Unfortunately this has also caused me to write the code that may be a bit difficult to follow.
If you like I can temporarily disable this functionally.

Can you please check. As that could explain the issue.

I will also investigate the PHP Output Buffering functions.

Thanks to everyone for your help.

I’m curious how this system works exactly. Are you constantly re-uploading the files over FTP? Or does your PHP code do integrity checks on itself?

Disabling this system would help a lot in trying to diagnose this. I promise I will try to leave the code exactly as I found it, but you may want to make sure you have a copy of the code yourself you can use to overwrite any live changes.

Not really. I don’t have access to the full block lists and there are different block lists in different places, and none of them show the behavior we see on your site here. The fact that I was able to get this behavior to change by editing the code makes me believe that it’s not a hosting issue.

And I don’t really feel like looking for something I think doesn’t exist and I don’t know where it would be if it did.