Jump to content

rechecking my PDO


Richard_Grant
Go to solution Solved by Jacques1,

Recommended Posts

Okay i have a function


function p_d_o($options, $func){//$options is a multidimensional array

..Parse $option to strings..
//when echoed $query looks like this:

//$vars[":val_0", "14084"]; // this is the only value retrieved from $_POST or $_GET all other values are from PHP function calls
//SELECT RAND_CODE,USERNAME FROM table WHERE RAND_CODE LIKE :val_0 LIMIT 5";
     $query = $cols_ . ' FROM ' . $options["table"] . ' ' . $options["conditional"] . ' ' . (($options["limitted"])?  $cond_ . ' LIMIT ' . $options["limitted"] : "");
          $secure_mysqli = $con->prepare($query);

          $secure_mysqli->execute($vars); //vars contains :val_0
     while($item = $secure_mysqli->fetch(PDO::FETCH_ASSOC)){
          $func($query);
     }
}

My question is Should i be worried about the other parts of the query string that is not being binded? I was having issues binding table name and cols.

Edited by Richard_Grant
Link to comment
Share on other sites

You indeed cannot pass identifiers like column or table names to a prepared statements, and that's indeed a problem.

 

There are basically two solutions: Either you avoid this scenario altogether, or you use a whitelist of acceptable identifiers. Theoretically, you might also try a kind of generic validation so that you can use entirely dynamic queries (which seems to be your goal). But this is risky and fragile, so I'd avoid it at all cost. Even the big database frameworks shy away from this.

Link to comment
Share on other sites

You indeed cannot pass identifiers like column or table names to a prepared statements, and that's indeed a problem.

 

There are basically two solutions: Either you avoid this scenario altogether, or you use a whitelist of acceptable identifiers. Theoretically, you might also try a kind of generic validation so that you can use entirely dynamic queries (which seems to be your goal). But this is risky and fragile, so I'd avoid it at all cost. Even the big database frameworks shy away from this.

 

Would you scold me for using mysqli_real_escape_string ? (if it would even let me use my pdo connection as the connection variable)

Link to comment
Share on other sites

  • Solution

Would you scold me for using mysqli_real_escape_string ?

 

You mean for identifiers? This doesn't work. mysqli_real_escape_string() only works within quoted string values. It only prevents users from “breaking out” of the quoted expression. If there are no quotes, the whole function is useless.

 

By the way, the PDO equivalent of mysqli_real_escape_string() is PDO::quote().

  • Like 1
Link to comment
Share on other sites

You mean for identifiers? This doesn't work. mysqli_real_escape_string() only works within quoted string values. It only prevents users from “breaking out” of the quoted expression. If there are no quotes, the whole function is useless.

 

By the way, the PDO equivalent of mysqli_real_escape_string() is PDO::quote().

 

My table name and col are passed in as a string parameter so PDO::quote should work just fine for me

Link to comment
Share on other sites

I think this is a misunderstanding. If you put the table name into an SQL string, you'll get a syntax error:

SELECT * FROM 'this_is_invalid';

Identifiers are not strings, so you cannot use PDO::quote().

 

Like I said, there's no easy solution. In fact, it's impossible to prevent SQL injections with the function itself, because you want it to accept complete SQL clauses (like the WHERE clause). Your only chance is to carefully validate all input before you pass it to the function.

 

You should also consider using professional database frameworks like Doctrine. They don't entirely solve the problem either, but they're more mature and easier to control.

Edited by Jacques1
Link to comment
Share on other sites

I think this is a misunderstanding. If you put the table name into an SQL string, you'll get a syntax error:

SELECT * FROM 'this_is_invalid';

Identifiers are not strings, so you cannot use PDO::quote().

 

Like I said, there's no easy solution. In fact, it's impossible to prevent SQL injections with the function itself, because you want it to accept complete SQL clauses (like the WHERE clause). Your only chance is to carefully validate all input before you pass it to the function.

 

You should also consider using professional database frameworks like Doctrine. They don't entirely solve the problem either, but they're more mature and easier to control.

 

. Its really spaghetti and if i didn't spend hours setting up my server to use PDO i would switch to mysqli

Edited by Richard_Grant
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.