Tag Archives

4 Articles

Content Security Policy 导致 bookmarklet 失效

近来发现在知乎、 Github 上我最常用的 bookmarklet (书签小工具,就是那种一句话 Javascript 书签)——饭否分享失效了。打开 Console 一看,有这样的提示:“Content Security Policy: 页面设置阻止读取一项资源:已经阻止执行内联脚本。”大概是孤陋寡闻,之前还没听说过 Content Security Policy 这玩意儿,猜测又是和 Cross-Origin Resource Sharing 有关系的什么东西,就做了一番搜索。

CSP 是一个可以限制页面中哪些 src (包括脚本、图片等等)可以被允许的实验性 HTTP Header 。这是 W3C Candidate Recommendation ,而这个是 MDN 上的相关资料。简而言之又是一个 defend by depth 的产物,可以给 XSS 防范再加上一层保险:直接禁止掉 inline script 和 inline eval ,然后给出一个允许加载的资源域的白名单,这样即使有 XSS 过滤漏洞,也无法注入站外的脚本。

但是问题就来了:用户直接在地址栏里输入的 Javascript 应该被允许么? Bookmarklet 应该被允许么? W3 文档这么说:

Enforcing a CSP policy should not interfere with the operation of user-supplied scripts such as third-party user-agent add-ons and JavaScript bookmarklets.

可事实是 Firefox ( Chrome 估计也是)没有正确实现,把 bookmarklet 也给拦截了,同时拦截掉了的还有 Lastpass 这样的插件的 JS 脚本,这也顺便解释了为什么 Lastpass 在知乎首页上无法自动填充的问题。

Github 博客上介绍这个新措施的文章里也提到了这个问题,并且给出了一个“解决方案”——直接把浏览器的 CSP 支持给禁用就好了……

Apache mod_rpaf 对于 allow/deny 指令无效

mod_rpaf (Reverse Proxy Add Forward)是 Apache 2.2 及更低版本中一个很有用的第三方模块,主要用于后端 Web Server ,可以将请求的 remote ip 重写为指定的字段(例如 X-Forwarded-For 或者 X-Real-IP )。很多网站目前都采用 nginx + Apache 的组合,这个模块可以使得转发对应用透明,应用按照普通方法即可获取到真实 IP ,不用修改代码来读取指定的 HTTP Header 。更优秀的是,这个模块对日志也是同样有用的—— access/error log 中记录的 IP 地址也会被修改为真实的 IP 。另外这个模块的自定义功能也很强大,可以任意指定使用哪一个 HTTP Header 字段、接受哪些前端转发 IP 等等。

然而正因为其强大,使得用户想当然地认为它在所有地方都有效,不曾想在 Apache 的访问控制(allow/deny 指令)中,该模块无效,访客 IP 仍旧是前端转发服务器的 IP !这个行为没有在文档中明确说明。我因此差点弄出了一个严重的安全问题——为了监控服务器我开启了 server-status ,本想都允许网关服务器访问以便在一个地方统一收集数据,就写了类似 allow from gate 这样的东西,结果 server-status 就一下子“门户大开”,所有人都可以看到了(因为都是经过前端网关代理的)。这个“问题”对 mod_rpaf 而言没有解决方案(除非修改代码)。另一个类似功能的模块 mod_remoteip (Apache 2.4 自带,有 backport 到 2.2 的版本)可以使得 allow/deny 能够使用真实 IP 。

PHP 应用隔离的几种方法

接着上回的话题,关于一个系统管理员能够给一台跑着多个应用的服务器做些什么来提高整体安全性。除了限制一些危险函数以外,很重要的便是尽可能地隔离不同的应用,以免一个瘫痪/被攻影响所有。其实,限制危险函数也是为了更好地实现应用隔离——接下来我们会看到,对于某些应用隔离方法,限制某些函数的调用是必须的。这里,我会大致按照隔离的效果降序给出几种常用方法。需要注意到的是,一般来说隔离效果越好,对性能的损失和其他副作用也越大。

Read More

禁用部分 PHP 函数加强系统安全

绝大多数 PHP 应用都只是单纯的 WEB 程序,很少用得到一些系统调用。一般最多用到一些列目录、读写删文件等。其他 system 、 passthru 等函数使用的最多的地方是 Web Shell 。作为一个运行着众多应用的服务器的运维,没有办法保证每一个程序的绝对安全,所能做的就是在自己的能力范围内尽可能增强系统安全性,通过权限隔离、限制等方法构筑“最后一道防线”。禁用一些一般不会用到的 PHP 函数就很有帮助。我的做法是在全局的 php.ini 中禁用掉这些函数,对于极个别需要其中某些函数的应用,在相应的 Apache VirtualHost/Directory 配置中通过 php_admin_value 来去掉限制。

Read More