0x00 起因
前几日在hackerone上挖掘某高赏金厂商,走了一遍业务点后,偶然发现http history里面有个graphql的接口
于是一场坐牢之旅开始了
0x01 前置知识与内省查询
不了解graphql的兄弟可以看看如下的图
通俗易懂地说:Graphql类似于restful的API 开源查询语言,其巧妙的新方法来改善应用程序中客户端和服务器之间的交互,为项目构建和后期维护提供了新思路
在实践经验中,发现国内用graphql技术的厂商并不是很多,大部分还是基于restful的,国外比较流行
在graphql中,是支持“内省查询”这种比较特殊的技术的
简单来说就是,GraphQL内置了类似于“swagger的”接口文档,你可以通过内省的方法获得这些信息,如graphql中对象定义、接口参数等信息。
当使用者不知道某个GraphQL接口中的类型哪些是可用的,可以通过__schema字段来向GraphQL查询哪些类型是可用的。
例如,您可以通过__schema通过此自省功能了解有关接口类型的更多信息。(下方图源于酒仙桥部队的一篇文章)
而内省查询通常是不应该对外能直接使用的
0x02 挖掘过程
有了一定的前置知识,我们来看这个graphql的点
笔者在抓到该厂商某个graphql的接口后,尝试使用_schema内省查询来获取接口的额外信息
POST /web-stories-api/graphql HTTP/1.1
Host: xxxxxxxxxx
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.78 Safari/537.36
Connection: close
Cache-Control: max-age=0
Content-Type: application/json
Content-Length: 1531
{"query":"query Query {\n __schema {\n queryType { name }\n mutationType { name }\n subscriptionType { name }\n types {\n ...FullType\n }\n directives {\n name\n description\n locations\n args {\n ...InputValue\n }\n }\n }\n }\n\n fragment FullType on __Type {\n kind\n name\n description\n fields(includeDeprecated: true) {\n name\n description\n args {\n ...InputValue\n }\n type {\n ...TypeRef\n }\n isDeprecated\n deprecationReason\n }\n inputFields {\n ...InputValue\n }\n interfaces {\n ...TypeRef\n }\n enumValues(includeDeprecated: true) {\n name\n description\n isDeprecated\n deprecationReason\n }\n possibleTypes {\n ...TypeRef\n }\n }\n\n fragment InputValue on __InputValue {\n name\n description\n type { ...TypeRef }\n defaultValue\n }\n\n fragment TypeRef on __Type {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n }\n }\n }\n }\n }\n }\n }\n }"}
结果非常nice,内省查询后目标返回了接口的详细信息
但是以上的数据看起来比较杂乱无章,决定使用内省查询的图形化的解析功能
https://apis.guru/graphql-voyager/ 这个site为内省查询的JSON response提供了不错的图形化解析
解析后结果如图(有些字段涉及厂商名称,打码了)
该graphql接口是基于某个获取“社交分享”的业务点的,最终我在图形化的解析结果中发现:某个查询对象中有一个并没有用到实际业务中的敏感参数“address”
看到这里,颅内高潮便起来了
直接把address参数加入query查询里,最终成功回显出来了众多“社交分享”中的address
但是很遗憾,大部分address都是null,或者最高精确度到“镇级行政区”的数据,没有详细到能出发表社交信息人的具体位置
但是还是决定试一试,向xx厂商安全团队报告了这个问题
厂商先后回复的意思大概是说,address等字段虽然在明面的业务请求上没展示,但是并不属于特别敏感的信息,对用户数据安全不会产生影响
尽管关闭这个graphql接口的内省查询会更安全,但是我们认为保留graphql内省查询这个feature会让菜鸡的安全研究人员(比如你)更容易找到api中的漏洞问题
所以我们暂时不会修改这个功能点,虽然我们很赞赏你花时间来提交我们赏金项目的问题
0x03 后言
看到这里,虽然有些失落,但是也无所谓,在每次漏洞挖掘与经验的学习的过程中中,有所习得(无论是知识还是经验)才是关键所在,而漏洞的最终效果和产出往往是天注定,我们强求不来
谁又知道下个”内省查询”不会产出boom级别的信息和漏洞呢
Hack to learn and learn to hack缺一不可