0

I am currently working through my code and trying to implement measures to protect from SQL injections. My other pages work fine however this page is a little different.

The user is to determine which table they are to delete from, this is by using the $Level variable, (don't worry, this is restricted to three). It worked with the old vulnerable method but doesn't now. Any ideas?

if (isset($_POST['Delete']))
{
$Level = trim($_POST['Level']);
$UserName = trim($_POST['UserName']);
//----------------Check if Exists------------------//
$Check = $conn->prepare("SELECT * FROM ? WHERE UserName = ?");
$Check->bind_param('ss', $Level, $UserName);
$Check->execute();
$result = $Check->get_result();
$count = $result->num_rows;
if ($count>0)
{   
    $Confirm= $UserName . ' Deleted';
    //----------------Delete SQL-------------------//
    $Delete = "DELETE FROM $Level WHERE UserName = '$UserName'";
    $Delete = mysqli_query($conn,$sql);
    header( "refresh:5;url=stratdeleteuser.php" );
}
else 
{
    $Confirm= 'No Matches Found';
}

}

Albertoe86
  • 35
  • 6
  • You let the user send you the name of the table to delete from?? Without even validating whether it's a table you want them to be deleting from? Anyway, I'm pretty sure you can't use a variable for the table when using bind_param –  Nov 07 '15 at 21:26
  • My my, your a pleasant bunch...And absolutely not, the user is to select it with a select box, would that suffice then? – Albertoe86 Nov 07 '15 at 21:29
  • 1
    What would happen if I replace your select box with an input field of same name? What would happen if I send post request with proper fields to your form submit script? – u_mulder Nov 07 '15 at 21:31
  • 1
    You tell me matey, I am new to this – Albertoe86 Nov 07 '15 at 21:31
  • 1
    Just have a little switch case that statement for $level with valid tables as cases and the default raises an error. Or have an array filled with valid table names and raise an error if $level is !in_array. Just remember that any client-side check can be circumvented –  Nov 07 '15 at 21:34
  • There we go...thanks Terminus – Albertoe86 Nov 07 '15 at 21:36
  • 1
    You should also probably stick to using OO style for the delete stmt and keep using bind_param for $username. –  Nov 07 '15 at 21:36
  • 1
    Hehe thanks, i was working my way through the existing code, not got down there yet, appreciate the help – Albertoe86 Nov 07 '15 at 21:37

1 Answers1

1

An if statement would suffice to protect the user input

if ($Level == 'strategic' || $Level == 'tactical')
{
    //----------------Check if Exists------------------//
    $Check = $conn->prepare("SELECT * FROM $Level WHERE UserName = ?");
    $Check->bind_param('s', $UserName);
    $Check->execute();
    $result = $Check->get_result();
    $count = $result->num_rows;
    if ($count>0)
    {   
        $Confirm= $UserName . ' Deleted';
        //----------------Delete SQL-------------------//
        $Delete = $conn->prepare("DELETE FROM $Level WHERE UserName = ?");
        $Delete->bind_param('s', $UserName);
        $Delete->execute();
        $Confirm = $UserName . ' Deleted';
        header( "refresh:5;url=stratdeleteuser.php" );
    }
    else 
    {
        $CheckErr= 'No Matches Found';
    }
}

I took care of the latter part for you to implement the OO style as Terminus rightfully suggested

ababusa
  • 240
  • 2
  • 10
  • 1
    Yeah, that's similar to what I was going for, thanks for looking into the second part, was struggling with that as it happens – Albertoe86 Nov 07 '15 at 22:54