Sanitize contact form without mysql_real_escape_string
Asked Answered
T

4

7

I normally use this function to sanitize my form inputs before storing them into my database:

//Function to sanitize values received from the form. Prevents SQL injection
function clean($str) {
    $str = @trim($str);
    if(get_magic_quotes_gpc()) {
        $str = stripslashes($str);
    }
    return mysql_real_escape_string($str);
}

Until today I didn't realize that mysql_real_escape_string required a database connection as I've only used it when I've been cleaning the data before storing it into the database.

I tried using the function on a contact form and got the "A link to the server could not be established" error. I could connect to the database but there is no need because I simply am trying to sanitize the data before it's being sent out to my e-mail via the contact form.

What is the best way to sanitize data that's not being stored in a mysql database and does this data still need to be sanitized?

Torrietorrin answered 9/8, 2010 at 5:6 Comment(0)
T
15

use filter_var()

http://php.net/manual/en/function.filter-var.php

like if you want to sanitize an email:

$_POST['email'] =    filter_var($_POST['email'], FILTER_SANITIZE_EMAIL); 

to message

$_POST['message'] = filter_var($_POST['message'], FILTER_SANITIZE_STRING);

is enogth

Tycoon answered 9/8, 2010 at 5:9 Comment(1)
what particular filters do you mean, please? there are so much of themBrakpan
Y
1

The purpose of sanitizing the data with mysql_real_escape_string is to avoid SQL injection. If you're not using SQL, you're already immune.

Men don't get cervical cancer.

Use a sanitization function appropriate to the special characters you need to avoid. Ideally, don't strip something which won't cause harm.

Yonkers answered 9/8, 2010 at 5:10 Comment(1)
mysql_real_escape_string alone do not help anythingBrakpan
B
-1

The whole concept is wrong. This function doesn't help not for email not even for database.

mysql_real_escape_string do not "sanitize" anything. It is merely escape delimiters and nothing else. Just to prevent syntax errors if you have a delimiter in your data:

SELECT * FROM table WHERE name = 'it's me' # error!

after data being escaped, your data become 'it\'s me' and there is no error.
Therefore, this function works only with SQL query and for data, enclosed in quotes only.

Thus, there is no sense in doing just mysql_real_escape_string without having quotes around. mysql_real_escape_string should be used
a) alone. stuff like trim or stripslashes has nothing to do here
b) right before query string composing and not elsewhere
c) only with data that going to be enclosed in quotes.
d) all other data need another ways of sanitization

As for the email, you don't need any sanitization it you send it as plain text. The only precaution you have to take is against mail injection
Not a big deal though. Just put user input into message body only. not into subject, to or from or any other header. Message body only. And you are safe

Brakpan answered 9/8, 2010 at 5:16 Comment(2)
What? Always use sanitation. Never trust user input. Such advice assumes that a) there's no way to inject a different header into the script (if you're not sanitizing the input, how do you know for sure?) and b) that all mail clients will do the right thing even with a text/plain header. I seriously doubt that.Saveloy
@Saveloy the only sensible point here is about some odd mail clients. Got one as example? But you "never trust user input" mindless prayer is indeed funny. Why not to get some experience before judge others?Brakpan
B
-1

(I'm new to stackoverflow so I'm going about this the wrong way/doing a bad job with the styling of my answer feel free to let me know.)

Correct me if I'm wrong as I'm also dealing with the same issue right now, but I don't think that the accepted answer using filter_var is enough as attackers could bypass this using unicode.

Example: "& #66;& #99;& #99;& #58;" (spaces added so stackoverflow will display it correctly)

This wouldn't get removed from the string, and would later be replaced with "Bcc:".

This is my solution, but there may be a better way. If anyone knows of one I'd love to hear it.

    $string = str_replace("&", "(and)", $string);
    $string = str_replace("#", "(num)", $string);
    $string = str_replace(";", "(semi-colon)", $string);
    $string = str_replace(":", "(colon)", $string);
    $string = str_replace("@", "(at)", $string);
    $string = str_replace("\\", "(backslash)", $string);
    $string = filter_var($string, FILTER_SANITIZE_STRING);
Blindfold answered 27/3, 2013 at 20:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.