涨姿势:jQuery 曾经的 XSS 漏洞

最近我管理的一台服务器被怀疑被利用发起 DoS 攻击(详情见长文学习构建之法(2):课程总结),被有关管理单位查了水表。他们附送了一份检测报告,指出我们存在若干安全漏洞。其中一条引起了我的兴趣。

URL:http://SSAST.ORG/static/javascripts/libs/jquery.js。
详情:发现存在漏洞的’jquery’库,版本号:’1.6.2’。
风险:中危。

此外还报告了 jquery-ui-dialog 版本 1.8.11。

科协主页确实很老了,还在用上古时代的 jQuery 的上古版本。令我很感兴趣的是,前端的漏洞,除了 XSS 或者 CSRF 还能是啥?jQuery 这种万众瞩目的库,难道不是经过无数人 review?还能出这种问题?

我选择去找我的好朋友,Google.com。

google-jquery-1-6-2

哈哈,I’m feeling lucky. 点开,果然是 XSS。CVE-2011-4969#9521 jQuery Bug Tracker

我感觉这不能算是 jQuery 的漏洞,而在于程序员对 jQuery 的用法。简言之,很多知名网站和前端库里有 $(location.hash) 这样的写法(然而我无法理解为什么要这样做)。攻击方法是诱导用户点击精心构造的合法 URL,比如 http://example.com/#<script>alert('hello');</script>

jQuery 1.6.3 的 Release Note 指出该漏洞已被修复,方法简单粗暴,$() 用一个正则表达式来过滤,拒绝任何跟在 # 字符后面的 HTML 标签。

学习构建之法(2):课程总结

 

 

年底、期末,在繁忙之中,我和我的团队完成了“微学堂”这一产品。伴随着它的交付,《软件工程》结课了。我现在是本科三年级,两年半以来修了五十多门课,应该说这一门是挑战度最高的。最后几周,不时有通知“下周的课不上了,各个小组自己做团队项目”:相对于课堂听讲,课外需要付出的精力之多,由此可见。

即使以代码行数衡量并不是,我感觉这个团队项目是我经历过的规模最大的项目,大到另我有无法驾驭的恐慌。不过这样说也不公平,这种“out of hand”的感受不仅来自这个项目本身,也有来自其他课程、辅修专业、社会工作等等带来的压力。然而话说回来,我直观上的感受就是,作为组长我不清楚每一个组员都具体做了什么、用什么方法做的。不可能有一人 review 每一段代码;不可能有一人了解项目中的全部实现细节;更不可能凭一人之力完成。

与此相比,此前的和本学期其他的“大作业”都只是小打小闹。不点名提及这学期的某些课程的某些 Project:一人花几个小时就做完,好意思说它是 Project?顶多算个 Assignment 好吧。如果把这些都算上,那么我这学期可能做了 20 个大作业,恩,说出来挺唬人(划掉)。

 

Donald Knuth 有一句名言:过早优化是万恶之源。项目中还存在一些过度设计的问题。其实这些词我都不是很懂,通过这个团队项目,只是感觉对此有了一些浅薄的理解。

中途出现的需求变更对我们造成了不利影响——来自教师的一条非功能性需求:我们被要求使用另一小组提供的 API 服务,而非自己编写相关模块。为了保证进度,我没有选择重构,而是把这个 API 服务做了一层包装,以保持接口不变而替换原有模块。这带来了架构上的冗余和“不优雅”。

这里所说的模块是一组爬虫。爬虫总有个运行频率的限度,而用户总是希望得到最新的信息,而且希望在最短时间内得到最新的信息。针对这一矛盾,我们设计了后台定时触发的“自动刷新”和用户手动触发的“强制刷新”这两种不同的刷新,同一个接口设计同步和异步两种调用方法。结果,因为他们 API 服务没能支持,全都白费功夫啦。

值得一提的是,做 API 服务的那组同学似乎并没有考虑运行频率的限度的问题。他们对爬虫的目标,也就是我校网络学堂和综合教务系统,发起高频次、高并发的请求,形成 DoS 攻击,造成网络学堂压力过大、反复宕机。运行着他们 API 服务的那台服务器,其 IP 被学校封禁。不巧的是,该台服务器是由我管理的。简言之,我因为他们被查水表了……这导致我不得不花大量的精力来与上级管理人员沟通,撰写需要同时抄送给三四个单位的整改报告——这影响了我们的进度。

我们在最初设计时,在安全性上花了很多精力。我们使用 OAuth,我们使用 https,避免用户信息的泄露。实现时,微信公众平台 OAuth 那一套牵扯了我们更多的精力:除代码编写外,开发环境搭建、调试、测试等方方面面都有复杂性的增加。结果呢,直到最后,我们的上游,也就是上文提及的 API 服务,也没有实现任何对调用者身份的验证。数据全部明文传输。他们的 mongodb 数据库甚至不设密码,直接暴露在外(这也是上文提及我被查水表的原因之一,原话是“存在高危安全隐患”)。

只要有一环出了问题,整个安全链条就会断掉。API 组糟糕的安全性意味着我们的用户的一切信息都会被公开在国际互联网上,也就意味着我们在安全性上的努力全部白费——除了在文档中写上一笔,期盼因此获得作业成绩的加分。好气啊!

 

花了这么多篇幅吐槽 API 组。我们自己得到的教训是:应该循序渐进。特别是在敏捷的语境下,不能一开始就想着搞出完美的设计“一步到位”,不能指望一开始就把所有细节都考虑周全。一开始最好是设计得简单些,keep it simple and stupid,在反复迭代中进行改进,边写边重构。

通过这个项目,团队管理上的经验也积累了不少。把一个团队带好,这是非常困难的,我一直觉得我在这方面没有缺少天赋,适合埋头干活,而不是做一个管理者。这回做组长,让我在这方面增加了一些经验,也增加了一些自信(笑)。具体的经验可以列一些,比如重要的事情不能只口头说——在微信群里说也算“口头”——要形成文档,形成书面的东西。

 

最后说回这个课程本身吧。除了做项目的锻炼之外,通过课堂讲授,我的理论水平也得到了提高——SC、CC、MCC、CDC 等度量测试覆盖的一堆词儿;系统的 actor、stakeholder,UML 状态图、顺序图、活动图,用户故事、用例建模,需求工程的那一套理论;接触了几种设计模式;关于团队、流程一些成熟经验……作为一门工科专业课,竟也有了一分管理学的味道。

建议就没什么了,各方面都挺好的。只有一条,那就是一组来搞 API、其他组使用的这种玩法,估计明年不会再搞了吧(逃)

 

这是《软件工程》课程系列博客的最后一篇。
相关文章:
学习构建之法(1):写个微信抢票
django 性能调优手记
“结对编程”初体验

Electronic Trading Challenge 酱油记

上个周末刚参加了 Jane Street 举办的 Electronic Trading Challenge Tsinghua Event。三只大三狗,大作业的汪洋大海之中。成绩是 19 支队伍的第 11。本文也很水,预警一下( ̄(工) ̄)

## 体验

简言之就是新奇、有趣。我都想开个户玩真的了。

还有便是认识到了差距,感觉自己好菜啊( ̄(工) ̄)

## 比赛概况

编写程序在虚拟市场里交易。市场上有 4 支个股、2 个基金,还有国库券。除了参赛队之外,市场里还有做市商。交易所提供每种证券的订单簿和订单成交信息。每个交易日持续 5 分钟,每天都是两手空空从头开始,每天结束后系统按照某种公允价值计算盈亏积分。比赛从上午九点持续到晚上九点,划分为一个一个 5 分钟,选手可以随时修改程序,加入或退出市场。

## 我们队的套利策略

我们首先花了点时间通读文档。叶曦在根据交易所的协议编写 API,我和江昊琛先开始研究怎么赚钱。因为暂无 API 可用,我们就用 nc 命令强行手动下单,结果一单亏了 2 块钱,这 2 块钱使我们队一连几个小时都以负的积分排名垫底……好气哦。

基金可以和对应篮子直接互相兑换,无论价格如何,只收固定的手续费。我们首先看到了这里面的套利机会。例如,X 能兑换 2 A + 3 B + 2 C。某一时刻 X 的买入价是 9,A 的卖出价是 2、B 的卖出价是 1、C 的卖出价是 3。那么我就可以花 9 元买入一个 X,兑换成 2 个 A、3 个 B、2 个 C,然后分别卖出去,得到 2 x 2 + 3 x 1 + 2 x 3 = 11 元。从左手搬到右手,9 元就变成了 11 元,只要兑换的手续费低于 2 元,我就赚了。

实际的价格并不是常数,而是数量的一个分段线性的函数。这个函数可以根据订单簿计算出来。对于买方报价,各段斜率是递减的;对于卖方报价,各段斜率是递增的。

Buys         Sells
Price Volume Price Volume
8     3      9     4 
7     2      11    3
6     2      12    4
4     4

随便编了个数字例子。对于给定的证券,买方报价总是低于卖方报价的,否则就直接成交了。X 的价格满足这个关系,ABC 的价格(A、B、C 的价格的加权和)也满足这个关系,但是 X 的价格和 ABC 的价格之间就不一定了。它们都会波动,很可能存在某些时刻,X 的价格和 ABC 的价格不匹配,这叫市场的瞬时无效性。

ABC 组合的曲线是用 A、B、C 的三条曲线按比例叠加得到的。

上图示意的情况下,我们可以买入 A、B、C,卖出 X,赚取差价。阴影部分就是机会啦。在横轴上找到一点,使买入 ABC 的总价与卖出 X 的总价之间的差额最大。如果这个差值大于手续费,我们就可以动手啦。同时还要关注反方向 X Sells 和 ABC Buys 两条曲线,以发现反方向的机会。

为完成这样的交易,需要同时盯着 4 组订单簿,随时更新 10 个总价格函数。每次操作要同时下 5 个订单。价格差转瞬即逝,这种事情显然只有程序能做。

说实在的,策略很简单,模型也很简单,但我们实在是太菜了。大概上午十一点开始写,晚上五点才把它调试好上线。

说实在的,策略很简单,模型也很简单,但我们实在是太菜了。大概上午十一点开始写,晚上五点才把它调试好上线。在此之前我们队只是简单地倒卖国库券,每个交易日的收益徘徊于两位数;后来叶曦做了几个我搞不懂的策略,提高到几百,但是波动似乎很大。等到这个套利策略上线,收益就稳定在 1000 元左右了。

## 差距

凭着这个套利策略,在比赛的最后几个小时,我们的排名上升了 3 位。后来我们了解到,前几名的队伍每个交易日的收益都在 10000 元以上。数量级上的差距,确实难以望其项背。

## 收获

打了一整天酱油,反正三顿饭都很不错。连续十个小时写代码,感觉很爽的。要说收获,也就是见了见世面吧,体验了一下 Hackathon 这种形式,对证券市场有了些感性认识。

(本文首发于知乎