模糊比精确更精确——判断URL是否存在

判断一个URL是否存在,是扫描中最简单的一种。不过要做好,也不容易。很久很久以前,大家都比较淳朴的时候,存在即返回200,不存在返回404。这个时候的扫描器比较好做,直接判断HTTP的返回头状态码就可以了。

现在基本上都rewrite了,很少遇见返回404错误的情况。于是常规的扫描是先生成一个随机的足够长的URL去请求服务器,得到标准的错误页面。随后遍历字典将返回的内容与标准页面对比,一致则判定为该URL不存在。这样有个问题就是很多错误页面会有一些随机化的内容,比如当前时间、当前服务器域名或者错误的URL内容等。要命的是这个不同内容各个网站是不同的,要做一个通用的扫描还有一些难度。

于是这里引入字符串相似度判定算法,使用模糊的方式确认URL是否存在。简单的说,返回的页面与标准错误页面相似程度非常高,达到90%以上,我们就可以判定为这个URL是存在的。这样,问题就转化成了相似度计算了。我在《URL相似度分析》中提到过集中算法,其中“编辑距离”算法刚好可以满足这里的需求。

做到这里,已经能够解决很多问题了,但是还不够。举个例子来说,我们有些网站请求/aaaaa时跳转到中文站主页,请求/bbbbbb时跳转到国际站主页。同样是错误跳转,但是总有一个和标准错误的页面相似度非常低,会被误报为URL存在。穷尽所有的错误页面是不可能的,那么这种情况如何解决?

可以简单的引入返回页面长度这个指标。以标准错误页面长度作为基准长度,计算每次返回的长度相对于基准长度的变化值。一般来说,错误页面的长度和首页之类页面的长度变化还是比较大的,而中文站首页与英文站首页的长度变化则小得多。当请求一个URL得到的返回内容与标准错误页面相似度很低,并且长度变化很大时,判定这个URL存在,否则为不存在。

误报还是有的,但是至少好了很多。还有什么更好的办法?

此条目发表在技术分类目录。将固定链接加入收藏夹。

模糊比精确更精确——判断URL是否存在》有 10 条评论

  1. 淳朴说:

    大家都比较淳朴的时候
    当前Blog无任何评论

  2. ellle说:

    呵呵,云舒牛说的这方法,莫不是和操作系统判断的指纹识别类似?不过碰到rewrite的网站用一般的扫描器来扫误报率太高,相似度判断需要一个库了,库的数据比较重要~云舒牛是不是弄个开源的库?

  3. 冒充的人说:

    不是指纹库,而是对待扫描的IP取一个不存在的URL,将得到的返回代码作为标准错误页面。然后轮流请求字典中的URL,将得到的内容与标准页面对比。这个算法就是http://en.wikipedia.org/wiki/Edit_distance

  4. ellle说:

    @冒充的人
    大概明白了!thx

  5. 淳朴说:

    我是一楼 来向云舒牛求助… 不知道有没搞过Mysql数据的字符集转换? 我需要从utf8_general_ci 转到 gbk_chinese_ci 求助求助~~~~

  6. 一凡说:

    办法就是不要试图把所有的事情都做成通用的

  7. 云舒说:

    看要解决的问题咯~有的场景需要通用,有的场景可以特殊。

  8. 淳朴说:

    我的场景是因为之前设计的失误,页面编码和数据库编码不一致,从而导致了虽然页面显示正常,但直接查看数据库中的数据是乱码.因此我用phpmyadmin导出来的数据也是乱码,更别想往GBK的库中导了. 我的想法是有没有办法把我通过phpmyadmin导出来的乱码文件转换成正常的GBK编码格式的? 因为虽然是乱码,但通过PHP程序调用到页面的是可以正常显示的.
    稍微通用也行呀 不通用的结果就是我用PHP读出来再插进去了十六W条记录 郁闷…

  9. 淳朴说:

    不是开玩笑哟 我觉得我的方法很笨

  10. 云舒说:

    不笨的,能解决问题就是好办法。

发表评论

电子邮件地址不会被公开。 必填项已用*标注