PHP安全编程之会话数据注入

时间:2022-10-25 21:12:59
一个与会话暴露类似的问题是会话注入。此类攻击是基于你的WEB服务器除了对会话存储目录有读取权限外,还有写入权限。因此,存在着编写一段允许其他用户添加,编辑或删除会话的脚本的可能。下例显示了一个允许用户方便地编辑已存在的会话数据的HTML表单:

<?php  
  
session_start();  
  
?>  
  
<form action="inject.php" method="POST">  
  
<?php  
  
$path = ini_get('session.save_path');  
$handle = dir($path);  
  
while ($filename = $handle->read())  
{  
  if (substr($filename, 0, 5) == 'sess_')  
  {  
    $sess_data = file_get_contents("$path/$filename");  
  
    if (!empty($sess_data))  
    {  
      session_decode($sess_data);  
      $sess_data = $_SESSION;  
      $_SESSION = array();  
  
      $sess_name = substr($filename, 5);  
      $sess_name = htmlentities($sess_name, ENT_QUOTES, 'UTF-8');  
      echo "<h1>Session [$sess_name]</h1>";  
  
      foreach ($sess_data as $name => $value)  
      {  
        $name = htmlentities($name, ENT_QUOTES, 'UTF-8');  
        $value = htmlentities($value, ENT_QUOTES, 'UTF-8');  
        echo "<p>  
              $name:  
              <input type=\"text\"  
              name=\"{$sess_name}[{$name}]\"  
              value=\"$value\" />  
              </p>";  
      }  
  
      echo '<br />';  
    }  
  }  
}  
  
$handle->close();  
  
?>  
  
<input type="submit" />  
</form>  


脚本inject.php执行由表单所指定的修改:

<?php  
  
session_start();  
  
$path = ini_get('session.save_path');  
  
foreach ($_POST as $sess_name => $sess_data)  
{  
  $_SESSION = $sess_data;  
  $sess_data = session_encode;  
  
  file_put_contents("$path/$sess_name", $sess_data);  
}  
  
$_SESSION = array();  
  
?>  

此类攻击非常危险。攻击者不仅可以编辑你的用户的数据,还可以编辑他自己的会话数据。它比会话劫持更为强大,因为攻击者能选择所有的会话数据进行修改,从而使绕过访问限制和其他安全手段成为可能。

针对这个问题的最好解决方案是将会话数据保存在数据库中。参见专题前面的内容。