In Chrome, every tab is its own process. Yet, logging in to a site, say, Facebook, persists across tabs. For that matter, in many cases, it persists across OS reboots. This seems inherently very very insecure, but I'm just wondering, how is Chrome implementing this? The reboot thing in particular means it is storing something like a session token even after the process is terminated, which allows seamlessly reconnecting, already authenticated, with secure sites.
With a cookie!
Chrome, like any other browser, is storing a cookie in your file system. Those cookies are what enable you to reconnect automatically to some site. Since it's in your file system, even if you reboot they will still be there. Multiple processes or not is irrelevant here.
Then you might wonder, if the cookies are in my file system, does it mean that any page can access them?
No. Only the page for which the cookie was created can access it. The one that enforces this policy is your browser. If your browser is doing its job correctly then you are ok since it will only send the cookie to the right site (server).
You can also access the cookies directly by looking at the file system, but for that you need to have access to the operating system. Webpages don't have access to that hence the browser is doing that job for them and only gives them the cookies they should be able to read.
You need to protect your cookies. Stealing your cookies is nearly the same as stealing your password/username. If someone or something, like a virus, steals the cookies residing on your computer, it can impersonate you on that website if you are currently logged in.
You can check, edit and add cookie with tool like firebug. So, if you want to mount a fake attack you can :
- log in on a website using chrome
- read the cookie in chrome using the developer tool
- open firefox with firebug and add the authentication cookie that you found in chrome
You will then be logged into that website in firefox as well as in chrome. This is a simplistic version of the hack session hijacking. You could transfer the cookie onto another computer if you want to.
From this page: http://blog.chromium.org/2008/09/multi-process-architecture.html
There's only one browser process, which manages the tabs, windows, and "chrome" of the browser. This process also handles all interactions with the disk, network, user input, and display, but it makes no attempt to parse or render any content from the web.
And from the section about Renderer tabs:
Each renderer process is run in a sandbox, which means it has almost no direct access to your disk, network, or display. All interactions with web apps, including user input events and screen painting, must go through the browser process. This lets the browser process monitor the renderers for suspicious activity, killing them if it suspects an exploit has occurred.
I'm assuming the "interactions with the disk, network, user input" part includes session cookies and such like.
First, in specific to Google Chrome you will find This article very useful. CullenJ mentioned before that Chrome uses processes not threads, but that is untrue. It uses both. According to the article linked above Chrome uses a thread to handle SQlite database operations and gives the example of cookie operations so we can assume that Chrome stores cookies in a SQLite database somewhere.
Now let's take a look at the following quote:
We discourage locking and threadsafe objects. Instead, objects live on only one thread, we pass messages between threads for communication, and we use callback interfaces (implemented by message passing) for most cross-thread requests.
So, we know that google uses message passing and we can find more information on it reading about IPC.
Chromium has a multi-process architecture which means that we have a lot of processes communicating with each other. Our main inter-process communication primitive is the named pipe. On Linux & OS X, we use a socketpair(). A named pipe is allocated for each renderer process for communication with the browser process. The pipes are used in asynchronous mode to ensure that neither end is blocked waiting for the other.
Within the browser, communication with the renderers is done in a separate I/O thread. Messages to and from the views then have to be proxied over to the main thread using a ChannelProxy. The advantage of this scheme is that resource requests (for web pages, etc.), which are the most common and performance critical messages, can be handled entirely on the I/O thread and not block the user interface. These are done through the use of a ChannelProxy::MessageFilter which is inserted into the channel by the RenderProcessHost. This filter runs in the I/O thread, intercepts resource request messages, and forwards them directly to the resource dispatcher host. See Multi-process Resource Loading for more information on resource loading.
Each renderer also has a thread that manages communication (in this case, the main thread), with the rendering and most processing happening on another thread (see the diagram in multi-process architecture). Most messages are sent from the browser to the WebKit thread through the main renderer thread and vice-versa. This extra thread is to support synchronous renderer-to-browser messages (see "Synchronous messages" below).
If you were wondering what a named pipe is Wikipedia gives this definition:
A named pipe is system-persistent and exists beyond the life of the process and can be deleted once it is no longer being used. Processes generally attach to the named pipes (usually appearing as a file) to perform inter-process communication.
Now, I would to get one last quote from the documentation dealing with multi process architecture. It reads as follows:
We also have strategies to assign new tabs to existing processes if the total number of processes is too large, or if the user already has a process open navigated to that domain.
So this may not be how chrome does it exactly (but, you can read further into it following their documentation) but, based on what I've read so far I could implement a browser doing the following:
- I browse to facebook.com and the browser starts a new renderer and creates a named pipe
- I login and the renderer sends a message to the database thread to store the cookie
- I open some more unrelated sites and browser creates more renderers and pipes
- For some reason I feel like opening another tab to facebook.com browser and the browser messages the renderer that has already opened facebook.com to render another tab too.
- The new tab has all information available to the first facebook.com tab because they are sharing a process (I would have the process store its own copy of a cookie or something for reading so I would not have to bother the database thread, but that may not be how Chrome does it).
- If I decide to sign out the database thread sees that the cookie has changed and writes it to the database. If I stay signed in it does not touch the database.
Now, I must add here that default cookie lifetime is when the browser closes it expires. So, to support across opening and closing the browser the website must tell it to override this lifetime (which many sites do).
Ok, so if a browser overrides its cookies lifetime then it is stored in the database (yes, on the file system) and will be read again when you go back to this site. Is it insecure to store it there? No, not if your computer is not compromised and that the OS is doing its job properly.
As a side note, operating systems have come along way in detecting and blocking attacks.
As far as going to another browser, they all do similar things for cookie storage and if it bothers you that much either use Chrome's Incognito mode or see this documentation which states:
If you want Google Chrome to automatically delete cookies when you close all your browser windows, select the "Keep local data only until I quit my browser" checkbox in the Content Settings dialog. You can also make exceptions so that specific sites’ cookies are deleted whenever you close your browser.