セッションに関して、主に考慮すべき問題は、セッション識別子の機密性です。機密情報であれば、セッションハイジャックの危険はありません。正当なセッション ID を使用すると、攻撃者はユーザーの 1 人になりすますことができます。
攻撃者は次の 3 つの方法で正規のセッション ID を取得できます。
を使用して
l修正しました
PHP は非常にランダムなセッション ID を生成するため、推測されるリスクは存在しません。セッション ID を取得するためにネットワーク通信データをキャプチャするのが一般的です。セッション ID が取得されるリスクを回避するために、SSL を使用することができ、ブラウザの脆弱性には適時にパッチを適用する必要があります。
ヒント
ブラウザーは、リクエストの Set-Cookie ヘッダーの要件に基づいて、後続のすべてのリクエストに対応する Cookie ヘッダーを含めることに注意してください。最も一般的なのは、画像などの埋め込みリソースに対するリクエストでセッション ID が不必要に公開されることです。たとえば、10 個の画像を含む Web ページをリクエストする場合、ブラウザはセッション ID を使用して 11 個のリクエストを発行しますが、その識別子で必要となるのは 1 つだけです。この不必要な公開を防ぐために、すべての埋め込みリソースを別のドメイン名のサーバーに配置することを検討できます。
セッション固定は、被害者をだまして攻撃者が指定したセッション ID を使用させる攻撃手法です。これは、攻撃者が正当なセッション ID を取得する最も簡単な方法です。
この最も単純な例では、セッション固定攻撃にリンクが使用されています:
<a href="http://example.org/index.php?PHPSESSID=1234">Click Here</a>
別の方法は、プロトコルレベルのリダイレクトステートメントを使用することです:
りー
これは、実際の HTTP ヘッダーまたはメタ タグの http-equiv 属性のいずれかを指定することによって生成される Refresh ヘッダーを介して行うこともできます。攻撃者の目的は、攻撃者が指定したセッション ID を含む URL にユーザーをアクセスさせることです。これは基本的な攻撃の最初のステップです。完全な攻撃プロセスを図 4-3 に示します。
図 4-3. 攻撃者が指定したセッション ID を使用したセッション固定攻撃
成功すると、攻撃者はスクレイピングや推測を回避できる 正当なセッション識別の必要性より危険な攻撃を仕掛けることが可能になります。
このステップをよりよく理解するには、自分で試してみるのが最善です。まず、fixation.php というスクリプトを作成します。 現在のサーバーに Cookie が保存されていないことを確認するか、すべての Cookie をクリアしてこれを確認してください。 PHPSESSID を含む URL から fixation.php にアクセスします:
http://www.php.cn/
値 chris を持つセッション変数 username を作成します。セッションストレージ領域を確認したところ、1234 がデータのセッション ID になっていることがわかりました:
<?php
header('Location:
http://www.php.cn/');
?>
$ に 2 番目のスクリプト test.php を作成します。 _SESSION['ユーザー名'] 存在する場合は、値を入力します:
<?php session_start(); $_SESSION['username'] = 'chris'; ?>
在另外一台计算机上或者在另一个浏览器中访问下面的URL,同时该URL指定了相同的会话标识:
http://www.php.cn/
这使你可以在另一台计算机上或浏览器中(模仿攻击者所在位置)恢复前面在fixation.php中建立的会话。这样,你就作为一个攻击者成功地劫持了一个会话。
很明显,我们不希望这种情况发生。因为通过上面的方法,攻击者会提供一个到你的应用的链接,只要通过这个链接对你的网站进行访问的用户都会使用攻击者所指定的会话标识。
产生这个问题的一个原因是会话是由URL中的会话标识所建立的。当没有指定会话标识时,PHP就会自动产生一个。这就为攻击者大开了方便之门。幸运的是,我们以可以使用session_regenerate_id( )函数来防止这种情况的发生。
<?php session_start(); if (!isset($_SESSION['initiated'])) { session_regenerate_id(); $_SESSION['initiated'] = TRUE; } ?>
这就保证了在会话初始化时能有一个全新的会话标识。可是,这并不是防止会话固定攻击的有效解决方案。攻击者能简单地通过访问你的网站,确定PHP给出的会话标识,并且在会话固定攻击中使用该会话标识。
这确实使攻击者没有机会去指定一个简单的会话标识,如1234,但攻击者依然可以通过检查cookie或URL(依赖于标识的传递方式)得到PHP指定的会话标识。该流程如图4-4所示。
该图说明了会话的这个弱点,同时它可以帮助你理解该问题涉及的范围。会话固定只是一个基础,攻击的目的是要取得一个能用来劫持会话的标识。这通常用于这样的一个系统,在这个系统中,攻击者能合法取得较低的权限(该权限级别只要能登录即可),这样劫持一个具有较高权限的会话是非常有用的。
如果会话标识在权限等级有改变时重新生成,就可以在事实上避开会话固定的风险:
<?php $_SESSION['logged_in'] = FALSE; if (check_login()) { session_regenerate_id(); $_SESSION['logged_in'] = TRUE; } ?>
Figure 4-4. 通过首先初始化会话进行会话固定攻击
小提示
我不推荐在每一页上重新生成会话标识。虽然这看起来确实是一个安全的方法。但与在权限等级变化时重新生成会话标识相比,并没有提供更多的保护手段。更重要的是,相反地它还会对你的合法用户产生影响,特别是会话标识通过URL传递时尤甚。用户可能会使用浏览器的访问历史机制去访问以前访问的页面,这样该页上的链接就会指向一个不再存在的会话标识。
如果你只在权限等级变化时重新生成会话标识,同样的情况也有可以发生,但是用户在访问权限变更前的页面时,不会因为会话丢失而奇怪,同时,这种情况也不常见。
以上就是PHP安全-会话固定的内容,更多相关内容请关注PHP中文网(www.php.cn)!