Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3660832
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 19, 20262026-05-19T01:14:39+00:00 2026-05-19T01:14:39+00:00

Greetings, A site I designed was compromised today, working on damage control at the

  • 0

Greetings,

A site I designed was compromised today, working on damage control at the moment. Two user accounts, including the primary administrator, were accessed without authorization. Please take a look at the log-in script that was in use, any insight on security holes would be appreciated. I am not sure if this was an SQL injection or possibly breach on a computer that had been used to access this area in the past.

Thanks

<?php
    //Start session
    session_start();
    //Include DB config
    require_once('config.php');

    //Error message array
    $errmsg_arr = array();
    $errflag = false;
    //Connect to mysql server
    $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
    if(!$link) {
        die('Failed to connect to server: ' . mysql_error());
    }
    //Select database
    $db = mysql_select_db(DB_DATABASE);
    if(!$db) {
        die("Unable to select database");
    }

    //Function to sanitize values received from the form. Prevents SQL injection
    function clean($str) {
        $str = @trim($str);
        if(get_magic_quotes_gpc()) {
            $str = stripslashes($str);
        }
        return mysql_real_escape_string($str);
    }
    //Sanitize the POST values
    $login = clean($_POST['login']);
    $password = clean($_POST['password']);

    //Input Validations
    if($login == '') {
        $errmsg_arr[] = 'Login ID missing';
        $errflag = true;
    }
    if($password == '') {
        $errmsg_arr[] = 'Password missing';
        $errflag = true;
    }

    //If there are input validations, redirect back to the login form
    if($errflag) {
        $_SESSION['ERRMSG_ARR'] = $errmsg_arr;
        session_write_close();
        header("location: http://somewhere.com");
        exit();
    }

    //Create query
    $qry="SELECT * FROM user_control WHERE username='$login' AND password='".md5($_POST['password'])."'";
    $result=mysql_query($qry);

    //Check whether the query was successful or not
    if($result) {
        if(mysql_num_rows($result) == 1) {
            //Login Successful
            session_regenerate_id();
            //Collect details about user and assign session details
            $member = mysql_fetch_assoc($result);
            $_SESSION['SESS_MEMBER_ID'] = $member['user_id'];
            $_SESSION['SESS_USERNAME'] = $member['username'];
            $_SESSION['SESS_FIRST_NAME'] = $member['name_f'];
            $_SESSION['SESS_LAST_NAME'] = $member['name_l'];
            $_SESSION['SESS_STATUS'] = $member['status'];
            $_SESSION['SESS_LEVEL'] = $member['level'];
            //Get Last Login
            $_SESSION['SESS_LAST_LOGIN'] = $member['lastLogin'];
            //Set Last Login info
            $qry = "UPDATE user_control SET lastLogin = DATE_ADD(NOW(), INTERVAL 1 HOUR) WHERE user_id = $member[user_id]";
            $login = mysql_query($qry) or die(mysql_error());
            session_write_close();
            if ($member['level'] != "3" || $member['status'] == "Suspended") {
                header("location: http://somewhere.com");
            } else {
                header("location: http://somewhere.com");
            }
            exit();
        }else {
            //Login failed
            header("location: http://somewhere.com");
            exit();
        }
    }else {
        die("Query failed");
    }
?>

UPDATE

Here is an updated version of the security script, please let me know what you think. Added a little SALT and a table to block both IP addresses (disabling the login form itself) and individual users after failing to authenticate four times. A Mayday email is also sent to an Admin and the user is notified that they have exceeded the limit.

Any critiques would be appreciated!

<?php
    //Start session
    session_start();
    //Include DB config
    include $_SERVER['DOCUMENT_ROOT'] . '/includes/pdo_conn.inc.php';

    //Error message array
    $errmsg_arr = array();
    $errflag = false;

    //Function to sanitize values received from the form. Prevents SQL injection
    function clean($str) {
        $str = @trim($str);
        if(get_magic_quotes_gpc()) {
            $str = stripslashes($str);
        }
        return $str;
    }

    //Define a SALT
    define('SALT', 'heylookitssuperman');

    //Sanitize the POST values
    $login = clean($_POST['login']);
    $password = clean($_POST['password']);
    //Encrypt password
    $encryptedPassword = md5(SALT . $password);
    //Input Validations
    //Obtain IP address and check for past failed attempts
    $ip_address = $_SERVER['REMOTE_ADDR'];
    $checkIPBan = $db->prepare("SELECT COUNT(*) FROM ip_ban WHERE ipAddr = ? OR login = ?");
    $checkIPBan->execute(array($ip_address, $login));
    $numAttempts = $checkIPBan->fetchColumn();
    //If there are 4 failed attempts, send back to login and temporarily ban IP address
    if ($numAttempts == 1) {
        $getTotalAttempts = $db->prepare("SELECT attempts FROM ip_ban WHERE ipAddr = ? OR login = ?");
        $getTotalAttempts->execute(array($ip_address, $login));
        $totalAttempts = $getTotalAttempts->fetch();
        $totalAttempts = $totalAttempts['attempts'];
        if ($totalAttempts >= 4) {
            //Send Mayday SMS
            $to = "admin@somewhere.com";
            $subject = "Banned Account - $login";
            $mailheaders = 'From: noreply@somewhere.com' . "\r\n";
            $mailheaders .= 'Reply-To: noreply@somewhere.com' . "\r\n";
            $mailheaders .= 'MIME-Version: 1.0' . "\r\n";
            $mailheaders .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
            $msg = "<p>IP Address - " . $ip_address . ", Username - " . $login . "</p>";
            mail($to, $subject, $msg, $mailheaders);
            $setAccountBan = $db->query("UPDATE ip_ban SET isBanned = 1 WHERE ipAddr = '$ip_address'");
            $setAccountBan->execute();
            $errmsg_arr[] = 'Too Many Login Attempts';
            $errflag = true;    
        }
    }
    if($login == '') {
        $errmsg_arr[] = 'Login ID missing';
        $errflag = true;
    }
    if($password == '') {
        $errmsg_arr[] = 'Password missing';
        $errflag = true;
    }

    //If there are input validations, redirect back to the login form
    if($errflag) {
        $_SESSION['ERRMSG_ARR'] = $errmsg_arr;
        session_write_close();
        header('Location: http://somewhere.com/login.php');
        exit();
    }

    //Query database
    $loginSQL = $db->prepare("SELECT password FROM user_control WHERE username = ?");
    $loginSQL->execute(array($login));
    $loginResult = $loginSQL->fetch();

    //Compare passwords
    if($loginResult['password'] == $encryptedPassword) {
        //Login Successful
        session_regenerate_id();
        //Collect details about user and assign session details
        $getMemDetails = $db->prepare("SELECT * FROM user_control WHERE username = ?");
        $getMemDetails->execute(array($login));
        $member = $getMemDetails->fetch();
        $_SESSION['SESS_MEMBER_ID'] = $member['user_id'];
        $_SESSION['SESS_USERNAME'] = $member['username'];
        $_SESSION['SESS_FIRST_NAME'] = $member['name_f'];
        $_SESSION['SESS_LAST_NAME'] = $member['name_l'];
        $_SESSION['SESS_STATUS'] = $member['status'];
        $_SESSION['SESS_LEVEL'] = $member['level'];
        //Get Last Login
        $_SESSION['SESS_LAST_LOGIN'] = $member['lastLogin'];
        //Set Last Login info
        $updateLog = $db->prepare("UPDATE user_control SET lastLogin = DATE_ADD(NOW(), INTERVAL 1 HOUR), ip_addr = ? WHERE user_id = ?");
        $updateLog->execute(array($ip_address, $member['user_id']));
        session_write_close();
        //If there are past failed log-in attempts, delete old entries
        if ($numAttempts > 0) {
            //Past failed log-ins from this IP address. Delete old entries
            $deleteIPBan = $db->prepare("DELETE FROM ip_ban WHERE ipAddr = ?");
            $deleteIPBan->execute(array($ip_address));
        }
        if ($member['level'] != "3" || $member['status'] == "Suspended") {
            header("location: http://somewhere.com");
        } else {
            header('Location: http://somewhere.com');
        }
        exit();
    } else {
        //Login failed. Add IP address and other details to ban table
        if ($numAttempts < 1) {
        //Add a new entry to IP Ban table
        $addBanEntry = $db->prepare("INSERT INTO ip_ban (ipAddr, login, attempts) VALUES (?,?,?)");
        $addBanEntry->execute(array($ip_address, $login, 1));
        } else {
            //increment Attempts count 
            $updateBanEntry = $db->prepare("UPDATE ip_ban SET ipAddr = ?, login = ?, attempts = attempts+1 WHERE ipAddr = ? OR login = ?");
            $updateBanEntry->execute(array($ip_address, $login, $ip_address, $login));
        }
        header('Location: http://somewhere.com/login.php');
        exit();
    }
?>
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-19T01:14:39+00:00Added an answer on May 19, 2026 at 1:14 am

    This is by no means comprehensive, and may include elements of general review:

    • The die() call upon a connection failure calls out to mysql_error(), which may leak sensitive information (database host, username)
    • In general, always try to pass the second argument (the connection handle) to mysql_real_escape_string(), which allows it to ensure that the value is properly escaped with regards to the character set et al. of the connection
    • Your header() call contains the string “location”; the correct header name is “Location”
    • You sanitise $_POST['password'] but then inject it back into the SQL with md5( $_POST['password'] ); although (due to the behaviour of md5()) this won’t introduce a vulnerability, it would potentially break in an environment where get_magic_quotes_gpc() was switched on, and is just a bit inconsistent
    • Your call to mysql_query() doesn’t specify the connection handle – although in this script, there’s unlikely to be another one lying around, I like to be explicit when talking to MySQL – it gives me the warm fuzzies

    You appear to be storing passwords hashed – good – though using MD5 (not so good, arguably), but with no salting of any kind – this means that if someone’s gotten hold of your password hashes, then they could use rainbow tables/brute force to try to crack passwords. That said, you may argue (and I’d happily accept) that if someone’s got onto the box and obtained that data, then you have other potential problems.

    I’d recommend having a read of http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html, which will explain why a per-user salt will help, and the real reason MD5 is probably not the best choice for a password hashing function any more.

    Without wanting to step outside the scope of this answer, and speculate too much; could session hijacking be the culprit here? (I don’t know anything about how your sessions are resumed, but it seems reasonable your code may be “trusting” the session data. Of course, this is not easy to defeat for certain – tying sessions to IP addresses is a good start, for instance.)

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.