Perl 我的web会话处理过程中是否存在缺陷?
好的,这样做的方式是用户通过web表单进行身份验证并生成会话ID,如下所示:Perl 我的web会话处理过程中是否存在缺陷?,perl,cgi,session,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(); }
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\u agent和remote\u addr,因为这样就很难插入某人的会话ID。使用。另见
会话_open中存在竞争条件
会话处理代码是否允许将任何其他会话信息写入会话文件
在check_sid中,您有我的$sid=shift;但您尝试打开$SDIR/$pid
即使您正确地命名了要插入到文件名中的变量,也存在一个明显的缺陷,即您没有解开会话id,即您信任未经检查的输入。结合这一事实,你正在使用开放式的两个参数形式,有趣的可能性呈现出来
在任何情况下,任何人都没有理由编写会话处理代码。工作已经为你完成了。不要重新发明轮子。您不能假设用户和IP地址之间存在1-1对应关系。多人可能来自同一IP地址的代理。用户通过负载平衡或故障转移反向代理可能涉及多个IP地址 任何将IP地址混合到会话方案中的尝试最终都会在您最不希望的时候中断,所以不要这样做
如果您关心会话,请使用SSL。我向会话\u open添加了一个信号量,但这能解决问题吗?我一直不明白LOCK_EX是否可以跨所调用脚本的多个实例工作。此外,我还没有找到CGI::Session的任何地方的例子,在这里,您可以从每个页面传递一个会话ID,并让它使用现有的会话ID。我见过的任何CGI示例总是在隐藏字段中传递用户名/密码,然后再次登录用户,您知道有什么好的教程吗?此外,它不允许编写任何其他会话信息,它实际上不是一个“会话”,而是一种机制,不必在页面之间发送编码密码来确定用户是否登录。我确实不需要存储任何实际的会话数据。@未知请参阅CGI::Application::Plugin::session示例或CGI:session文档:将当前$CGI实例传递给CGI::session构造函数。在隐藏字段中传递用户名/密码信息没有意义。此外,如果您不需要存储会话信息,为什么不使用HTTP身份验证?ADDR的目的不是提供1-1的协同响应,而是添加另一层安全性,我想,如果有人获得了Person会话ID,他们还需要知道Person IP和user client。虽然如果他们有会话id,他们可能已经知道ip…Randal的观点是,单个用户在单个会话期间可能有多个ip。将会话绑定到特定IP地址会给这些用户带来问题。我只想指出,CGI::session模块建议您使用IP检查作为安全措施。