The input originated from user input, but it's already been sanitized.
Better to be safe than sorry or just over-kill?
$_SESSION is basically the equivalent of your code making a text file for every user (identifying different users by magic, for explanation's sake), and storing some variables in that text file. Except for your code or something else on your server, nothing should be modifying the $_SESSION. So, if you make a habit of sanitizing everything before storing it in $_SESSION, you don't have to sanitize it again.
Related
I would like to save some POST data in my PHP session, like so.
$_SESSION['items'] = $_POST;
I plan on carrying this data through a couple more pages before saving it in the database. The type of data is text, so it can be anything, including SQL injection.
I will sanitize the data before saving it in my database, but only after it's been saved in the session for a little while.
My question is if saving UNsanitized raw POST data in the session presents a security concern, even if it will be sanitized later.
Thanks.
It's safe to store unsanitized user data in a session, so long as you sanitize it before you use it. The only exception to this I can think of is if you're using a database session handler that expects you to sanitize data before storing it in the session.
With that said, I would argue that there is a security concern here. PHP programmers are wired to look at $_POST and think unsafe. The same isn't true (or isn't as true) for $_SESSION. You, or someone working with your application, might at some point decide they need to do something with a session variable and assume it has already been sanitized.
In general, I think it is best to sanitize data as soon as you receive it.
I've got a register form which works without issues, but recently it has been pointed out to me that it's a bad habit for UX , for example, if an account already exists, and I redirect the user back to the registration page, without re-populating the form he filled and only display an error message.
So I quickly figured out a nice way to fix this, if after the initial registration data checks out and an account with the respective e-mail already exists, I could just create a $_SESSION storing the $_POST data, and destroy it after re-populating the user's form.
Now my question is: are $_SESSION variables vulnerable to any type of attack, or I can go ahead and store the raw input data inside the $_SESSION, and escape it with htmlspecialchars() when re-populating the form ?
Variables in session are not vulnerable to attacks within the session. However, using those variables in other places may open up holes. For example, just because you put a get/post variable in session doesn't mean that it magically can be used directly in a query. It could still cause SQL injection issues. When considering stuff like this, you have to think about where the data originated. If it started from some sort of user input, consider it dirty.
The only place this might be a problem is if the data sent is really large and you are just blindly assigning $_SESSION['POST'] = $_POST;. There shouldn't be an issue with overflow or stuff like that. The problem will be more that php has to unserialize the data at the start of a request and reserialize at the end (typically only if a change has happened). This unserialize/serialize takes time (it may be quick, but still). I would suggest just assigning only the values you want to save.
It is hard to say exactly. But I am about 100% sure the answer is no they aren't really vulnerable. That is assuming that you can destroy the session almost immediately. In this case you would create the session, redirect the user back to the old page, check for session vars, set the vars in the correct location (which you could just do with plain text in this case) and then destroy session. The session would only be alive for about 10seconds.. a minute max? and noone would really have enough time to pull from the server. If they are listening to traffic already you are in more trouble this.
Had to move to answer because that was too long...
You may be able to do a check for user name with ajax BEFORE they ever submit however. That would be better. Don't allow them to submit if the email is already existent. Just submit based off keyup or something.
No, session variables are stored on the server through a variety of options such as saved to disk, shared through a redis or memcached store, and so on.
Even if this data were to be compromised I don't really see how sanitation would protect anything or mitigate the negative effects of such an attack.
If you really are worried about such a thing, you can destroy the temp session variable after you're done using it.
I'm creating a multi-step survey and want to store the data in $_SESSION before writing everything to a database. Is there anything I should be doing to the data before storing it there from a security perspective?
Assuming you're on the regular file-based sessions, then you don't have much to worry about from an injection vulnerability view. PHP will take care of the mechanics of read/writing the session file, using serialize() and the like. Stuff whatever you want into $_SESSION and it'll magically be there on the next page invocation.
However, from the broader security perspective, anything that goes into the session file IS readable by anything else running under the same web server instance (e.g. the apache user ID). So it's not somewhere you could store sensitive data, let along things like credit cart/cvv numbers.
well, to avoid problems recovering the data, i suggest you to use a name for the session and use an array exclusively for the post data, kinda:
$_SESSION['postData'] = $_POST;
Its fairly safe to throw whatever you want in the session without sanitizing it. You could though, since you're going to anyways, sanitize it before putting it in the session so its ready to go into the database, then you can sleep more soundly.
I am very confused over something and was wondering if someone could explain.
In PHP i validate user input so htmlentitiies, mysql_real_escape_string is used before inserting into database, not on everything as i do prefer to use regular expressions when i can although i find them hard to work with. Now obviously i will use mysql_real_escape_string as the data is going into the database but not sure should i be using htmlentities() only when getting data from database and displaying it on a webpage as doing so before hand is altering the data entered by a person which is not keeping it's original form which may cause problems if i want to use that data later on for use for something else.
So for example, i have a guestbook with 3 fields name, subject and message. Now obviously the fields can contain anything like malicious code in js tags basically anything, now what confuses me is let say i am a malicious person and i decided to use js tags and some malicous js code and submit the form, now basically i have malicious useless data in my database. Now by using htmlentities when outputting the malicious code to the webpage (guestbook) that is not a problem because htmlentities has converted it to it's safe equivalent but then at the same time i have useless malicious code in the database that i would rather not have.
So after saying all this my question is should i accept the fact that some data in the database maybe malicious, useless data and as long as i use htmlentities on output everything will be ok or should i be doing something else aswell?.
I read so many books saying about filtering data on receiving it and escaping it on outputting it so the original form is kept but they only ever give examples like ensuring a field is only an int using functions already built into php etc but i have never found anything in regards ensuring something like a guestbook where you want users to type anything they want but also how you would filter such data apart from mysql_real_escape_string() to ensure it does not break the DB query?
Could someone please finally close this confusion for me and tell me what i should be doing and what is best practice?
Thanks to anyone who can explain.
Cheers!
This is a long question, but I think what you're actually asking boils down to:
"Should I escape HTML before inserting it into my database, or when I go to display it?"
The generally accepted answer to this question is that you should escape the HTML (via htmlspecialchars) when you go to display it to the user, and not before putting it into the database.
The reason is this: a database stores data. What you are putting into it is what the user typed. When you call mysql_real_escape_string, it does not alter what is inserted into the database; it merely avoids interpreting the user's input as SQL statements. htmlspecialchars does the same thing for HTML; when you print the user's input, it will avoid having it interpreted as HTML. If you were to call htmlspecialchars before the insert, you are no longer being faithful.
You should always strive to have the maximum-fidelity representation you can get. Since storing the "malicious" code in your database does no harm (in fact, it saves you some space, since escaped HTML is longer than unescaped!), and you might in the future want that HTML (what if you use an XML parser on user comments, or some day let trusted users have a subset of HTML in their comments, or some such?), why not let it be?
You also ask a bit about other types of input validation (integer constraints, etc). Your database schema should enforce these, and they can also be checked at the application layer (preferably on input via JS and then again server side).
On another note, the best way to do database escaping with PHP is probably to use PDO, rather than calling mysql_real_escape_string directly. PDO has more advanced functionality, including type checking.
mysql_real_escape_string() is all you need for the database operations. It'll ensure that a malicious user can't embed something into data that'll "break" your queries.
htmlentities() and htmlspecialchars() come into play when you're working with sending stuff to the client/browser. If you want to clean up potentially hostile HTML, you'd be better off using HTMLPurifier, which will strip the data to the bedrock and hose it down with bleach and rebuild it properly.
There's no reason to worry about having malicious JavaScript code in the database if you're escaping the HTML when it comes out. Just make sure you always do escape anything that comes out of the DB.
Okay I was wondering when should I sanitize my code, when I add store it in the database or when I have it displayed on my web page or both?
I ask this question because I sanitize my code before it gets stored in the database but I never sanitize when its displayed for the user.
Here is an example of how I sanitize my code before its stored in the database.
$title = mysqli_real_escape_string($mysqli, $purifier->purify(strip_tags($_POST['title'])));
$content = mysqli_real_escape_string($mysqli, $purifier->purify($_POST['content']));
There are distinct threats you are (probably) talking about here:
You need to sanitize data that's being inserted into the database to avoid SQL injections.
You also need to be careful with the data that's being displayed to the user, as it might contain malicious scripts (if it's been submitted by other users). See Wikipedia's entry for cross-site scripting (aka XSS)
What's harmful to your database is not necessarily harmful to the users (and vice versa). You have to take care of both threats accordingly.
In your example:
Use mysqli::real_escape_string() on the data being inserted into your db (sanitizing)
You probably want to use the purifier prior to data insertion - just ensure it's "purified" by the time the user gets it.
You might need to use striplashes() on data retrieved from the db to display it correctly to the user if magic_quotes are on
Rule is thumb is to sanitize ALL user input. Never trust the user.
When you are putting something in the database, you make sure it's safe to put in the database.
When you are about to display something in a browser, you make sure it's safe to display it in the browser.
If you make something browser-safe before you put it in the database, then you are now picking up the habit of trusting that things will be browser-safe when they come out of the database. It's not a good habit to trust user data, even if you're pretty sure you cleaned it previously. Also makes it easy to forget to sanitize before output if you're using someone else's database or code.
I think you would want to escape the input (to avoid SQL injections) and sanitize (to avoid scripting attacks) at the same time, as you're inserting into the database.
This way, you only need to run the sanitizer once on insertion, rather than (potentially) millions of times on display.
You should always encode data when you display it. This way your application can do no wrong. This will protect you from bad data no matter how it came to be.