Hello I create PHP form where my users can post ads. I know that it can constitute to break-in and that is way we are using: "htmlspecialchars()" and "mysql_real_escape_string()" and "stripslashes()". The problem is that I don't know where to use ach one of them if the input is "name" (<input type='text' name='name' />), so how should the POST be? like this: $name = htmlspecialchars($_POST['name']); or like this: $name = mysql_real_escape_string($_POST['name']); or mabe like this: $name = Trim(stripslashes($_POST['name'])(; ? What about the print to the screen - the stage where I get the data from the SQL: $query = mysql_query("SELECT * FROM `sells` "); $index = mysql_fetch_array($query); $name= $index['name']; PHP: Should it be : $name= htmlspecialchars($index['name']); or like this: $name = mysql_real_escape_string($_POST['name']); or mabe like this: $name = stripslashes($_POST['name']); ? Thanks for advance!
Hi, At the time of insert use this: - $name = addslashes($_POST[‘name’]); And at the time of echo use this Echo stripsalshes($name); Cheers, ~Maneet
$item = $_POST['item']; $other = $_POST['item']; //escape the entire Query $sql = mysql_real_escape_string("INSERT INTO table ('item', 'other') VALUES($item, $other)"); You don't need to escape strings when you are grabbing data FROM the database, only when you are inserting stuff into it. Or you could do: $_POST = array_map('mysql_real_escape_string', $_POST); and that'll do it automatically
Ok, so or $sql = mysql_real_escape_string("INSERT INTO table ('item', 'other') VALUES($item, $other)"); or $_POST = array_map('mysql_real_escape_string', $_POST); ? I don't need to use stripslashes at all? something like this: $name = Trim(stripslashes($_POST['name'])); ?
Do Not use addslashes or stripslashes for SQL, use the native mysql_real_escape_string() function. Do Not escape the entire query like JREAM suggested, that function is meant to escape a single value for safe use within a query, that means it will escape all quotes and other symbols used in SQL. If you escape the whole thing, you will not have a working query. First off, there are two main vulnerabilities you must consider: XSS and SQL Injection. XSS (cross site scripting) is a vulnerability where you allow someone to place JavaScript into your page. This is bad, because you can include an external javascript file and it will run on the client machine. The way to defend against this is use htmlspecialchars(), which change the special html characters for display. < becomes <, > becomes >, etc. SQL Injection (in it's simplest form) occurs where you can "break" and SQL query. The following code has an SQL injection vulnerability: $result = mysql_query("SELECT * FROM sometable WHERE username = '{$_REQUEST['username']}'") PHP: Why? Let's say you put in the name "John". That works just fine, nothing wrong there, but let's say you put in "John' UNION SELECT ... ". This is where you can inject your code. If you are using MSSQL, you can simply do this: "John'; UPDATE user_password = 'lolmyownpassword'". This can cause some real problems, the way to combat it is to make sure that all data before going in is safe. You need to use the mysql_real_escape_string() function to do this to be absolutely safe. Do not use addslashes and such. <?php $item1= htmlspecialchars($_POST['item1']); // $item1 at this point can be safely outputted to the screen but is not safe for SQL yet $item = mysql_real_escape_string($item1); // Now it is safe for a MySQL query $sql = "UPDATE table SET junk = '$item1' WHERE something = 23"; $result = mysql_query($sql); // ... PHP:
Hiן SamT, Thank you for your full comment! I understand your explantion, but I didn't understand why not to escape the entire query like JREAM suggested: $_POST = array_map('mysql_real_escape_string', $_POST); PHP: this code will do escape for all the variable that come from forms and make them safe for the DB... ?
I think SamT thought that the function was being applied to the query itself. The array_map provided would work fine to apply the function to each posted element.
doing array_map through the entire $_POST array will make it safe for the database, but you will still have an XSS vulnerability if you do not htmlspecialchars() your input before displaying it to the browser. The reason why using mysql_real_escape_string() is not a good idea for escaping the whole query at once is simply because it was designed to only escape a single value. Take these examples: $sql = mysl_real_escape_string('SELECT * FROM sometable'); PHP: In this case, it will work, though escaping a literal query is not required. However, look what happens when you do this: $username = $_POST['username']; $sql = mysl_real_escape_string("SELECT user_password FROM users WHERE username = '$username'"); PHP: The query will be broken, if you posted "Admin" as your username to this script, and you echo'd "$sql", it will look like the following: "SELECT user_password FROM users WHERE username = \'Admin\'" Code (markup): Notice how the quotes surrounding Admin are now escaped. MySQL will then assume the text "Admin" is a column and try to match records where the username column is equal to the Admin column (which does not exist). The proper way to do this: $username = htmlspecialchars($_POST['username']); $username = mysl_real_escape_string($username); $sql = "SELECT user_password FROM users WHERE username = '$username'"; PHP: Which will create the query: "SELECT user_id FROM users WHERE username = 'Admin'" Code (markup): What I recommend: Escape all values with mysql_real_escape_string() right before entering the query, not as they are imputed. Someone can easily POST a bunch of arbitrary data to the page and cause high loads (DDoS). Escape only the inputs you are are using. For XSS protection, you should run htmlspecialchars() only on the variables you are using as they are being imputed. Instead of using $_POST, $_GET, and $_COOKIE in your code, simply do this: $username = htmlspecialchars($_POST['username']); This ensures that $username is safe for HTML output at all times and should be free of XSS.
But if I input data into the DB, and using "mysql_real_escape_string", and in another page I pull those date from the DB and print it to the sreen, should I still need to use "htmlspecialchars"? after all I pull it from my DB whice all check and clean... ? I kind sure that you gonna say that hacker will try to insert JS into the DB (mysql_real_escape_string don't handle JS) and when I print it (in another page) the JS will do the problems... Am I right? One more thing, from all this explantion I didn't understand if the code that I wrote will do the job for the "DB input" side: $_POST = array_map('mysql_real_escape_string', $_POST); $_GET= array_map('mysql_real_escape_string', $_GET); PHP: I'm asking because I have lots of forms in my site and instead of writing $item1= mysql_real_escape_string($_POST['item1']); PHP: lots of time I rather to write theabove code one time...
Use htmlspecialchars() only when you take user input, and it should be safe for output in HTML at that point. You cannot exploit a database with JS, if they get JS in your database and you display that value directly from the database, then that's an XSS attack. Just make sure that you clean it with htmlspecialchars() at the moment you take the input: $username = htmlspecialchars($_POST['username']); Any time you use $username after that, it will be safe for output in HTML. The code with array_walk will apply the mysql_real_escape_string() function on each value of $_POST and $_GET. I advise against this as it's a waste of resources. Only run mysql_real_escape_string() on values right before you place them in an SQL query. To review: - Input variables like this: $username = htmlspecialchars($_POST['username']); $email = htmlspecialchars($_POST['email']); // ... PHP: - Refer to them as the variable you set them to, DO NOT use $_POST or $_GET with anything after you cleaned them. - Use mysql_real_escape_string() right before they enter a query $username = mysql_real_escape_string($username); $sql = "SELECT * FROM users WHERE username = '$username'"; // ... PHP: Following this procedure will ensure several things: - You will have no possibility of SQL injections - XSS attacks would be extremely unlikely (htmlspecialchars has been known to have bugs) - All values can be safely echo'd to the screen upon input
OK, thank Sometimes I put hyper link with paraneters, such as: <a href='index.php?page=1'>text</a> when I do $page = $_GET['page'] do I still need to use "mysql_real_escape_string()" before I'm pulling data from the DB?
wow mate, mysql_real_escape_string is fine, but it will protect you just aginst SQL Injection, you should use also strip_tags() for XSS and such. BTW strip_tags works better then htmlspecialchars.
If you are expecting it to be an integer, you can simply cast it as int, and it will be safe for the database: $page = (int) $_GET['page']; // This is safe for DB and output to HTML Code (markup): strip_tags() is good if you are parsing the value between two tags, htmlspecialchars() effectively clean the string for display within the template and therefore will suit your needs in this situation.
Do you know if the code: $_GET= array_map('mysql_real_escape_string', $_GET); will work with "htmlspecialchars" ? for example: $_GET= array_map('htmlspecialchars', $_GET); $_POST= array_map('htmlspecialchars', $_POST); PHP:
egads, so much confusion here #1 as soon as you create a variable for a database query, you can use a mysql_real_escape_string function if you are using stripslashes() at all, you are doing it WRONG #2 never assume info is safe (pulled from db so its ok) I seen a few people say you dont have to worry about it here.. Wrong, never assume.. #3 sanitize all input immediately after receiving get/post data #4 any returned echo/print to web use htmlspecialchars($output); // if you know you dont want html etc, strip_tags() it too make sure magic quotes is disabled, most problems also originate from escaping strings twice+ #5 just another note, if slashes are in your DATABSE, you are doing it WRONG .... but even better yet you need to start getting into mysqli, etc to avoid the hack attacks
Thanks for you advaice, About num4 - if I don't want HTML, can I use only strip_tags() (without htmlspecialchars) ? About the slashes - well, I don't think users will input slashes in their texts, so I won't have slashes in my DB. should I do anything specail?
Do you thing that maybe this code will be better: foreach ($_GET as $x => $i) { $_GET[$x] = @htmlspecialchars($_GET[$x], ENT_QUOTES); } foreach ($_POST as $x => $i) { $_POST [$x] = @htmlspecialchars($_POST [$x], ENT_QUOTES); } foreach ($_COOKIE as $x => $i) { $_COOKIE[$x] = @htmlspecialchars($_COOKIE[$x], ENT_QUOTES); } foreach ($_GET as $x => $i) { $_GET[$x] = @mysql_real_escape_string($_GET[$x], ENT_QUOTES); } foreach ($_POST as $x => $i) { $_POST [$x] = @mysql_real_escape_string($_POST [$x], ENT_QUOTES); } foreach ($_COOKIE as $x => $i) { $_COOKIE[$x] = @mysql_real_escape_string($_COOKIE[$x], ENT_QUOTES); } PHP: Than the code I wrote above ? ?