我的网络会话处理过程中是否存在缺陷?

时间:2010-01-28 21:52:07

标签: perl cgi session

好的,这样做的方式是用户通过Web表单进行身份验证并生成会话ID,如下所示:

sub session_open
{
    my $sid;
    my $user = shift;

    if ( open(SEMA, "> ../sema/sess") )
    {
        flock SEMA, LOCK_EX;
        do 
        {
            $sid = generate_session_id();
        } 
        while ( -d "$SDIR/$sid" );
        my $sstr = "$user:$ENV{'HTTP_USER_AGENT'}";
        write_file('>', "$SDIR/$sid", $sstr);
        close SEMA;
    }

    return $sid;
}

然后会话ID被传递到url中的每个页面,如果会话文件存在并且检出他的用户代理和远程地址,它允许用户继续:

sub check_sid
{   
    my $sid = shift;
     return 0 if $sid =~ /[^\w\d]/;
    return 0 if !open(SID, "< $SDIR/$pid");
    my ($user, $agent) = split /:/, <SID>, 2;
    close SID;
    return 0 if $agent ne $ENV{'HTTP_USER_AGENT'}";
    return $user;
}

在后台我有一个cron作业,每5分钟运行一个脚本,到期时间为2小时:

foreach (<../session/*>)
{
    unlink $_ if -M $_ > 0.08333;
}

我在这里有任何瑕疵和不必要的步骤吗?我想使用user_agent和remote_addr,因为以这种方式插入会话ID会更难。

2 个答案:

答案 0 :(得分:9)

您不能假设用户和IP地址之间存在1-1对应关系。多个人可能来自同一个IP地址(代理后面)。可能涉及多个IP地址(用户通过负载平衡或故障转移反向代理)。

任何将IP地址混合到会话方案中的尝试最终会在您最不期望的时候中断,所以不要这样做。

如果您关心会话,请使用SSL。

答案 1 :(得分:4)

使用CGI::Session。另请参阅CGI::Application::Plugin::Session

  • session_open中有竞争条件。

  • 您的会话处理代码是否允许将任何其他会话信息写入会话文件?

  • check_sid,您有my $sid = shift;,但您尝试打开"$SDIR/$pid"

  • 即使您已正确命名要插入到文件名中的变量,也有一个明显的缺陷,即您没有取消会话ID(即,您信任未经检查的输入)。将此与您使用open的两个参数形式的事实相结合,并且有趣的可能性出现。

在任何情况下,任何人都没有理由编写会话处理代码。这项工作已经为你完成了。不要重新发明轮子。