xss是指攻击者在目标网站的网页上植入恶意代码,从而对正常用户进行劫持、获取用户隐私信息。
假设有一个博客网站,允许用户输入评论,然后别的用户可以获取其他用户的评论。
前端页面:
<!DOCTYPE html>
<html>
<head>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>function addComment() {
var kkk = $("#add").val() $.ajax({
url: "http://localhost:8081/add",
type: 'post',
dataType: 'text',
data: kkk,
success: function() {
alert("提交成功")
},
error: function(msg) {
alert("error:" + msg);
}
})
}</script>
</head>
<body>
<h1>xss:</h1>
<div>
<input type="text" id="add" placeholder="输入评论">
<button type="button" onclick="addComment()">提交</button></div>
</body>
</html>
func main() {
//简单起见,充当数据库
var comment string
http.HandleFunc("/get", func(writer http.ResponseWriter, request *http.Request) {
header := writer.Header()
header.Add("Content-Type","text/html; charset=UTF-8")
header.Add("Access-Control-Allow-Origin","*")
header.Add("Access-Control-Allow-Methods","POST,GET")
writer.WriteHeader(http.StatusOK)
_, _ = writer.Write([]byte(comment))
})
http.HandleFunc("/add", func(writer http.ResponseWriter, request *http.Request) {
s,_ := ioutil.ReadAll(request.Body)
comment = string(s)
header := writer.Header()
header.Add("Content-Type","text/html; charset=UTF-8")
header.Add("Access-Control-Allow-Origin","*")
header.Add("Access-Control-Allow-Methods","POST,GET")
writer.WriteHeader(http.StatusOK)
})
http.ListenAndServe(":8081",nil)
}
攻击者评论时,输入以下评论内容:
然后一个正常用户通过url(http://localhost:8081/get)访问该评论,导致被攻击
通过前面的介绍可以得知,XSS 攻击有两大要素:
攻击者提交恶意代码。
浏览器执行恶意代码。
所有可以从以下方面进行防范:
1、对于用户的输入参数和服务端输出到HTML的结果都进行检查,进行必要的转义;
2、改成纯前端渲染,把代码和数据分隔开。
纯前端渲染的过程:
- 浏览器先加载一个静态 HTML,此 HTML 中不包含任何跟业务相关的数据。
- 然后浏览器执行 HTML 中的 JavaScript。
- JavaScript 通过 Ajax 加载业务数据,调用 DOM API 更新到页面上。
在纯前端渲染中,我们会明确的告诉浏览器:下面要设置的内容是文本(
.innerText
),还是属性(.setAttribute
),还是样式(.style
)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了。但纯前端渲染还需注意避免 DOM 型 XSS 漏洞(例如
onload
事件和href
中的javascript:xxx
等,请参考下文”预防 DOM 型 XSS 攻击“部分)。
3、CSP
CSP的意义:防XSS等攻击的利器。CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。CSP 大大增强了网页的安全性。攻击者即使发现了漏洞,也没法注入脚本,除非还控制了一台列入了白名单的可信主机。
CSRF(Cross-site request forgery)跨站请求伪造:攻击者通过邮件、广告链接诱导受害者进入第三方网站。在第三方网站中,攻击者向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证(cookie),一般网站都是直接根据cookie判断是否是合法登录,由于受害者的cookie已经被获取了,所以被攻击网站就会认为是合法用户。这样就完成了冒充用户,并且对被攻击的网站执行某项操作的目的。
一次典型的CSRF攻击有着如下的流程:
首先我们写一个服务端响应:
func main() {
var num = 10
http.HandleFunc("/reduce", func(writer http.ResponseWriter, request *http.Request) {
//验证cookie,成功num--
cookie,_ := request.Cookie("id")
if nil == cookie{
writer.WriteHeader(http.StatusOK)
fmt.Fprint(writer,"cookie is nil")
} else if cookie.Value == "hahaha"{
num--
writer.WriteHeader(http.StatusOK)
fmt.Fprint(writer,num)
}
})
// 这里假设用户是登录成功了,进入页面后,服务端种了一个cookie
http.HandleFunc("/view", func(writer http.ResponseWriter, request *http.Request) {
http.SetCookie(writer,&http.Cookie{
Name: "id",
Value: "hahaha",
})
writer.WriteHeader(http.StatusOK)
fmt.Fprint(writer,num)
})
http.ListenAndServe(":8081",nil)
}
第一步:
我们将如下链接="http://localhost:8081/reduce"通过邮件发送给被攻击用户,假设用户点击了,结果将如下:
请求失败了,然后假设用户先访问了链接=“http://localhost:8081/view”,再访问的上述链接呢?
成功让值减一了,达到了攻击目的。
- CSRF(通常)发生在第三方域名。
- CSRF攻击者不能获取到Cookie等信息,只是使用。
针对这两点,我们可以专门制定防护策略,如下:
- 阻止不明外域的访问
- 同源检测
- Samesite Cookie
- 提交时要求附加本域才能获取的信息
- CSRF Token
- 双重Cookie验证
既然CSRF大多来自第三方网站,那么我们就直接禁止外域(或者不受信任的域名)对我们发起请求。
在HTTP协议中,每一个异步请求都会携带两个Header,用于标记来源域名:
这两个Header在浏览器发起请求时,大多数情况会自动带上,并且不能由前端自定义内容。 服务器可以通过解析这两个Header中的域名,确定请求的来源域。
虽然CSRF大多数情况下来自第三方域名,但并不能排除本域发起。如果攻击者有权限在本域发布评论(含链接、图片等,统称UGC),那么它可以直接在本域发起攻击,这种情况下同源策略无法达到防护的作用。
前面讲到CSRF的另一个特征是,攻击者无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息。
而CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求和攻击的请求区分开,也可以防范CSRF的攻击。
CSRF Token的防护策略分为三个步骤:
1.将CSRF Token输出到页面中
2.页面提交的请求携带这个Token
3.服务器验证Token是否正确
1、原来阿里字节员工简历长这样
2、一条SQL差点引发离职
3、MySQL并发插入导致死锁
如果你也觉得我的分享有价值,记得点赞或者收藏哦!你的鼓励与支持,会让我更有动力写出更好的文章哦!