Skip to content
Advertisement

Removing eval from PHP function [closed]

I want to know if there is a way to remove eval() from my code.

In this function I load by POST some vars to update or insert a new user on my DB based on what the admin has inserted on the form.

public function alterUser()
{
    
    $name = $_POST['name']; //required field 
    $contact = $_POST['contact']; //required field 
    $password = $_POST['password']; //required field 
    
    $string = "DB::table('users')";
    
    if(isset($_POST['id'])){
        $string = $string."-> where ('id', $_POST['id']) ->update([";
    }else{
        $string = $string."-> insert([";
    }
    
    $string = $string."'name' => $_POST['name'],";
            
    if (isset($_POST['email'])) 
        $string = $string."'email' => $_POST['email'],";
    
    $string = $string."'password' => Hash::make($password),'contacto' => $contact,";
    
    if (isset($_POST['nif'])) 
        $string = "$string.'nif' => $nif,";
    
    $string = $string."]);";

    eval($string);
    return redirect('/user');
}

As this opens some security vulnerabilities there are any other alternatives to get this working?

Advertisement

Answer

It seems like you could simplify your code a lot, and remove the need for eval() which you shouldn’t use unless it is a last resort.

There is no need for all the IF blocks had in your code, because if the value isn’t set, it also won’t be added to the $values array.

Just assign your $_POST variable to a $values variable, Laravel does most of the heavy lifting for you.

public function alterUser()
{

    $values = $_POST;

    //remove _token variable created by Laravel in all POST requests
    unset($values['_token']); 

    //perform any actions needed on values before being send to database
    $values['password'] = Hash::make($values['password']);

    if(!empty($values['id'])) {
        DB::table('users')->insert($values);
    } else {
        DB::table('users')->where('id', $values['id'])->update($values);
    }
    
    return redirect('/user');
}

I see in your code that you rename the contact variable to contacto. I recommend changing your form to match this variable name, but if that isn’t possible, you can still rename it after setting $values = $_POST like this:

$values['contacto'] = $values['contact'];
unset($values['contact']);

Also, if your form sends any variables that you do NOT want to send to the database, such as a “password verify” field or something like that, then you can unset them after setting $values = $_POST like this:

unset($values['VALUE_TO_REMOVE']);
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement