Websites which have sensitive information need to be patched to ensure its not exploited because of session issues.
In earlier versions of apache cookie reliability was not assumed and hence the default method was always using url-rewrite which meant every url link, every form submission etc would have a PHPSESSID=<sessionid> passed along to inform the server about the active session. New versions have turned this off using
session.use_trans_sid = 0
in the /etc/php5/apache2/php.ini file.
Reasons?
Well one might safe the offline page as a bookmark or pass the link across to others not realizing that the session id information is also sent. So someone who quickly accesses these pages could possible get logged on, this was also true wrt search engines, and I guess in some cases it being seen as duplicate content as the same page will have a different session id every time the robots scan the website.
But having this set does not mean you are protected. Let me explain.
What prevents me from presetting the session id! Assume there is a banking site www.example.com which has a login screen at www.example.com/login.php
I can send you can email with a link to the bank site as http://www.example.com/login.php?PHPSESSID=12345
When you click on the link it presents the session id as 12345 rather then asking the server to generate a new one. This is called session fixation. Keep in mind even with session.use_trans_sid = 0 this will work as this sets it only not to use url-rewrite. To prevent this altogether set session.use_only_cookies = 1 which ensures that only cookies will be used, but this could cause problems when dealing with transaction which involve switch sites, i.e. siteA forwards to site B for payment which forwards to siteA for thank you, in which case a phpsessid inform might be used to revive the old session.
A good approach would always be to at the login screen and immediately post login to force a new session id generated using random numbers
session_start();
$newsessid = somerandomnumberfunction();
session_id($newsessid);
you can also use session_regenerate_id() function to generate a new id
session_start();
session_regenerate_id();
Also its always good to ensure every valid session is checked against an ip. One good method is to store the session id and remote ip information in a table, or better store the ip as a session variable itself, once the user logs in and ensure that this is continued for remaining pages for security. This ofcourse wont work when users use the same office or shared network as the ip to the outside world is the same.
https is always a good idea for sensitive sites, but keeping it persistent for all pages which use session is important if you really want a foolproof system else anyone can always sniff your packets.
So to quickly go through the bits
- set session.use_trans_sid = 0 in /etc/php5/apache2/php.ini file.
- Ensure you always use a new self generated session id on successful login attempt.
- Try setting session.use_only_cookies = 1 and check if all works fine.
- Use https throughout to ensure no one can sniff your session id.
- Store session id, remote IP information and compare for successive pages
セッションとセキュリティ
外部リンク: » Session fixation
セッションモジュールは、セッションに保存した情報を見ることができる のがそのセッションを作成したユーザーだけであることを保証することが できません。セッションの完全性を積極的に守るには、そのセッションに 紐づく値に応じた追加措置が必要です。
セッションに運ばれるデータの重要性を評価し、必要な保護策を講じてください。 この対策は、通常は何らかの犠牲を伴うもので、ユーザの利便性を損なうことになります。 例えば、単純なソーシャルエンジニアリングからユーザを守るためには session.use_only_cookies を有効にする必要があります。 この場合、ユーザ側でクッキーが常に有効となっていなければならず、 有効でない場合はセッションが動作しなくなります。
存在するセッションIDが第三者に洩れる手順は何種類かあります。 洩れたセッションIDにより、第三者が特定のIDに関連する全てのリソー スにアクセスできるようになります。まず、セッションIDがURLにより伝 送される場合です。外部サイトにリンクを張っている場合、外部サイト のreferrerログにセッションIDを含むURLが保存される可能性があります。 第二に、よりアクティブな攻撃者がネットワークのトラフィックをモニ ターしている可能性があります。セッションIDが暗号化されていない場 合、セッションIDはネットワーク上を平文テキストで伝送されます。 解決策はサーバ上にSSLを実装し、ユーザにSSLを必ず使用させることです。
セッションとセキュリティ
Anurag Jain
13-Dec-2008 01:28
13-Dec-2008 01:28
JonathanFeller at NOSPAMgmx dot ch
28-Oct-2008 04:22
28-Oct-2008 04:22
Perhaps, you would also like to timeout a session after some idle time. I noticed that session.gc_maxlifetime is not suitable for this. So I used this code to do the job:
<?php
if (!isset($_SESSION['timeout_idle'])) {
$_SESSION['timeout_idle'] = time() + MAX_IDLE_TIME;
} else {
if ($_SESSION['timeout_idle'] < time()) {
//destroy session
} else {
$_SESSION['timeout_idle'] = time() + MAX_IDLE_TIME;
}
}
?>
Olle Bergkvist
22-Oct-2008 06:47
22-Oct-2008 06:47
It is also quite important to (somehow) make sure that the cookies you're setting (including the session cookie) is only visible to the site that created it (or to other trusted sites only).
If the cookie's path is set to '/' (the whole domain), then any website on the same domain (might be lots of websites) _will_ get the cookie through HTTP headers and could possibly hijack your session.
One slightly acceptable protection would be to lock a session to one IP adress.
