Say I'm on my home PC with my browser open, I visit a site that uses sessions, as long as I don't close my browser or remain idle for 24 minutes the session will be maintained as I make subsequent HTTP requests to the site.
However on my server running PHP, if I use fopen() or file_get_contents() to request a page from that same site, does that site create a session for the 'user' that is my server? Is there a way to keep the connection open so the session is maintained for subsequent fopen() requests?
Can I do this by passing the session id in the request headers on the subsequent request? ie I set the headers including the session id, pass the headers to a context_stream_create(), and then pass the context with the next fopen() request? Can this be done for POST requests (which is what I really need to do)?
Any app which can speak HTTP language have the capability to save the cookie and therefore save the state in HTTP.
The answer to your questions is YES. You can do anything you want with just using the right protocol ( GET/POST ) and sending proper headers ( Host, User-Agent, ... )
But you have an alternate solution, i think this class will help : PHP Browser Class
Related
Imagine a scenario where you own mysite.com, and it loads javascript from an exterior domain such as adsprovider.com/ads.js.
Can adsprovider.com's javascript then perform an ajax call to mysite.com and attempt to retrieve the user's session data? If so, how can you protect your users against it?
Can adsprovider.com's javascript then perform an ajax call to mysite.com
Yes. The origin is defined by the URL of the HTML document the script is loaded into, not by the URL the script itself is loaded from.
retrieve the user's session data
Only if the session data is exposed through HTTP. Stuff you never give to the client is safe (but there is probably going to be quite a lot of session data that should be kept private between your server and the user).
Note that the script can read document.cookies and steal the session token too (unless the session token is sent with the httponly flag on).
If so, how can you protect your users against it?
Sandbox the adverts in iframes hosted on different origins.
Fortunatly, an Ajax call for your session data can't be directly request from external server.
You can load javascript from a CDN external source of course, but the script run from your own domain, and access to your server is not possible from outside.
Otherwise there would be a lot of security problem.
Also keep in mind that javascript is client side.
You can check Same-origin policy and CORS for more info on this topic.
I have a weird problem. I have a web page, that on the main page sets a session variable for each user that visits, and then on the next pages if the session variable is set, some stuff is shown, and some other isn't. The variable i'm setting is just an "1".
$_SESSION['user_id'] = $user_id;
Everything is simple, everything is working great, but I have this one user, that the server doesn't save the session variable for. Just one guy as far as I know. What can be causing this behaviour? He is using a mac if that matters, but on other macs the website works great.
Thanks.
When you call session_start() PHP sets a cookie with just the PHPSESSID variable set. This variable is used to identify the client browser with the session data on the server. If your user has disabled cookies, then it is not possible to use sessions without passing PHPSESSID back and forth in every request via GET or POST.
HTTP is a stateless protocol. IF session would be only in server side, how could it be able to distinguish between users?
[HTTP is a stateless protocol means: HTTP requests are responded from the server, and it forgets who sent the request, where did that come from.]
This is why cookies are storing the session ids.
In other words, if a user is disabling the cookies, he is not allowing PHP to set the session for himself. This is the reason behind.
What is the distinction between Sessions and Cookies in PHP?
A cookie is a bit of data stored by the browser and sent to the server with every request.
A session is a collection of data stored on the server and associated with a given user (usually via a cookie containing an id code)
Cookies are used to identify sessions. Visit any site that is using cookies and pull up either Chrome inspect element and then network or FireBug if using Firefox.
You can see that there is a header sent to a server and also received called Cookie. Usually it contains some personal information (like an ID) that can be used on the server to identify a session. These cookies stay on your computer and your browser takes care of sending them to only the domains that are identified with it.
If there were no cookies then you would be sending a unique ID on every request via GET or POST. Cookies are like static id's that stay on your computer for some time.
A session is a group of information on the server that is associated with the cookie information. If you're using PHP you can check the session.save_path location and actually "see sessions". They are either files on the server filesystem or backed in a database.
The main difference between a session and a cookie is that session data is stored on the server, whereas cookies store data in the visitor’s browser.
Sessions are more secure than cookies as it is stored in server. Cookie can be turned off from browser.
Data stored in cookie can be stored for months or years, depending on the life span of the cookie. But the data in the session is lost when the web browser is closed.
Cookie
is a small amount of data saved in the browser (client-side)
can be set from PHP with setcookie and then will be sent to the client's browser (HTTP response header Set-cookie)
can be set directly client-side in Javascript: document.cookie = 'foo=bar';
if no expiration date is set, by default, it will expire when the browser is closed.
Example: go on http://example.com, open the Console, do document.cookie = 'foo=bar';. Close the tab, reopen the same website, open the Console, do document.cookie: you will see foo=bar is still there. Now close the browser and reopen it, re-visit the same website, open the Console ; you will see document.cookie is empty.
you can also set a precise expiration date other than "deleted when browser is closed".
the cookies that are stored in the browser are sent to the server in the headers of every request of the same website (see Cookie). You can see this for example with Chrome by opening Developer tools > Network, click on the request, see Headers:
can be read client-side with document.cookie
can be read server-side with $_COOKIE['foo']
Bonus: it can also be set/get with another language than PHP. Example in Python with "bottle" micro-framework (see also here):
from bottle import get, run, request, response
#get('/')
def index():
if request.get_cookie("visited"):
return "Welcome back! Nice to see you again"
else:
response.set_cookie("visited", "yes")
return "Hello there! Nice to meet you"
run(host='localhost', port=8080, debug=True, reloader=True)
Session
is some data relative to a browser session saved server-side
each server-side language may implement it in a different way
in PHP, when session_start(); is called:
a random ID is generated by the server, e.g. jo96fme9ko0f85cdglb3hl6ah6
a file is saved on the server, containing the data: e.g. /var/lib/php5/sess_jo96fme9ko0f85cdglb3hl6ah6
the session ID is sent to the client in the HTTP response headers, using the traditional cookie mechanism detailed above: Set-Cookie: PHPSESSID=jo96fme9ko0f85cdglb3hl6ah6; path=/:
(it can also be be sent via the URL instead of cookie but not the default behaviour)
you can see the session ID on client-side with document.cookie:
the PHPSESSID cookie is set with no expiration date, thus it will expire when the browser is closed. Thus "sessions" are not valid anymore when the browser is closed / reopened.
can be set/read in PHP with $_SESSION
the client-side does not see the session data but only the ID: do this in index.php:
<?php
session_start();
$_SESSION["abc"]="def";
?>
The only thing that is seen on client-side is (as mentioned above) the session ID:
because of this, session is useful to store data that you don't want to be seen or modified by the client
you can totally avoid using sessions if you want to use your own database + IDs and send an ID/token to the client with a traditional Cookie
A session is a chunk of data maintained at the server that maintains state between HTTP requests. HTTP is fundamentally a stateless protocol; sessions are used to give it statefulness.
A cookie is a snippet of data sent to and returned from clients. Cookies are often used to facilitate sessions since it tells the server which client handled which session. There are other ways to do this (query string magic etc) but cookies are likely most common for this.
Cookies are stored in browser as a text file format.It stores limited amount of data, up to 4kb[4096bytes].A single Cookie can not hold multiple values but yes we can have more than one cookie.
Cookies are easily accessible so they are less secure. The setcookie() function must appear BEFORE the tag.
Sessions are stored in server side.There is no such storage limit on session .Sessions can hold multiple variables.Since they are not easily accessible hence are more secure than cookies.
One part missing in all these explanations is how are Cookies and Session linked- By SessionID cookie. Cookie goes back and forth between client and server - the server links the user (and its session) by session ID portion of the cookie.
You can send SessionID via url also (not the best best practice) - in case cookies are disabled by client.
Did I get this right?
Session
Session is used for maintaining a dialogue between server and user.
It is more secure because it is stored on the server, we cannot easily access it.
It embeds cookies on the user computer. It stores unlimited data.
Cookies
Cookies are stored on the local computer. Basically, it maintains user identification, meaning it tracks visitors record. It is less secure than session.
It stores limited amount of data, and is maintained for a limited time.
If I had a user logged onto my site, having his id stored in $_SESSION, and from his browser he clicked a 'Save' button which would make an AJAX request to the server. Will his $_SESSION and cookies be retained in this request, and can I safely rely on the id being present in the $_SESSION?
The answer is yes:
Sessions are maintained server-side. As far as the server is concerned, there is no difference between an AJAX request and a regular page request. They are both HTTP requests, and they both contain cookie information in the header in the same way.
From the client side, the same cookies will always be sent to the server whether it's a regular request or an AJAX request. The Javascript code does not need to do anything special or even to be aware of this happening, it just works the same as it does with regular requests.
If the PHP file the AJAX requests has a session_start() the session info will be retained. (baring the requests are within the same domain)
What you're really getting at is: are cookies sent to with the AJAX request? Assuming the AJAX request is to the same domain (or within the domain constraints of the cookie), the answer is yes. So AJAX requests back to the same server do retain the same session info (assuming the called scripts issue a session_start() as per any other PHP script wanting access to session information).
Well, not always. Using cookies, you are good. But the "can I safely rely on the id being present" urged me to extend the discussion with an important point (mostly for reference, as the visitor count of this page seems quite high).
PHP can be configured to maintain sessions by URL-rewriting, instead of cookies. (How it's good or bad (<-- see e.g. the topmost comment there) is a separate question, let's now stick to the current one, with just one side-note: the most prominent issue with URL-based sessions -- the blatant visibility of the naked session ID -- is not an issue with internal Ajax calls; but then, if it's turned on for Ajax, it's turned on for the rest of the site, too, so there...)
In case of URL-rewriting (cookieless) sessions, Ajax calls must take care of it themselves that their request URLs are properly crafted. (Or you can roll your own custom solution. You can even resort to maintaining sessions on the client side, in less demanding cases.) The point is the explicit care needed for session continuity, if not using cookies:
If the Ajax calls just extract URLs verbatim from the HTML (as received from PHP), that should be OK, as they are already cooked (umm, cookified).
If they need to assemble request URIs themselves, the session ID needs to be added to the URL manually. (Check here, or the page sources generated by PHP (with URL-rewriting on) to see how to do it.)
From OWASP.org:
Effectively, the web application can use both mechanisms, cookies or
URL parameters, or even switch from one to the other (automatic URL
rewriting) if certain conditions are met (for example, the existence
of web clients without cookies support or when cookies are not
accepted due to user privacy concerns).
From a Ruby-forum post:
When using php with cookies, the session ID will automatically be sent in the request headers even for Ajax XMLHttpRequests. If you
use or allow URL-based php sessions, you'll have to add the session id
to every Ajax request url.
It is very important that AJAX requests retain session. The easiest example is when you try to do an AJAX request for the admin panel, let's say. Of course that you will protect the page that you make the request to, not to accessible by others who don't have the session you get after administrator login.
Makes sense?
One thing to watch out for though, particularly if you are using a framework, is to check if the application is regenerating session ids between requests - anything that depends explicitly on the session id will run into problems, although obviously the rest of the data in the session will unaffected.
If the application is regenerating session ids like this then you can end up with a situation where an ajax request in effect invalidates / replaces the session id in the requesting page.
That's what frameworks do, e.g. if you initialize session in Front Controller or boostrap script, you won't have to care about it's initalization either for page controllers or ajax controllers. PHP frameworks are not a panacea, but they do so many useful things like this!
put your session() auth in all server side pages accepting an ajax request:
if(require_once("auth.php")) {
//run json code
}
// do nothing otherwise
that's about the only way I've ever done it.
I am interested in knowing how session management and cookies work in PHP. I want to know their underlying mechanism, like how the browser interacts with the cookies, and how the cookies are used to validate the session data in the server.
Is there any web resources that allow me to learn that?
In PHP in particular, the standard way sessions work is that PHP generates a random session ID, and puts it in a cookie. (By default called PHPSESSID) This cookie is handled by the browser by saving it locally on the user's machine, and is sent with every request to the domain it belongs to.
This session ID is then used to refer to a data store on the server machine, by standard located in /tmp/ on an apache install on linux. This is where everything in the $_SESSION array is stored between requests.
As you may notice, this is only as safe as the cookie is, as there is no real authentication between the user and server that the user is the "real" owner of the session ID. This means that so-called "session hijacking" is possible by sniffing the cookie and inserting the cookie with the session ID on the attacker's machine. This can be used to take over an account on a webpage, and browse around it just as if you were the original user, because to the server you are.
There's also an alternate, even more unsafe, way of keeping the session alive that PHP supports. This is done by sending the session ID as a GET variable with every link. As you may notice, this means that if a user simply copy-pastes one of these links, he will be giving away all his credentials. =)
Further information could be found in the PHP manual.
From PHP’s Session Handling manual:
A visitor accessing your web site is assigned a unique id, the so-called session id. This is either stored in a cookie on the user side or is propagated in the URL.
This unique id is a big random number that is stored on the server side to match it next time the client makes a new request. It typically goes into the /tmp directory.
A cookie is a bit of data that's associated with a HTTP address.
I.e.
1/ Browser requests www.google.com
2/ www.google.com response includes setting a cookie
3/ From this point on and as long as the cookie is valid (there's an expiry time associated with it), each subsequent request made by the browser to www.google.com/anything includes the cookie above
For details: http://en.wikipedia.org/wiki/HTTP_cookie
A cookie permits creating a session in the otherwise stateless HTTP protocol in the sense that it allows a client-server conversation to be isolated from other clients interacting with the server.