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.
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.
So sometimes when I pass variables around from page to page, if I want to pass a variable into a form action, I would simply store it in an <input type="hidden"> element. This generally works well but I realized that someone could easily go into the HTML markup and simply change hidden to type text and therefore they could easily edit what is being passed (this can be bad if say they were editing their own profile and I had stored in the hidden input field their ProfileID and they changed it to someone else's)
I was wondering if there is a best practice to resolving this issue? I talked to some coworkers and they said to put checks on the server when they submit the form to make sure they aren't passing in the incorrect info. Is the best way of going about it or are there other ways?
Security-wise, you cannot trust any information that comes from the client, as you correctly noted. This means that you have to store it server-side when such pages are called.
A common practice is to give each client a session identifier in a cookie and on the server-side, you can relate all sensitive information to that session identifier. The session identifier should be random, because if it was sequential, you could just change its value and hijack someone else's session at random.
There are multiple ways to store information with regards to a session identifier. The most flexible one in PHP, and probably the easiest to implement, is to use built-in session support. PHP handles the session identifier for you and lets you store any serializable object in the $_SESSION superglobal. This is an okay-ish solution, as session data is often stored in the temporary folder of your server, and if it's a shared server, chances are other websites on that server could theoretically snoop in and see or even manipulate session data. Of course, if what you're doing is really low-impact, then it's kind of unlikely that someone would go as far as rent the same server just to mess with you. Still, for instance, OAuth providers recommend that you do not store OAuth tokens in $_SESSION storage in public environments.
<?php
session_start();
// place anything you need to save between pages in $_SESSION
$_SESSION["foo"] = array("bar", "baz");
// until you unset $_SESSION["foo"], it will be available in every page that called
// session_start().
?>
It's a good practice to call session_destroy when users log out to make sure that their session data doesn't exist for longer than it needs to.
On the other hand, you can also store information in a database, such as MySQL. This is better security-wise as you should run away from any host that doesn't have distinct database users or distinct databases for each server user, and you can be assured that no one else will be able to change (or even just see) the session information. However, this isn't as flexible, as you need a table structure to store anything you want to store.
Why is it recommended to store CodeIgniter sessions in a database table? I know it's about security but how?
why is it required to set an encryption key in the config when using the Session class?
Are you supposed to decrypt the session?
Does $this->session->sess_destroy(); delete the entire cookie or just the data you put in the cookie? And does it end the session completely, by which I mean undoing
$this->load->library('session')?
CI's sessions are, actually, cookies. Encrypted, but cookies nonethelesss. That's why is preferrable to store session in a database, because you're (supposedly) dealing with a less unreachable target from attacks, especially if you use Active Records wich automatically escapes your queries (so that SQL injections are avoided).
Also, contrary to cookies, DB doens't have such limited amount of memory available, so you can store any amount of data you want there, cache the operations, and have them hidden from the frontend.
I'm not sure about why it is required, apart from the fact that some sessions datas are automatically encrypted by CI. So, even if you don't make use of the Encryption library, some encrypting is still caried one (while saving session ID, for example.). As Kai Qing correctly noted, you don't have to do any decryption on datas already handled by CI.
$this->session->sess_destroy() just deletes the data stored as sessions. While being also cookies, in order to delete the whole content you need to use the dedicated functions (look into the cookie helper, for example). Keep in mind, though, that when you call this function you delete also flash messages (as they are sessions), so if you just want to unset some elements, use unset_userdata($item).
It doesnt end the library loading, also. As for any other library, or class, or controller, or whatever, everything is re-loaded from zero after each request. Each time you make a request the scripts runs, reinitializes everything, and when the script ends all is lost like tears in the rain. That's the regular lifespan of a php script. If your script is not bound to end after you call the session->sess_destroy(), the session library will be still loaded, though the data will be erased.
To answer your first question - It is recommended to store via DB to minimize the data found in the session and reduce the risk of foolishness - like a helper. Since DB stored sessions will only store the id in a cookie, the information available is reduced to an unusable bit of information.
You don't need to decrypt anything. The engine handles that for you.
as for destroy - I don't know exactly. But I imagine a simple var_dump would answer that.
I have a site, where the username is stored in a session variable when they are logged in, I am wondering is it safe to make queries off of the value stored in this session variable?
yes, session are stored on server side.
instead of saving user name, you can save user id (int), so that it takes less space on
server. Remember that you should handle CSRF, and Session hijacking
Yes it is save. However, always escape any input that goes into a query (the best way is a bound parameter). Never trust any variable explicitly, especially if you can't see directly where it comes from (meaning unless you can scroll up and see $foo = 'bar';). So the better method is to just not trust everything, and you'll be safer in the end...
Sessions work by storing a session ID in a cookie sent to the user machine and storing all actual variables on the server. As such, your main worry is that the user will be able to find out the session ID of another user and pretend to be them; i.e., session hijacking.
Given that, you aren't really worried about SQL injections here as much, so you should be OK so far as making queries off the variables stored in the session. However, you should be worried that data can be viewed by someone other than the intended recipient. If you take precautions against hijacking, then you should be OK.
It depends.
If the pages in your site that are using the session are protected by encryption (HTTPS), then that mitigates the risk of session hijacking due to sniffing network traffic (the cookie containing the session id is protected.)
However, if you're on a shared host, the session file is typically stored in a central location and trusting unencrypted session data does entail some risk.
You could encrypt the session data, or you could develop a custom session storage as outlined in the link below:
Trick-Out Your Session Handler
But, no matter what you do or how much you trust your session data, you should use prepared statements or stored procedures to protect the integrity of your SQL statements, preventing SQL injection.
in fact, it's safe to use ANY variable in the SQL query, As long as you're following syntax and safety rules.
And data source has nothing to do here. No matter if it's session or a file, or an RPC request or POST data. All data is equal for the query and should be processed always the same way.
I know it's hard to understand but it's very important too, so, at least try it.