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.
Related
Is there a way to transmit data from one site to another using the $_POST variable, or a similar one? Just to clarify, I am not talking about form data, and the user is not supposed to notice or have to do anything for the data to be transmitted. The $_GET variable is out of question because that can easily be spoofed in a white box attack. Furthermore the $_SESSION variable is out of question, as I am trying to transmit the data to the page, where I Start the session. Would using the $_COOKIE variable be an option that is comparably safe to the $_POST variable? Are there any other variables, that would be applicable to this situation?
Long story short, my question is can I use the $_POST variable without using a form, and if yes, how? AND/OR is there a way to directly transmit data from one page to another, with a level of security similar to the $_POST command?
** secure_log_in **
#confirmed users identity
header("Location: set_session.php?email=$email&setting_session=yes");
** set_session.php **
if (isset($_GET["setting_session"]))
{
start the session
}
The problem is, that if an attacker just tries to access the page set_session.php with the link shown above, as long as they know an email used by a user (we will just assume that the attacker knows an email used for the site) they can easily get access to areas they should not have access to. My question is, is there a way to use the $_POST command to send the $email over.
A way around this problem, may be using a cookie. How easy/difficult would it be for the attacker to create a cookie, with the email address required to access the secure section?
After trying it a lot longer I noticed, that the best way to solve this is to just include the page, and set a variable on one of the pages, to only run the script when you want to. This should be rather safe, and solves all of the problems and is less resource intensive, as well as faster.
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 currently use PHP sessions (without database saving) to identify users on a small website. However, I would like to make it more secure by saving session data to a MySQL database along with using a cookie with PHP.
I'm thinking of having a PHP script which I will include on every page which will:
Try to validate a session based on a database entry
Create a session if needed
Set special session variables I might need
Is this the best way to go about things? Am I missing anything in my script?
Session automatically try to use cookies for session ID.
The common practice is to store everything important into $_SESSION on login (and check only for privileges change).
If you want to make it more secure you may store $_SERVER['REMOTE_ADDR'] and $_SERVER['USER_AGENT'] into session and check them on each request.
The last thing I can think of right now is checking 'life time of session' manually.
Anyway I think that using https instead of http would bring you much more safety than reinventing sessions.
Storing each request/session into DB would make sense only if you needed to have special handling for parallel request.
That's a pretty big question. You want to do a bit of research on learning the tools I'll provide you for the job. I cannot write every detail about them here, but I'll try to get you pointed in the right direction.
check the user cookie to see if they have your session id variable set. if it isn't, start them a new session and offer a login perhaps.
if they have the cookie, check if it is a valid session id
if it is, load that session.
You'll need tools like setcookie, session_id(), $_SESSION, $_COOKIE. Making a users table is a whole other topic really.
I work with MVC's all the time that do just exactly what your referring to. Its a real piece of junk setting it up that way, but it can be useful in certain situations.
But the most important thing you should know is that when combining the login to an active session, it won't really make it more secure unless you use 2 session identifiers. is this what you want to do?
This would also be useful if you wanted to track where users log-in from. Gook luck!
I'm developing some additional functionality for a client's website that uses the email address as a key lookup variable between various databases (email marketing system, internal prospect database, and a third shared DB that helps bridge the gap between the two).
I'm concerned that storing a visitor's email address as a $_SESSION variable could lead to security issues (not so much for our site, but for the visitor).
Anybody have suggestions or experience on whether this is okay to do, or if there's another alternative out there?
It is important to understand the difference between how $_SESSION variables are stored and how cookies are used to retrieve it. All data in the session is stored on the server (in /tmp by default, I believe), and persisted between requests. No session data is stored directly in a cookie by default.
However, PHP will store a cookie with a unique id that identifies your user with a particular session (hence how the same information can be retrieved over different requests).
If the cookie with the session id is compromised, another user can impersonate someone with that session. This includes authenticated sessions, where a user has already logged in. If this happens, chances are you'll likely have bigger problems than exposing an email address.
It wouldn't be a bad idea to use some kind of user id in your session, as opposed to the email address. However there are a number of other, probably more useful, ways to add security to your session.
See this question: PHP Session Security
There isn't anything inherently dangerous to storing values in $_SESSION. It all depends on whether you provide code that would inadvertently output it to the browser.
You could use part of the email address in the variable. So for example, you could use the name joe from the e-mail joe#bloggs.com. Then use another parameter to perform the search.
Also, always use mysql_real_escape_string() when passing variables to the database, and add in some backslashes for good measure.
I've created a login page and registration page and now I want to use that to password protect pages and have pages which show information specific to that user.
Would storing the user ID of the user logged in in a Session variable be a safe and correct way of doing this?
How easy would it be for a user to change the session variable to a different ID and access another user's information, and not having to type the users login details in?
EDIT: Would posting the user ID from each page to the next be more secure?
Here's an article on session security
If you encrypt user name in such a way that only your PHP scripts can decrypt it then you should be safe I guess.
That's what session meant to be
For session security, you can check http://phpsec.org/projects/guide/4.html
While I'm not aware of any way in which a user could manipulate the information in $_SESSION unless your code (or code on your server) allows them to, so don't do anything crazy like...
foreach($_POST as $key=>$value) { // DON'T DO THIS
$_SESSION[$key] = $value; // DON'T DO THIS!
} // WHY ARE YOU DOING THIS!?
You shouldn't do anything like this, where you're just putting whatever data the user gives you in your $_SESSION variables. Like the database, writing to the session should be thought of as a form of output, and you should sanitize what you put in it (and where it's put) accordingly.
So, unless you're doing something crazy like this (you might be; it can be much more subtle), I don't think you have to worry about a user changing the session variable. You might have to worry about the threats of a shared hosting environment where someone who's probably not quite an end user is manipulating the session info.
What's not so safe is the session identifier, as there are a few straightforward ways to hijack a session in PHP.
I recommend checking out that book I've been linking to, Essential PHP Secutiry. It's a very small and straightforward (but thorough) explanation of several basic PHP security concepts, many of which can be generalized and should be kept in mind when doing any web dev work.
I'll talk about the default session behavior, here: sessions are based on a cookie "PHPSESSID" which is set to an MD5 checksum (32 alphanumeric characters). PHP accepts this cookie from the browser, and uses it to load server-side session data. The client has no direct way to modify data in the session, but does get to specify their own session ID.
You can add additional layers of security (SSL, checking the client IP, etc.), but by default if I know your cookie I can effectively login as you. As far as how "easy" that is, well, that depends on lots of other layers of security: is someone sniffing your traffic, do you have malware installed, etc.
Tools like Suhosin attempt to improve session security.