哪些可能引起前端安全问题
-
跨站脚本(Cross-Site Scripting)一种代码注入方式,为了与css区分所以被称作xss。
- 向页面或url链接中注入js代码
-
iframe的滥用:iframe中的内容是由第三方提供的,默认情况下他们不受我们\控制。
-
跨站点请求伪造(Cross-Site-Request Forgeries,CSRF):指攻击者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息或设定信息等某些状态更新,属于被动攻击。
- 利用用户已登录网站的cookie,发起伪请求
-
恶意第三方库
-
SQL注入
-
文件上传
1.XSS分类
就是攻击者想尽一切办法将可执行的代码注入到网页中。
根据攻击来源可分为存储型、反射型(非持久型)、DOM型三种。
存储型和反射型的区别:存储型恶意代码存储在数据库里,反射型恶意代码存储在URL中
DOM型和前两种的区别:DOM型XSS攻击中,取出和执行恶意代码由浏览器前端完成,属于前端JavaScript自身的安全漏洞,而其他两种属于服务端的安全漏洞。
如何预防XSS
XSS攻击有两大要素:
(1)攻击者提交恶意代码
(2)浏览器执行恶意代码
预防方案:
- 对数据进行严格的输出编码(如js编码、css编码、url编码等;避免拼接html)
- 输入验证:对常见的数字、url、电话号码、邮箱地址等校验;验证码;
- 开启浏览器XSS防御(http Only cookie)。
通常有两种方式:
- CSP:本质就是建立白名单,告诉浏览器哪些外部资源可以加载和执行。可以通过两种方式开启CSP:
设置HTTP Header中的content-security-policy
设置meta标签的方式
- 转义字符:转义用户输入输出的内容,对于引号、尖括号、斜杠进行转义。但是,对于富文本不能通过上面的方式转义所有的字符,这种情况通常采用白名单过滤。
- HttpOnly Cookie:预防XSS攻击最有效的防御手段。(通过js脚本将无法读取到cookie信息,但可以通过request.getCookies()读取)
2.CSRF:跨站请求伪造
攻击者诱导受害者进入第三方网站,然后向被攻击网站发送跨站请求,利用受害者在被攻击网站的注册凭证,绕过后台验证,冒充用户对被攻击网站执行操作。
如何预防CSRF
- 同源检测:http协议试用referer属性确定来源
- CSRF Token校验:页面提交请求携带这个token,服务器验证token是否正确
- 双重cookie验证
- HTTP自定义属性验证收到反
- 显示验证方式:添加验证码、密码等
3.iframe的滥用
h5中,出现了一个叫sandbox的属性,可以对iframe的行为进行限制,实现最小权限。试用方式如下:
<iframe sandbox src="..."> ...</iframe>
sandbox也提供了丰富的配置参数:
- allow-forms:允许iframe中提交form表单
- allow-popups:允许iframe中弹出新的窗口或者标签页(例如,window.open(),showModalDialog(),target=”_blank”等等)
- allow-scripts:允许iframe中执行JavaScript
- allow-same-origin:允许iframe中的网页开启同源策略
4.点击劫持(ClickJacking)
攻击者将需要攻击的网站通过iframe嵌套的方式嵌入自己的网页中,并将iframe设为透明,在页面透出一个按钮诱导用户点击。
如何防御:
-
X-FRAME-OPTIONS:是一个HTTP响应头,为了防御iframe嵌套的点击劫持攻击,有三个值:
DENY(不能被所有网站嵌套或加载)、SAMEORIGIN(只能被同域网站嵌套或加载)、ALLOW-FROM(可以被指定网站嵌套或加载)。
-
JavaScript防御:js代码。
5.CDN劫持
前端静态资源一般存放在cdn,也会被攻击者劫持。
现在的CDN以支持SRI为荣,script和link标签有了新属性integrity,是为了防止校验资源完整性来判断是否被篡改,它通过验证获取文件的哈希值是否和你提供的哈希值一样来判断资源是否被篡改
使用 SRI 需要两个条件:一是要保证 资源同域 或开启跨域,二是在 以供校验。
6.sql注入
-
通过把sql命令插入到web表单提交或输入域名或页面请求的查询字符串,欺骗服务器执行恶意的sql命令。
-
攻击方式:
- 直接注入式攻击
- 间接攻击方法:将恶意代码注入要在表中存储或作为原数据存储的字符串
const isDev = process.env.NODE_ENV === 'development'
// 开发|测试|仿真|生产:dev|qas|stg|prd
;[
{
env: 'dev',
baseUrl: isDev ? '/' : '//',
ajaxBaseUrl: isDev ? '/' : '//'
},
{
env: 'prd',
baseUrl: '//',
ajaxBaseUrl: '//'
}
].forEach(it => {
const { env } = it
config.plugin(env === 'dev' ? 'html' : `html-${env}`).use(HtmlWebpackPlugin, [
{
template: 'public/index.html',
filename: isDev && env === 'dev' ? 'index.html' : `index-${env}.html`,
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
removeAttributeQuotes: true
},
VAR: it
}
])
})