OWASP API安全 Top 10 (1)

OWASP API 安全Top 10 目录:

  • API1:2019-失效的对象级别授权(本篇)
  • API2:2019-失效的用户身份验证
  • API3:2019-过度的数据暴露
  • API4:2019-资源缺乏和速率限制
  • API5:2019-失效的功能级授权
  • API6:2019-批量分配
  • API7:2019-安全配置错误
  • API8:2019-注入
  • API9:2019-资产管理不当
  • API10:2019-日志和监视不足

API1:2019-失效的对象级别授权

漏洞原理

这个漏洞和IDOR是类似的,就是权限有问题,用户访问了不该访问的资源,其实就是我们常说的越权。

比如修改请求中的对象ID,达到对没有授权的对象ID的访问。导致敏感数据的未授权访问,数据丢失,数据被篡改,账号被接管等问题。

这个漏洞非常的普遍,在前几年,几乎随便都能测到这种漏洞。服务器因为不会完整的跟踪用户的状态,只会通过解析对象ID来返回结果,如果不做授权就会直接返回数据。

对象级的授权主要是在代码层面上进行访问控制的一种机制,检验用户是否可以访问对象,出现这种漏洞主要是因为很多厂商都没做这一块。

例子:

Broken Object Level Authorization

当用户向API发出请求的时候,主要是为了访问对象。用户只能访问已经被授权的对象,这是正常的流程。当授权不当的时候,用户就可以访问不应该被允许的数据。

比如我们访问下面这个API,就可以访问到12345用户的消息记录

https://pxiaoer.blog/messages/12345

如果我们把12345改成12346,则变成另外一个用户。如果这样访问就可以得到消息,那就存在越权的漏洞。

还比如,在POST的请求中,有如下的JSON

{
    "userId": "12345678",
    "oldPassword": "My_0ld_Pa$$",
    "newPassword": "$uperS3CurE"
}

我们更改userId如果没有权限验证的话,就会把用户的密码修改成功。

攻击场景

场景1:

一个电商网站的商铺接口

/shops/{shopName}/revenue_data.json

可以通过替换 shopName 来访问其他商铺的数据。

场景2:

在一个可穿戴设备流量中的HTTP头部,存在一个自定义的请求头User-Id:54796

可以通过更改User-Id后面的值来修改其他用户的账号数据

攻击手段

主要是有两种类型的对象

  • 基于user ID
  • 基于对象ID

于user ID

比如像 https://google.com/get_users_search_history?userID=1234

如果能够遍历userID就可以得到其他人的数据

我们可以通过验证userid来防止遍历:

if($_GET['userID'] === object.ownerID){
   ShowData()
}else{
  echo "You are not allowed to view this data"
  wait(5s)
  Redirect(Homepage)
} 

但是不要错误的以这种逻辑来验证:



if(!$_GET['userID'] === object.ownerID){
  echo "You are not allowed to view this data"
  wait(5s)
  Redirect(Homepage)
}
ShowData() 

上面的代码主要是因为可以使用回退按钮,就可以让数据显示。

基于对象ID

对象ID也是一样的,主要是需要记住对对象ID 进行权限限制

比如:

GET product.php?id=12
POST product.php?id=12
DELETE product.php?id=12
OPTIONS

上面三个接口: 得到商品信息,更新商品详情和删除商品

在后面的开发中,又想添加一个功能,把商品信息通过CSV导入,那就需要一个接口

POST /import.php?   {1,"test",12} 

这个时候,攻击者就可以通过修改CSV导入的内容来重写商品信息

POST updateProduct.php?productID?id=1
if($_GET['productID'].owner === object.ownerID){
  UpdateData()
}else{
  echo "You are not allowed to view this data"
  wait(5s)
  Redirect(Homepage)
}

POST /import.php?
StartUpdateData()

还有一种场景就是有跨团队调用的这种函数很容易忘记实现权限验证

比如,上面的例子中添加一个函数,每10分钟更新一次价格,这里的更新价格的函数就可以替换对象ID

TimerForProducts(){
   wait(24H)
   UpdatePrices($_GET[UsersProducts[])
}

UpdatePrices(products[]){
   for each product in products{
      getPrice()
   }
}

GET /updatePrices?UsersProducts=1,2,3,4

上面的程序中,攻击者很容易就可以通过后台调用来更新价格

GET /updatePrices?UsersProducts=1,2,3,4,5,6,7,8,9,...

防御手段

  • 主要是用户授权机制上,用户策略和继承关系来实现一定的授权机制。
  • 在接收用户输入和访问数据库等函数中,通过授权机制来检查登录用户是否有权在该记录上执行所请求的操作。
  • 多测试授权机制
  • 使用auth token来代替userID来作为参数,比如JWT等
  • 使用GUIDS来作为ID,GUIDS是一串很长的随机数,这样可以避免猜出其他用户的认证信息
  • 使用一个认证的解决方案
  • API安全网关

真实案例

1.[Razer Pay] Broken Access Control at /v1/verifyPhone/ allows enumeration of usernames and ID information

链接:https://hackerone.com/reports/752443

雷蛇的账户,允许用户枚举账户查看其他账户的用户名和手机号。

2.Private list members disclosure via GraphQL

链接:https://hackerone.com/reports/885539

3.User sensitive information disclosure

链接:https://hackerone.com/reports/975047

4.Disclose Any Store products, Files, Purchase Orders Via Email through Shopify Stocky APP

链接:https://hackerone.com/reports/763994

5.IDOR on stocky application-Low Stock-Varient-Settings-Columns

链接:https://hackerone.com/reports/853130

6.IDOR on Apple via “X-Dsid” header allows attacker to retrieve name, credit card information, addresses, and various PII of any Apple users via DSID

链接:https://twitter.com/samwcyo/status/1350025970615529473

挖掘建议

自动挖掘

自动化工具确实不太好检测这一类的漏洞,不过还是有一些人在尝试。

I. 黑盒+自动化

主要分给两个关键部分

  • 流量采集
    • 服务器出口日志采集
  • 请求重放
    • 多个账号重放请求
    • 结果对比
    • 排除误报

优点:在理想情况下,可以通过很少的人力去覆盖大量应用

缺点:大量的误报,安全产品死于误报;线上真实流量重放效果最好,却容易造成故障

II. 黑盒+半自动化

像ZTO的authcheck、BurpSuit插件AuthMatrix等差不多,就是手工对比。

  • 流量采集
    • 浏览器被动代理或爬虫方式采集
  • 请求重放
    • 多个账号重放请求
    • 对response进行简化
  • 人工确认
    • 对简化后的response进行判断是否存在漏洞

优点:最后输出的漏洞结果准确度较高,适合针对单一系统进行安全测试

缺点:在面对大量应用及大量迭代新增API时,效率太低

III. 白盒+自动化

这种方式有两种思路,一种是发现存在越权风险的接口,一种是发现不存在越权风险的接口,原理是差不多的

  • 白盒扫描
    • 入参是否包含可越权(可遍历)的参数
    • 是否有从cookie或session中或获取用户标识
  • 风险确认
    • 是否包含authcheck(xxid, userid)的判断逻辑
    • 是否包含@authcheck的注解

优点:仿佛看到了可以批量发现越权风险的方法,对于一些简单的水平越权可以有效发现,而且一般一个系统的权限缺陷都是相似的,发现一个,发现一片

缺点:误报率太高,不能发现复杂的越权风险

IV. 白盒+半自动化

这种思路和上面提到的”黑盒+半自动化“的思路差不多

  • 白盒扫描
    • 扫描器应用的API list
    • 标明入参及用户标识、判断逻辑
  • 人工确认
    • 通过白盒扫描出来的入参、用户标识、判断逻辑来判断是否存在越权风险

优点:对一部分水平越权、未授权访问的风险可以有效发现

缺点:API数量一多就不灵光了,很难发现复杂的越权

手工挖掘

手工比较好检测,主要是找到这些userID和对象ID,而且他们可能出现的位置是在URL,请求主体或者HTTP 头中。

主要是分析返回的响应结果来检查是否有漏洞存在。

手工挖掘工具

  • Chrome 开发者工具
  • Burp Suite
  • Postman

参考资源:

API数据安全研究报告

看了一下中国信通院出的,API数据安全研究报告,有几个点还是可以说下的。

API安全风险分析

一. 外部威胁因素

  • API漏洞导致数据被非法获取
  • API成为外部网络攻击的重要目标
  • 网络爬虫通过API爬取大量数据
  • 合作第三方非常留存接口数据
  • API请求参数易被非常篡改

二.内部脆弱性因素

  • 身份认证机制
  • 访问授权机制
  • 数据脱敏策略
  • 返回数据筛选机制
  • 异常行为监测
  • 特权账号管理
  • 第三方管理

API安全系列——漏洞分析之Facebook OAuth框架漏洞

这个漏洞的公开链接为:https://www.amolbaikar.com/facebook-oauth-framework-vulnerability/

发布时间为2020年3月1日

OAuth基本的认证流程如下图:

OAuth 的流程是, 用户请求facebook资源给B,然后B发起许可,用户同意许可并请求facebook,facebook给了一个token给用户转交给了B,B再去利用这个token去facebook请求资源。 其实最重要的就是那个token。

参考链接:

  1. https://www.freebuf.com/vuls/234519.html
  2. https://wooyun.js.org/drops/OAuth%202.0%E5%AE%89%E5%85%A8%E6%A1%88%E4%BE%8B%E5%9B%9E%E9%A1%BE.html

API安全系列——Astra工具的使用

Astra是2018年黑帽大会上公布的一款工具,专门用于对REST API的渗透测试。

地址:https://github.com/flipkart-incubator/Astra

Astra竟然还是使用的Python2.7,那我就用docker来运行它。

首先,它依赖mango,先把mango跑起来。

$ docker pull mongo
$ docker run --name astra-mongo -d mongo

然后是GUI Astra

$ git clone https://github.com/flipkart-incubator/Astra.git
$ cd Astra
$ docker build -t astra .
$ docker run --rm -it --link astra-mongo:mongo -p 8094:8094 astra

浏览器打开 http://localhost:8094/

在URL中只能填入单个URL,效果如下

Astra 还是命令行模式,支持多个URL扫描,命令如下:

$ git clone -b docker-cli https://github.com/flipkart-incubator/Astra.git
$ cd Astra
$ docker build -t astra-cli .
$ docker run --rm -it --link astra-mongo:mongo astra-cli 

然后可以使用python astra.py 来使用

$ python astra.py --help

                      _
        /\       | |
       /  \   ___| |_ _ __ __ _
      / /\ \ / __| __| '__/ _` |
     / ____ \__ \ |_| | | (_| |
    /_/    \_\___/\__|_|  \__,_|



usage: astra.py [-h] [-c {Postman,Swagger}] [-n COLLECTION_NAME] [-u URL]
                [-headers HEADERS] [-method {GET,POST}] [-b BODY]
                [-l LOGINURL] [-H LOGINHEADERS] [-d LOGINDATA]

REST API Security testing Framework

optional arguments:
  -h, --help            show this help message and exit
  -c {Postman,Swagger}, --collection_type {Postman,Swagger}
                        Type of API collection
  -n COLLECTION_NAME, --collection_name COLLECTION_NAME
                        Type of API collection
  -u URL, --url URL     URL of target API
  -headers HEADERS, --headers HEADERS
                        Custom headers.Example: {"token" : "123"}
  -method {GET,POST}, --method {GET,POST}
                        HTTP request method
  -b BODY, --body BODY  Request body of API
  -l LOGINURL, --loginurl LOGINURL
                        URL of login API
  -H LOGINHEADERS, --loginheaders LOGINHEADERS
                        Headers should be in a dictionary format. Example:
                        {"accesstoken" : "axzvbqdadf"}
  -d LOGINDATA, --logindata LOGINDATA
                        login data of API