Sessions are based on the session identifier, a string that uniquely identifies a browser session via a cookie1 set on the client when session_start()
is called. Since they are based on cookies, you should treat them as user input and you should never absolutely trust user input. Cookies can be stolen via XSS, and PHP cookies are not encrypted by default.
Sessions are stored in the %TEMP%
directory, whichever that may be for your system. The save location can be changed from the session.save_path directive or by the session_save_path during runtime, but on a typical hosting environment2, it's generally considered easier to gain access to the filesystem than a database.
The various security concerns are addressed on the manual:
The session module cannot guarantee that the information you store in a session is only viewed by the user who created the session.
...
Assess the importance of the data carried by your sessions and deploy additional protections -- this usually comes at a price, reduced convenience for the user.
...
The session module cannot guarantee that the information you store in a session is only viewed by the user who created the session.
Session fixation is the commonly quoted buzzword, you can find a little more info on the Session Fixation Vulnerability in Web-based Applications article that's referenced on the manual.
The session_set_save_handler() function allows you to transparently choose where sessions are saved:
session_set_save_handler() sets the user-level session storage functions which are used for storing and retrieving data associated with a session. This is most useful when a storage method other than those supplied by PHP sessions is preferred. i.e. Storing the session data in a local database.
After you build and set your handler, you can continue using sessions as usual. There are quite a few examples on the comments to the manual page on storing sessions to a database. Storing sessions in a database has an important disadvantage: if for any reason the database goes awol, then you've lost everything you've built around sessions too.
1 You can propagate the session id via a URL parameter, but that's more trouble than it's worth.
2 By typical I mean cheap shared hosting.