惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Check Point Blog
Hacker News: Ask HN
Hacker News: Ask HN
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
WordPress大学
WordPress大学
P
Proofpoint News Feed
V
Visual Studio Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
N
Netflix TechBlog - Medium
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 叶小钗
Cisco Talos Blog
Cisco Talos Blog
S
Schneier on Security
T
Threat Research - Cisco Blogs
腾讯CDC
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Hacker News
The Hacker News
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
GbyAI
GbyAI
N
News | PayPal Newsroom
L
LINUX DO - 最新话题
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Palo Alto Networks Blog
T
Tenable Blog
S
Secure Thoughts
T
Threatpost
V2EX - 技术
V2EX - 技术
大猫的无限游戏
大猫的无限游戏
Martin Fowler
Martin Fowler
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Vercel News
Vercel News
罗磊的独立博客
P
Privacy & Cybersecurity Law Blog
Engineering at Meta
Engineering at Meta
小众软件
小众软件
Google DeepMind News
Google DeepMind News
N
News and Events Feed by Topic
Y
Y Combinator Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
P
Privacy International News Feed
H
Heimdal Security Blog
量子位
B
Blog

博客园 - Janpoem

PHP的Session托管机制容易造成漏洞 关于PHP的Session处理的问题 Eclipse 3.5汉化包打包下载 [转]Benchmarking magic [转]重新发现HTML表格 [转]在网页中嵌入任意字体的解决方案 50款优秀而又实用的PHP工具 博文阅读密码验证 - 博客园 [转]NetBeans 6.5 界面美化与字体设置 [转帖]为 PHP 应用提速、提速、再提速! 昨日换了Ubuntu 8.10 10 SEO elements all websites should have 终于成功安装yaws和erlyweb了 笔记本CPU正常温度是多少? 不知不觉就一年了 谁把AIG拖垮了[转] asp.net MVC更新到preview 5了 什么样的女人值得叫老婆[转] 卸载windows服务
关于php session被保存在数据库中的一个小问题
Janpoem · 2008-11-12 · via 博客园 - Janpoem

session保存在数据库,关于性能方面可查看的资料不多。从以往的经验来说,将Session保存在数据库中,初步上是会觉得性能比File要略降。然而就数据库的特点来说,其本质也是二进制文件,所以,从大流量、广义上来说,保存在数据库,反而提高了性能和稳定性。加上Mysql可优化的地方很多,以及实现数据库保存后,将增加分站部署,安全监控等等诸多便利之处,所以长期来说,一个框架还是应该以提供将Session保存到数据库为基础方法的。

对于php保存到session的细节,网络上可搜罗的资料不多,来去都是基本介绍的方法,我手上几本关于php的书,也都是蜻蜓点水。根据最近的实际测试结果表明,仅仅实现session存储到数据库中,仍不足以保障其安全,关键点在php对于session的gc控制。这个在phpchina.com有很翔实的说明,通过设定:session.gc_probability和session.gc_divisor,可以控制gc执行的几率。

然而我们会发现,问题的关键不在于何时执行gc,因为无论是基于数据库还是File,面向更广的应用时,操作的数量都会呈几何增长,增加系统的gc执行率,无疑增加了系统的负担。那么不执行gc会导致什么问题发生呢?比如我们考虑以下的基本session模式:

session表的基本字段:sid,value,expire,session控制方法(请参照一些最基本的示范,我这里就不罗嗦了),实现最基本的open, close, find, write, destory, gc。

大多数的教程中,会建议我们,在find的方法中执行类似以下的一个SQL CMD:

select value from sessions where sid  = ? and expire > ?

那么,我们可以通过一些办法设置expire是否过期,比如,getExpire()返回一个具体的有效期。现在问题的关键是,大多数的教程告诉我们,我们应该这样去搜索session表,可是当expire过期的那些session呢?他仍然存放在session表中,而且他还保存了上一次会话的value。当然,这些过期的session并不会让value生效,但对于很多逻辑不够严谨的程序来说,却会造成一个致命的判断漏洞,比如一个图片验证码的实例:

在显示验证码的页面,我们给客户端的链接标识了一个$_SESSION['auth'] = 'xxxx',也许用户打开页面以后,忙别的事情去了,结果产生了session id,并且也将session id和auth的值写入到session表了。也许你设置的有效期是10分钟,也许是更长,但不管怎么样用户的操作是非线性的,总会打破你的预计。在有效期之外,他回到了需要验证码的页面,并且执行了某些程序,触发了后台的验证,那么程序本应该按照我们上面所设定的,执行find方法,并且取出auth的值去比对。然而这时候,php会很残酷的告诉你,没有auth这个索引所对应的值,因为find对于超过有效期外的session,就返回了一个false,或者一个null,或者别的什么了,总之,他没有返回你预期的结果。

也许,你后台验证码检验的代码是这么写的:

if ($_SESSION['auth'] === xxxx)

这时,假如你开启了报错,php会抛出一个警告,然后略过这部分,自顾自的执行下面的程序去。假如很不幸的你没开启报错,结果用户又一次巧妙的“溜”了过去。

这问题的严重性还在于,假如你并没有对php的gc处理设置一个合适的比率,他似乎不会执行去destory,那么这条过期的session一直会存在于你的session表中,用户会一次又一次的从这验证中“溜”过去。

有些介绍的文章,在session执行close的时候执行gc程序,我也对此方法进行的实验,但从整个非线性分布的情况来推测,每个客户端访问都会激活gc清理,gc的清理是以expire > ?为条件进行搜索的,也就是不管是也不是,总要来回一趟,而且一旦有符合条件的,还是批量删除,放在非线性的环境中,实在不敢估量。

我觉得,session的gc清理,可以被作为系统的进程来执行,比如类似RoR的做法。或者可放在网站的后台,进行人为的操作。而尽量减少php执行过程所消耗的时间(毕竟是动态语言,省一分是一分)。

而对于session,其实也仅仅是针对当前sid产生的,我将find的方法进行了一点修改:

select value,expire from sessions where sid = ?

sid一般都会被作为主键和索引,搜索的效率也相对较高。

接着进行判断:

if ($ses['expire'] > getExpire()) # 表示为有效
  return $ses['value'];
else { # 表示为无效
  # 这里执行destory方法
  return false;
}

也许方法早有人想到并提出来,不过可能鄙人水平有限没搜索到,也许还有更好的方法,欢迎指正。