面试之-理解XSS、CSRF攻击原理与实践

一、XSS攻击

1、解释

xss是指攻击者在目标网站的网页上植入恶意代码,从而对正常用户进行劫持、获取用户隐私信息。

2、案例

假设有一个博客网站,允许用户输入评论,然后别的用户可以获取其他用户的评论。

前端页面:

javascript 复制代码
<!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>
go 复制代码
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)访问该评论,导致被攻击

3、防范

通过前面的介绍可以得知,XSS 攻击有两大要素:

  1. 攻击者提交恶意代码。

  2. 浏览器执行恶意代码。

所有可以从以下方面进行防范:

1、对于用户的输入参数和服务端输出到HTML的结果都进行检查,进行必要的转义;

2、改成纯前端渲染,把代码和数据分隔开。

​ 纯前端渲染的过程:

  1. 浏览器先加载一个静态 HTML,此 HTML 中不包含任何跟业务相关的数据。
  2. 然后浏览器执行 HTML 中的 JavaScript。
  3. JavaScript 通过 Ajax 加载业务数据,调用 DOM API 更新到页面上。

在纯前端渲染中,我们会明确的告诉浏览器:下面要设置的内容是文本(.innerText),还是属性(.setAttribute),还是样式(.style)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了。

但纯前端渲染还需注意避免 DOM 型 XSS 漏洞(例如 onload 事件和 href 中的 javascript:xxx 等,请参考下文"预防 DOM 型 XSS 攻击"部分)。

3、CSP

​ CSP的意义:防XSS等攻击的利器。CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。CSP 大大增强了网页的安全性。攻击者即使发现了漏洞,也没法注入脚本,除非还控制了一台列入了白名单的可信主机。

二、CSRF攻击

1、解释

CSRF(Cross-site request forgery)跨站请求伪造:攻击者通过邮件、广告链接诱导受害者进入第三方网站。在第三方网站中,攻击者向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证(cookie),一般网站都是直接根据cookie判断是否是合法登录,由于受害者的cookie已经被获取了,所以被攻击网站就会认为是合法用户。这样就完成了冒充用户,并且对被攻击的网站执行某项操作的目的。

一次典型的CSRF攻击有着如下的流程:

2、案例

首先我们写一个服务端响应:

go 复制代码
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",再访问的上述链接呢?

成功让值减一了,达到了攻击目的。

3、防范

  • CSRF(通常)发生在第三方域名。
  • CSRF攻击者不能获取到Cookie等信息,只是使用。

针对这两点,我们可以专门制定防护策略,如下:

  • 阻止不明外域的访问
  • 同源检测
  • Samesite Cookie
    • 提交时要求附加本域才能获取的信息
    • CSRF Token
  • 双重Cookie验证
同源检测

既然CSRF大多来自第三方网站,那么我们就直接禁止外域(或者不受信任的域名)对我们发起请求。

在HTTP协议中,每一个异步请求都会携带两个Header,用于标记来源域名:

  • Origin Header
  • Referer Header

这两个Header在浏览器发起请求时,大多数情况会自动带上,并且不能由前端自定义内容。 服务器可以通过解析这两个Header中的域名,确定请求的来源域。

虽然CSRF大多数情况下来自第三方域名,但并不能排除本域发起。如果攻击者有权限在本域发布评论(含链接、图片等,统称UGC),那么它可以直接在本域发起攻击,这种情况下同源策略无法达到防护的作用。

CSRF Token

前面讲到CSRF的另一个特征是,攻击者无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息。

而CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求和攻击的请求区分开,也可以防范CSRF的攻击。

原理

CSRF Token的防护策略分为三个步骤:

1.将CSRF Token输出到页面中

2.页面提交的请求携带这个Token

3.服务器验证Token是否正确

推荐阅读

1、原来阿里字节员工简历长这样

2、一条SQL差点引发离职

3、MySQL并发插入导致死锁


如果你也觉得我的分享有价值,记得点赞或者收藏哦!你的鼓励与支持,会让我更有动力写出更好的文章哦!

相关推荐
NAGNIP2 小时前
万字长文!回归模型最全讲解!
算法·面试
qq_318121593 小时前
互联网大厂Java面试故事:从Spring Boot到微服务架构的技术挑战与解答
java·spring boot·redis·spring cloud·微服务·面试·内容社区
且去填词4 小时前
Go 语言的“反叛”——为什么少即是多?
开发语言·后端·面试·go
青莲8437 小时前
RecyclerView 完全指南
android·前端·面试
青莲8437 小时前
Android WebView 混合开发完整指南
android·前端·面试
37手游后端团队10 小时前
gorm回读机制溯源
后端·面试·github
C雨后彩虹10 小时前
竖直四子棋
java·数据结构·算法·华为·面试
CC码码11 小时前
不修改DOM的高亮黑科技,你可能还不知道
前端·javascript·面试
indexsunny12 小时前
互联网大厂Java面试实战:微服务、Spring Boot与Kafka在电商场景中的应用
java·spring boot·微服务·面试·kafka·电商
自燃人~14 小时前
实战都通用的 Watchdog 原理说明
redis·面试