联系支持

我们通过电子邮件回复,通常两天内。

为防止滥用,Google reCAPTCHA 会检查这次提交,其间会向 Google 传输数据。脚本只在你打开此表单时才加载。

← 全部文章

"pl"曾经指两种不同的东西

2026年8月19日,我们在.htaccess里加了一条规则,用来拦截一类绝不应该被直接提供给浏览器的文件:编辑之后遗留在网站根目录里的源代码副本——比如index.php.bak、一个散落的config.py,或者任何带脚本扩展名、访客有可能以纯文本形式获取到源代码而不是让它运行起来的文件。

这条规则是按文件扩展名匹配的:.php.py.rb.pl,以及其他十几种。.pl是Perl语言的扩展名。这个项目里没有一行Perl代码——这条规则纯属预防性质,并不是为了修复某个已经存在的文件。

大约一天之后,有一位访客反映计数器预览图坏掉了。是全部预览图都坏了,但只发生在一种语言上。

另一个"pl"

stats4u.net是通过Accept-Language协商为每位访客选择语言的,而不是用一个固定的默认值——浏览器语言设为波兰语的访客会被直接送到/pl/,不涉及任何跳转,而当没有任何匹配时,网站会回退到英语。波兰语是一个常见的匹配结果:落在这个语言版本上的访客足够多,所以缩略图坏掉一天,不可能长时间不被人发现。

每一张样式预览图,都是每种样式、每种语言各一个小文件:cache/preview/2900.pl.svg。原本用来拦截something.pl——也就是Perl脚本——的这个匹配模式,同样也匹配到了2900.pl后面再跟着.svg的情形:一个样式编号,一个碰巧和某个脚本扩展名拼写相同的语言代码,再加上真正的文件类型。一个"点pl点"的匹配模式,没办法区分这两种情况。

样式库里所有.pl.svg.pl.png预览图,全都开始返回403 Forbidden。其他所有语言都没有受影响,因为这个网站使用的其他语言代码,没有一个和扩展名列表里的条目发生冲突。只有这一个撞上了。

做了什么改动

pl被从扩展名列表里移除了。这条规则仍然会拦截这个项目有理由担心的每一个真实脚本扩展名;但它不会再拦截一种语言了。

值得把这件事的起因写下来:文件扩展名列表和语言代码列表,来自两套不同的词汇体系,没有什么能阻止一个两个字母的条目同时是这两套体系里的成员。在一个路径里带有语言前缀的网站上,往任何一份列表里添加条目之前,都应该对照另一份列表检查一遍。我们没有这么做,结果是靠一位读者注意到缩略图坏了——而不是靠我们自己的监控——才发现了这个问题。