0x01
我在某次授权渗透时候碰到的场景:
渗透对象:
某电商 APP
目标缺陷:
API 设计不合理导致可泄露业务相关敏感信息
测试过程:
APP 含有购买功能,购买后会为订单生成订单号,此处订单号并不连续且为纯数字。为了进行越权测试,我注册了两个账户,分别进行一次购买行为。测试时我用 Burp 截取查看订单功能的数据包,并修改 URL 中的订单号为任意数字,向服务端再次提交请求,经过多次测试,发现服务端的返回请求状态码不是 403
就是 404
,基本可以确定此处不存在订单越权查看问题,但是根据服务端返回的状态码,不难推测出如下结论:
404 即该订单号对应的订单不存在
403 即该订单存在,但不允许我查看
0x02
那么可以怎么利用呢?订单属于商业敏感数据,APP 开发者当然不愿意自己的实际订单数据被用户或竞争对手拿到,在这里我可以根据遍历订单编号得到的服务端返回状态码(403
即订单存在)确定该 APP 的实际订单量。
类似场景还有,当获取用户个人主页时候,Restful 接口类似如下:
GET /users/123/profile HTTP/1.1
Host: target.com
修改 123
为其他数字,根据服务端返回状态码是否为 403
即可判断对应用户是否存在,在确定注册用户 id 递增的情况下,那么可以在月初注册一个账户拿到用户 id,记为 num1
,月末注册另一账户并拿到用户 id,记为 num2
,再遍历下刚刚的接口,就能筛选出 num1
、num2
之间的用户数量了,也即为一个月的新增用户数。
对创业公司来说,倘若投资人以某种渠道拿到了你们产品的真实注册用户数和订单量,你觉得他还会在乎你 PPT 上的内容吗?当然,这有点夸张了XD。
0x03
在我看来,当一个用户访问的资源不属于自己时,服务端返回 403
和 404
都是可以的,403
指 Forbidden,禁止用户访问不属于自己的资源,404
指 Not Found,用户不能看到不属于自己的资源,也能解释通。另外,也有服务端会返回 401
,401
指 Unauthorized,用户未授权访问不属于自己的资源,依然合理。
那到底该用哪一个呢?去翻了下 RFC2616
,对 403
状态码的解释里有这么一句:
If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
大概意思就是,只要服务端不想暴露信息给客户端,接口都统一返回 404
,完整部分可以看下图:
针对上面我碰到的场景来说,总结一句话就是
未授权用户访问有效资源时,服务端统一返回 404 更安全