简体   繁体   中英

Is my code safe for injection?

I was using MySQL before, and was told it was unsafe, so now I have recoded my admin login panel in PDO, which users here and other forums said can not be injected. But the hacker is still getting in... I edited the page after the login and told the hacked to tell me what I've put on it and the hacker told me...

I need to know if my code is safe. He is telling me that he is getting in though SQL.

So first I stored their IP in a session so if their IP changes it will log them out (or username)

if ( isset($_SESSION['last_ip']) == false )
{
    $_SESSION['last_ip'] = $_SERVER['REMOTE_ADDR'];
}
if ( $_SESSION['last_ip'] !== $_SERVER['REMOTE_ADDR'] )
{
    session_unset();
    session_destroy();
}

Then here is my login:

session_start();
include 'functions/functions.php';  
$db = mysqlconnect();
$password = md5($_POST['mypassword']);
$mod = 1; 
$statement = $db->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$statement->execute(array($_POST['myusername'],$password));
$result = $statement->fetchObject()->mod;
$count = $statement->rowCount();
if ( $result == 1 ) {
    $db = mysqlconnect();
    // Register $myusername, $mypassword and redirect to file "login_success.php"
    $_SESSION['user'] = $_POST['myusername'] ;
    //Test if it is a shared client
    if ( !empty($_SERVER['HTTP_CLIENT_IP']) ) {
        $ip=$_SERVER['HTTP_CLIENT_IP'];
        //Is it a proxy address
    } elseif ( !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ) {
        $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    } else {
        $ip=$_SERVER['REMOTE_ADDR'];
    }
    $sqll = "UPDATE users SET lastip=? WHERE username=?";
    $q = $db->prepare($sqll);
    $q->execute(array($ip,$_SESSION['username']));
    $_SESSION['user'] = $_POST['myusername'] ;
    $sqlll = "INSERT INTO user_log (username,ip) VALUES (?, ?)";
    $qq = $db->prepare($sqlll);
    $qq->execute(array($_SESSION['username'],$ip));
    header("Location: home.php");
} else {
    echo "Wrong Username or Password";
}

Can the code be injected ?

And this is my home.php page which stops users from viewing it.

/// My conenct is here                    
$sql = "SELECT * FROM users WHERE username='$_SESSION[user]'";
$result = mysql_query($sql) or die(mysql_error());
$values = mysql_fetch_array($result);


if( isset($_SESSION['user']) ) {

} else {
    echo "Bye Bye";
    die;
}

if ( $values['mod'] == 1 ) {    
    echo "welcome";  
} else {
    echo"Your account has been reported for hacking";
    die;
}

Assuming the queries you show are the only queries you use, it's funny how the hacker uses the very code you thought would block him. Very often in the IT world the front door is triple locked but the backdoor is open. In this case it's not the backdoor, but the little window in the door that you use to see if you are not opening to a crook.

Use prepared statements and variable binding on all queries.

That is the general rule. You just forgot the "all" in "all queries".

Your statement:

$sql = "SELECT * FROM users WHERE username='$_SESSION[user]'";

is your open window. Quite obviously your hacker spoofed the username in the session data. The simple solution is to:

  1. validate the username or any data you receive from outside ($_SESSION, $_POST, some $_SERVER and others) BEFORE you do anything with it. Certainly before you perform any database interaction.
  2. use variable binding like you did in the other queries.

Removing tags or using mysql_real_escape_string is of less value in this case because the hack is perfectly possible without any unstorable characters.

By the way you don't really need to use PDO to use variable binding. It is perfectly possible in mysql too.

$verbLok = mysqli_connect(Iam, not, gonna, tellyou);
$result = array();
if (($stmtLok = $verbLok->prepare( "SELECT * FROM users WHERE username = ?  limit 1")))
{        
    $stmtLok->bind_param("s", $_SESSION[user]);
    $stmtLok->execute();
    $result = $stmtLok->get_result();
    $stmtLok->close();
}
mysqli_close($verbLok);

should do the trick for you. $result will hold an array of result rows. I am not too familiar with conventional queries anymore, but as far as I remember it's similar to your code.

Interesting reading on how a SQL code injection attack is possible on your query can be found on this page .

A good SQL Injection prevention would be to escape any and all text that could be used to terminate the SQL command mid-evaluation to start a new command.

To do that you should escape any quotes in the input, and use better SQL — use backticks around fields and table names, use quotes to wrap any non-code text, etc.

SELECT * FROM `users` WHERE `id` = '1'

Then escape all quotes with mysql_real_escape_string , or by manual replacements with #039; etc, also to be sure escape any HTML to make sure it doesn't mess up other things, use htmlentities etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM