web安全是前端领域绕不开的一个话题,许多程序猿只专注于业务实现,觉得攻击离自己很远,而安全相关的策略也只停留在面试层面。比较万幸的是我们最常使用的web服务器框架默认都会启用健壮而深思熟虑的措施来防范一些较常见的攻击!
对于一个没有考虑到安全问题的产品,很容易受到黑客的重点关注,从而造成严重损失!此文意在帮助前端人员认识前端安全,提高安全意识!
https://cloud.tencent.com/developer/article/1406118

XSS(Cross Site Scripting):跨站脚本攻击
攻击原理:通过破坏html/css/js的构造,来实现攻击,它不需要做任何的登录认证,通过合法的操作,向你的页面注入脚本;
导致的后果:
反射型(非持久型)&&DOM型
诱导用户点击带攻击的链接(可能是短链接),页面中包含获取链接参数并显示在页面的逻辑
攻击点包括所有可能运行JavaScript代码的地方:
html节点内容
通过.innerHTML、.outerHTML、document.write()将用户输入的信息直接插入到页面
html属性
href、src等html属性包含用户输入的代码, 比如包含javascript:可执行代码或者提前闭合属性,并在后面拼接js代码
js代码
代码中包含后台注入的变量或用户输入的内容
存储行(持久型):危害大、范围广
将攻击代码提交到数据库中,并在前端请求时返回。论坛、评论等是重灾区
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
来自于Unleashing an Ultimate XSS Polyglotopen in new window的一段用来检测HTML内容和属性、跳转链接、内联 JavaScript 字符串等多种上下文中的 XSS 漏洞的代码
防止攻击者提交恶意代码
对于明确的输入类型进行转码、过滤,但不要对不明确用途的输入进行转码,防止使用时出现乱码情况
// 转码
function escape(str) {
str = str.replace(/&/g, '&')
str = str.replace(/</g, '<')
str = str.replace(/>/g, '>')
str = str.replace(/"/g, '&quto;')
str = str.replace(/'/g, ''')
str = str.replace(/`/g, '`')
str = str.replace(/\//g, '/')
return str
}
//白名单过滤
const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1><script>alert("xss");</script>
输入内容长度控制
防止浏览器执行恶意代码
CSPopen in new window:查看兼容性open in new window
内容安全策略,最初的设计目的是减少XSS的攻击,后来的版本也可以防止其他形式的攻击,如点击劫持等;它的本质就是白名单制度,由浏览器进行拦截处理!
可以将相应的CSP政策放在Google 提供的 CSP Evaluatoropen in new window上检验
// 响应头
Content-Security-Policy:"default-src self; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * data:;";
// html -> head
<meta http-equiv="Content-Security-Policy" content="default-src self; script-src 'unsafe-inline' 'unsafe-eval'; img-src *;">
- CSP自诞生日开始就有很多安全人员在研究如何绕过CSP设置:文章open in new window
- CSP落地:针对已有项目,前期最好先用
Content-Security-Policy-Report-Only请求头,不阻塞资源加载,只对拦截进行上报,逐步增加调整适用于项目的规则后再上Content-Security-Policy
加深对XSS攻击的理解:谷歌 XSS 通关小游戏open in new window

CSRF(Cross-site request forgery):跨站请求伪造。
攻击原理:登陆网站A,诱导用户进入网站B,网址B向网站A发送跨域请求,利用用户存储在cookie的登陆凭证,绕过后台的登陆校验,进行非法操作的目的
导致的后果:在不知情的情况下,利用受害者登陆信息发起支付、自动评论、损坏网站声誉等攻击
GET类型的攻击:利用没有跨域限制的标签来实现攻击,比如img、script、link、iframe
<img src="http://test.bank.com/api/pay?money=100&card=12312312" >
POST类型的攻击:通常使用的是一个自动提交的表单
<form name="autoSubmit" action="http://test.bank.com/api/pay" method="POST">
<input type="text" name="card" value="11111">
<input type="text" name="money" value="100">
</form>
<script>document.autoSubmit.submit()</script>
可以发现攻击通常发生在第三方网站,自己的网站无法防止攻击发生,因此,防护的方式就需要依靠提高自己网站对CSRF的防护
根据三方网站发起攻击特点
根据攻击不会进入被攻击网站前端特点
https://juejin.cn/post/7357920285867343924?utm_source=gold_browser_extension#heading-1 https://www.bram.us/2018/02/21/css-keylogger-and-why-you-shouldnt-worry-about-it/ https://github.com/maxchehab/CSS-Keylogging

攻击原理:通过iframe设置透明或不透明的层来诱骗用户点击(拖拽)操作,而实际的操作的却是用户看不到的一个元素,从而达到在用户不知情的情况下实施攻击
导致的后果:钓鱼、欺诈和广告作弊等
点击劫持
拖拽劫持:
诱使用户从隐藏的不可见iframe中拖拽出攻击者希望得到的数据,然后放到攻击者能控制的另外一个页面中,从而窃取数据。
Javascript判断是否被内嵌( HTML5的sandbox属性或IE中iframe的security都可以限制frame内js执行)
if(top != self || top.location != self.location || top.location != location){
top.loction = self.location
}
添加X-FRAME-OPTIONS响应头;它有三个可选的值:
DENY 拒绝当前页面加载任何frame页面
SAMEORIGIN frame页面的地址只能为同源域名下的页面
ALLOW-FROM origin 定义允许frame加载的页面地址
攻击原理:针对以数据内容为核心资产的企业,通过爬虫技术爬取页面接口和数据
导致的后果:被竞争对手掌握数据情况,从而在竞争中处于劣势地位
数据脱敏(常见)
如果想看脱敏数据,需要更加严格校验和限制的接口区单独获取
font-face字体(常见)
重要的数据用图片代替
通过Canvas 的指纹过滤掉爬虫
攻击原理:使用恶意的 SQL 语法去影响数据库内容,从而访问、修改或删除数据
导致的后果:盗表,删表,篡改数据,伪造管理员身份
攻击原理:通过特殊的请求或大量的请求方式,使服务器不能及时完成全部请求;造成请求挤压,进而出现雪崩效应;
区别:DoS - 单挑 ;DDOS - 群殴
导致的后果:使网站无法被访问
攻击原理:在用户和服务器之间搭建媒介,使用户和服务器之间以为在互相通信,从而实现通信信息的窃取和更换;参考MDNopen in new window
导致的后果:网页被更改,拆入广告,浏览信息被监听
防御:全站HTTPS,建立安全通道
前端没有绝对的安全,而我们能做的只有削弱特定类型攻击,降低遭受攻击的可能性,增加攻击难度
web安全是前端领域绕不开的一个话题,许多程序猿只专注于业务实现,觉得攻击离自己很远,而安全相关的策略也只停留在面试层面。比较万幸的是我们最常使用的web服务器框架默认都会启用健壮而深思熟虑的措施来防范一些较常见的攻击!
对于一个没有考虑到安全问题的产品,很容易受到黑客的重点关注,从而造成严重损失!此文意在帮助前端人员认识前端安全,提高安全意识!
https://cloud.tencent.com/developer/article/1406118

XSS(Cross Site Scripting):跨站脚本攻击
攻击原理:通过破坏html/css/js的构造,来实现攻击,它不需要做任何的登录认证,通过合法的操作,向你的页面注入脚本;
导致的后果:
反射型(非持久型)&&DOM型
诱导用户点击带攻击的链接(可能是短链接),页面中包含获取链接参数并显示在页面的逻辑
攻击点包括所有可能运行JavaScript代码的地方:
html节点内容
通过.innerHTML、.outerHTML、document.write()将用户输入的信息直接插入到页面
html属性
href、src等html属性包含用户输入的代码, 比如包含javascript:可执行代码或者提前闭合属性,并在后面拼接js代码
js代码
代码中包含后台注入的变量或用户输入的内容
存储行(持久型):危害大、范围广
将攻击代码提交到数据库中,并在前端请求时返回。论坛、评论等是重灾区
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
来自于Unleashing an Ultimate XSS Polyglotopen in new window的一段用来检测HTML内容和属性、跳转链接、内联 JavaScript 字符串等多种上下文中的 XSS 漏洞的代码
防止攻击者提交恶意代码
对于明确的输入类型进行转码、过滤,但不要对不明确用途的输入进行转码,防止使用时出现乱码情况
// 转码
function escape(str) {
str = str.replace(/&/g, '&')
str = str.replace(/</g, '<')
str = str.replace(/>/g, '>')
str = str.replace(/"/g, '&quto;')
str = str.replace(/'/g, ''')
str = str.replace(/`/g, '`')
str = str.replace(/\//g, '/')
return str
}
//白名单过滤
const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1><script>alert("xss");</script>
输入内容长度控制
防止浏览器执行恶意代码
CSPopen in new window:查看兼容性open in new window
内容安全策略,最初的设计目的是减少XSS的攻击,后来的版本也可以防止其他形式的攻击,如点击劫持等;它的本质就是白名单制度,由浏览器进行拦截处理!
可以将相应的CSP政策放在Google 提供的 CSP Evaluatoropen in new window上检验
// 响应头
Content-Security-Policy:"default-src self; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * data:;";
// html -> head
<meta http-equiv="Content-Security-Policy" content="default-src self; script-src 'unsafe-inline' 'unsafe-eval'; img-src *;">
- CSP自诞生日开始就有很多安全人员在研究如何绕过CSP设置:文章open in new window
- CSP落地:针对已有项目,前期最好先用
Content-Security-Policy-Report-Only请求头,不阻塞资源加载,只对拦截进行上报,逐步增加调整适用于项目的规则后再上Content-Security-Policy
加深对XSS攻击的理解:谷歌 XSS 通关小游戏open in new window

CSRF(Cross-site request forgery):跨站请求伪造。
攻击原理:登陆网站A,诱导用户进入网站B,网址B向网站A发送跨域请求,利用用户存储在cookie的登陆凭证,绕过后台的登陆校验,进行非法操作的目的
导致的后果:在不知情的情况下,利用受害者登陆信息发起支付、自动评论、损坏网站声誉等攻击
GET类型的攻击:利用没有跨域限制的标签来实现攻击,比如img、script、link、iframe
<img src="http://test.bank.com/api/pay?money=100&card=12312312" >
POST类型的攻击:通常使用的是一个自动提交的表单
<form name="autoSubmit" action="http://test.bank.com/api/pay" method="POST">
<input type="text" name="card" value="11111">
<input type="text" name="money" value="100">
</form>
<script>document.autoSubmit.submit()</script>
可以发现攻击通常发生在第三方网站,自己的网站无法防止攻击发生,因此,防护的方式就需要依靠提高自己网站对CSRF的防护
根据三方网站发起攻击特点
根据攻击不会进入被攻击网站前端特点
https://juejin.cn/post/7357920285867343924?utm_source=gold_browser_extension#heading-1 https://www.bram.us/2018/02/21/css-keylogger-and-why-you-shouldnt-worry-about-it/ https://github.com/maxchehab/CSS-Keylogging

攻击原理:通过iframe设置透明或不透明的层来诱骗用户点击(拖拽)操作,而实际的操作的却是用户看不到的一个元素,从而达到在用户不知情的情况下实施攻击
导致的后果:钓鱼、欺诈和广告作弊等
点击劫持
拖拽劫持:
诱使用户从隐藏的不可见iframe中拖拽出攻击者希望得到的数据,然后放到攻击者能控制的另外一个页面中,从而窃取数据。
Javascript判断是否被内嵌( HTML5的sandbox属性或IE中iframe的security都可以限制frame内js执行)
if(top != self || top.location != self.location || top.location != location){
top.loction = self.location
}
添加X-FRAME-OPTIONS响应头;它有三个可选的值:
DENY 拒绝当前页面加载任何frame页面
SAMEORIGIN frame页面的地址只能为同源域名下的页面
ALLOW-FROM origin 定义允许frame加载的页面地址
攻击原理:针对以数据内容为核心资产的企业,通过爬虫技术爬取页面接口和数据
导致的后果:被竞争对手掌握数据情况,从而在竞争中处于劣势地位
数据脱敏(常见)
如果想看脱敏数据,需要更加严格校验和限制的接口区单独获取
font-face字体(常见)
重要的数据用图片代替
通过Canvas 的指纹过滤掉爬虫
攻击原理:使用恶意的 SQL 语法去影响数据库内容,从而访问、修改或删除数据
导致的后果:盗表,删表,篡改数据,伪造管理员身份
攻击原理:通过特殊的请求或大量的请求方式,使服务器不能及时完成全部请求;造成请求挤压,进而出现雪崩效应;
区别:DoS - 单挑 ;DDOS - 群殴
导致的后果:使网站无法被访问
攻击原理:在用户和服务器之间搭建媒介,使用户和服务器之间以为在互相通信,从而实现通信信息的窃取和更换;参考MDNopen in new window
导致的后果:网页被更改,拆入广告,浏览信息被监听
防御:全站HTTPS,建立安全通道
前端没有绝对的安全,而我们能做的只有削弱特定类型攻击,降低遭受攻击的可能性,增加攻击难度