views:

187

answers:

8

I'm in the process of building a site with CodeIgniter. This is the 1st site that I've built myself that interacts with a database. I'm using MySQL for this project. How can I tell if data needs to be escaped before saving it to the database?

+1  A: 

When in doubt, escape it all. Can't be too safe.

Alright, alright. I get it

ALWAYS ESCAPE

Mike B
never trust the user.
Josiah
thats wrong answer. Your, @Josiah too. There is nothing user or doubts relevant. There is nothing relevant at all. Escaping is unconditional procedure.
Col. Shrapnel
+1 to Col. Shrapnel. Escaping is not actually a security issue, escaping is the way of making query valid.
zerkms
@Shrapnel and @zerkms Making a query valid sounds like a good thing? What am I missing?
Mike B
@Mike: remove "doubt" and "too safe". the only one rule is "always". programmer shouldn't think about "to escape or not"
zerkms
This must be certain act. Redundant escaping will spoil the data.
Col. Shrapnel
Escaping is not a "when in doubt" situation. It is an "always" situation.
thomasrutter
So, to clarify, I need to escape my queries to ensure that they're valid, and I need to escape my submissions for security/validity measure? Did I get that right?
Lenwood
+4  A: 

Don't worry about escaping yourself (you WILL screw it up). Use a DB layer where you prepare the statement first, and then add data to it.

In PHP you should use PDO. You write

SELECT * FROM table WHERE key = :key AND value = :value

and then add the data in by calling functions.

Paul Tarjan
A: 

When to escape? As soon as your site goes public.

ggfan
terrible wrong mistake. Right answer - As soon as you start to work with database
Col. Shrapnel
@Col: write your own answer please so we can +1 it as better ;-) (not irony)
zerkms
+2  A: 

If the data is a string, it must always be escaped.

However, it's better to use parameters instead.

SLaks
+3  A: 

If you're using the database class with query bindings, you don't have to do any manual escaping:

The secondary benefit of using binds is that the values are automatically escaped, producing safer queries. You don't have to remember to manually escape data; the engine does it automatically for you.

Daniel
To the downvoter, please care to elaborate ;) Heck, it's the only answer relevant to CodeIgniter.
Daniel
i've downvoted because of silly second part. it's irrelevant to question and terrible idea itself. if you need in filtering data because of business logic expects - do this, but don't this to trying secure something.
zerkms
+1 correct and provides references. It even makes use of the fact that the Question asker is using codeigniter
Jonathan Fingland
@zerkms: filtering on input or on output depends a lot on the use cases. filtering input is not inherently wrong.
Jonathan Fingland
@Jonathan Fingland: filtering not correlating to escaping. at all. any string data **always** should be escaped. don't confuse OP.
zerkms
Yep, validation/filtering is a separate concern.
VolkerK
@zerkms: granted. good point. The OP is clearly a novice by his own admission, And I interpreted it as a broader question than literally stated. If taken strictly, then filtering was not what was asked for.
Jonathan Fingland
That settles it then, edited ;)
Daniel
I'm glad I asked. I need to do A LOT more reading. Most of my code is developed after watching tutorials, and this never came in any of them.
Lenwood
A: 

You escape a MySQL query string when any of the string is made up of user input, for example:

in PHP: $username = ;//VALUE FROM USER INPUT

then your query string is: "INSERT INTO table ('username') VALUES (".$username.")"

You would have to escape this mySQL query due to the fact the $username variable could potentionally have malicous code inserted by the client to be injected into your database.

AjayP
Not a query string but data string. Not when any of the string is made up of user input,but just **any string**. Go figure
Col. Shrapnel
+8  A: 

I would advice you to accustom yourself to use prepared statements. Especially since you are new to working with databases. The sooner you start using these, the easier it becomes a second nature.

I, for instance, didn't know about prepared statements when I started with databases. And I experienced my own stubborness when I came in touch with them. Because I had accustomed myself to another way of doing things already. Now, this might not be a character trade of yourself, but it doesn't hurt to start as soon as possible with it either way.

Prepared statements allow you to use placeholders in queries. These placeholders can then be substituted with actual values by binding them to the placeholders. This process of binding, automatically escapes the values.

Here's a (simple) PDO example:

$db = new PDO( /* some database parameters */ );
$statement = $db->prepare( 'INSERT INTO table VALUES( :username, :password )' );
$statement->bindValue( ':username', $dirtyUsername );
$statement->bindValue( ':password', $dirtyPassword );
$result = $statement->execute();
// result checking ommited for brevity

There's lot's more possibilities with PDO and prepared statements. For instance you can easily reuse the prepared statement in a loop, as such:

$statement = $db->prepare( 'INSERT INTO table VALUES( :username, :password )' );
foreach( $users as $dirtyUser )
{
    $statement->bindValue( ':username', $dirtyUser->username );
    $statement->bindValue( ':password', $dirtyUser->password );
    $result = $statement->execute();
    // result checking ommited for brevity
}

Or pass the placeholder bindings to the execute method, like so:

$statement = $db->prepare( 'INSERT INTO table VALUES( :username, :password )' );
$result = $statement->execute( array( 
                                   ':username' => $dirtyUsername, 
                                   ':password' => $dirtyPassword
                             ) );
// result checking ommited for brevity

... etc., etc.

fireeyedboy
Process of binding does no escaping. The rest is ok
Col. Shrapnel
In the case of using PDO it actually might (ok, not the call to bindParam() itself exactly). When the ATTR\_EMULATE\_PREPARES flag is set (or forced because the driver doesn't support server-side prepared statements) PDO creates a query string containing the (escaped) parameters.
VolkerK
+1  A: 

If you are generating SQL yourself rather than using something like PDO, then you must always escape strings.

Escaping strings is a basic requirement of the SQL language. It's what allows you to use characters like apostrophes or backslashes in a string without everything going bad. There is no situation at all in which escaping strings is not required.

Even non-strings will have to be filtered to ensure that they are, indeed, non-strings.

If you are learning, please seriously consider learning something like PDO as many others have said, rather than escaping your own strings.

thomasrutter