tags:

views:

127

answers:

5

I am trying to secure my site so I don't have sql injections and xss scripting. Here's my code.

//here's the from, for brevity, i just show a field for users to put firstname
<form>
<label for="first_name" class="styled">First Name:</label>
<input type="text" id="first_name" name="first_name" value="<?php if (!empty($first_name)) echo $first_name; ?>" /><br />

//submit button etc
</form>


if (isset($_POST['submit'])) {

 //gets rid of extra whitesapce and escapes
 $first_name = mysqli_real_escape_string($dbc, trim($_POST['first_name']));

 //check if $first_name is a string
 if(!is_string($first_name)
 { 
 echo "not string"; 
 }

 //then insert into the database. 
 .......

}

mysqli_real_espace_string: I know that this func escapes certain letters like \n \r, so when the data gets inputted into the dbc, it would have '\' next to all the escaped letters?

--Will this script be enough to prevent most sql injections? just escaping and checking if the data is a string. For integers values(like users putting in prices), i just: is_numeric().

--How should I use htmlspecialchars? Should I use it only when echoing and displaying user data? Or should I also use this too when inputting data to a dbc?

--When should I use strip_tags() or htmlspecialchars?

SOO with all these function...

if (isset($_POST['submit'])) {

 //gets rid of extra whitesapce and escapes
 $first_name = mysqli_real_escape_string($dbc, trim($_POST['first_name']));

 //check if $first_name is a string
 if(!is_string($first_name)
 { 
 echo "not string"; 
 }

 //gets rid of any <,>,&
 htmlspecialchars($first_name);

 //strips any tags with the first name
 strip_tags($first_name)

 //then insert into the database. 
 .......

}

Which funcs should I use for sql injections and which ones should I use for xss?

EDIT: When can a user insert xss scripts against me? Like when there is any forms that needs to filled out?

+2  A: 

For SQL injection, mysql_real_escape_string should work. (To be totally sure, you can use prepared statements)

For XSS, htmlspecialchars should work. strip_tags might not be as safe, as someone could cleverly disguse their javascript.

webdestroya
So any places where users can input data, I should use htmlspecialchars and if I am inserting the data into the dbc, I should use mysql_real_espace_string and prepared statements?
ggfan
Yes. (real_escape_string OR prepared statements) you dont (and probably shouldn't) use both at once.
webdestroya
Okay, thanks! Ill look into prepared statements
ggfan
A: 

You should add using stored procedures to your list. This is an excellent security measure in its own right.

RandyMorris
-1: Stored procedure do not guarantee anything on their own. With the MySQL library, then yes, it tends to limit attack vectors because the data to the underlying query is kept separate from the query, but only because mysql(i)_query only allows a single query at a time. If it allowed multiple queries, which other DBs may or do, then I can just add another query to cause all the havoc I want.
Michael Madsen
Down voting for suggesting store procedures? I doubt you know enough to cause any more "havoc" than down voting other peoples opinions.
RandyMorris
@RandyMorris: I am not downvoting for suggesting stored procedures. I am downvoting for suggesting them *as a security measure of their own right*. On their own, SPs aren't going to give you security.
Michael Madsen
Anything not implemented correctly is not helping security, isn't this part of the definition of an exploit in the first place?
RandyMorris
They are not security measures on their own, which is what you claim. Believing so is even potentially harmful, if someone starts using SPs without fixing the underlying problem, which is unsafe building of queries through concatenation. Even if mysql(i)_query won't allow multiple queries, mysqli_multi_query will, and many other DB libraries always allow multiple queries - and in that case, SPs won't make any difference at all. *That is why I downvoted:* Simply using SPs will not solve the true problem (query concatenation), and claiming it will is false and potentially harmful.
Michael Madsen
A: 

Whenever you are embedding user-supplied information in HTML, you should use htmlspecialchars. Whenever you are embedding user-supplied information in SQL, you should use mysql_real_escape_string. Follow these rules and you should be OK.

Note, however, that a better solution for database security would be to use prepared/parametrized queries (see here and here), as these will handle the escaping for you, eliminating the possibility of your forgetting.

Also, don't forget to check for magic quotes.

Will Vousden
+2  A: 

Checking if data is a string is useless: strings are exactly what you'd use for injections.

real_escape_string is a reasonable, but not guaranteed way of avoiding SQL injections, because escaping routines have a risk of being buggy and not escaping things correctly (in fact, there have been bugs previously). The right way to do it is to used parameterized queries - this separates the data from the structure of the query, making injection impossible. If you absolutely cannot use parameterized queries, however, real_escape_string (with a set_charset when the connection is opened) is the best you can do.

You will want to use htmlspecialchars on anything the user can touch, and you want to use it at the moment it is shown on a page. If you want users to format posts or anything, then you should provide them with a formatting language a la BBCode (and convert the BBCode after running htmlspecialchars). If you need to store pure HTML, you wouldn't want to use htmlspecialchars, but you'd want to make damn sure that only trusted people can write there. For example, if you're writing a blog, it might be okay to allow pure HTML in the blog post itself, because only the blog editors can write stuff there. However, you wouldn't want to allow it in the comments, because everyone can write stuff there, and that would just make it too easy to do stuff like cross-site scripting.

Michael Madsen
+1  A: 

If you are printing HTML you should clean it with HTML Purifier first. Think of it as an advanced (and customizable) version of strip_tags().

For insertion into database, I use prepared statements. It's foolproof.

chelmertz