前置知識

GraphQL查詢方式

GraphQL是一種用于API的查詢語言,首先我們就需要知道GraphQL有哪些查詢方式。

主要有:

其中最為常見的是Query、Mutation、Subscription這三種,Query用于向服務端查詢指定數據、Mutation用于在服務端修改或添加數據,具體可參考官方文檔進行了解:https://graphql.org/learn/

GraphQL內省查詢

簡單來說就是,GraphQL內查機制,通常是內部可用,通過內省的方法獲得相關信息,如對象定義、接口參數等信息。一般查詢前面帶有雙下劃線的就表示內省的一部分,比如:__Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive等,官方文檔:https://graphql.org/learn/introspection/

GraphQL API發現 

當我們在測試時,如何發現GraphQL API?下面介紹幾種有效的方法。


常見的GraphQL路徑判定

GraphQL API與Restful API不同,一般來說它的URL比較固定,這也是它的特性之一,從單個請求中獲取應用程序所需的所有數據。

常見的GraphQL路徑如下:

/graphql
/graphiql
/v1/graphql
/v2/graphql
/v3/graphql
/v1/graphiql
/v2/graphiql
/v3/graphiql
/api/graphql
/api/graphiql
/graphql/api
/graphql/console
/console
/playground
/gql
/query
/graphql-devtools
/graphql-explorer
/graphql-playground
/graphql.php
/index.php?graphql
......

通用查詢探測

由于GraphQL API中存在一個__typename 的保留字段,該字段會以字符串形式返回查詢對象的類型,所以我們可以向未知API發送query{__typename},如果響應中返回{“data”: {“__typename”: “query”}},那么就可以確定該API為GraphQL API。

內省查詢

向未知API發送__schema字段使用自省來發現架構信息,該字段在所有查詢的根類型上都可用。

query {__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}

可以查詢到所有類型、字段、參數以及參數類型。

改變請求方法/報錯信息判斷

利用不同的請求方法(GET、POST)發起請求也能夠進行GraphQL API的辨別,因為對于一些僅允許某種請求方法的GraphQL API而言,不同的請求方法返回的格式和內容也不同。除此之外,根據報錯信息可以判斷是否為GraphQL API,主要特征是Syntax Error: Expected Name, found。

GraphQL API攻擊面 


內省查詢攻擊

通過了解GraphQL的內省查詢機制,其實我們可以發現在相關系統沒修改默認配置的情況下,我們可以通過__schema 或者 __type 等來進行系統級別的查詢,以獲取服務器上定義的所有類型、字段、敏感信息等。通過內省查詢,我們獲取到系統所有相關字段及信息,如下圖:

然后利用voyager工具將查詢結果可視化。

獲取數據結構以便進一步利用。

拒絕服務

GraphQL支持請求批處理,并且會對請求一個一個處理,這就導致可以利用批量查詢來實施Dos攻擊。

示例:

請求body:
{"query":"query {\n systemUpdate\n}","variables":[]},
{"query": "query {\n systemUpdate\n}","variables":[]},
{"query":"query {\n systemUpdate\n}","variables":[]}

當查詢類型相互引用時,通過構建一個循環查詢,來實現Dos攻擊。

query { 
Pastes {
Owner {
Pastes {
Owner {
Pastes {
Owner
{
Pastes {
Owner {
Pastes {
Owner {
Pastes {
Owner {
name
}
}
}
} }
}
}
}
}
}
}
}
}

隨著查詢呈指數級增長,最終導致服務器崩潰。

由于GraphQL API不會對重讀字段進行去重處理,所以還可以通過查詢重復字段進行Dos攻擊。

query {
pastes {
owner {
pastes {
ipAddr # 1
ipAddr # 2
ipAddr # 3
ipAddr # 4
......
ipAddr # 1000
}
}
}
}

越權查詢/信息泄露

通過內審查詢獲取到相關信息后,可以進一步利用,GraphQL API作為單路由API接口在查詢過程中往往會忽略一些鑒權問題,這可能導致越權漏洞的出現,并且泄露敏感信息。

例如在查詢到存在id參數。

通過修改id參數進行水平越權,獲取想要的敏感信息。

命令執行

由于GraphQL API沒有充分驗證輸入或者沒有嚴格過濾,導致在一些查詢中可以通過鏈接的形式拼接 UNIX 命令,達到命令執行的目的。

或者是通過systemDiagnostics接受某些 UNIX 二進制文件作為調試目的的參數,例如 whoami、ps等,在獲取相關憑證或者權限之后,可以進行拼接來達到命令執行的目的。

SQL注入

GraphQL API同樣會可能存在SQL注入漏洞,可以對查詢結構體中的一些參數進行SQL注入嘗試。

這里對“test”參數進行SQL注入嘗試。

加上單引號后返回報錯信息。

后續直接利用sqlmap進行后續操作。

graphql注入

類似于SQL注入拼接字符串,在GraphQL API進行相關查詢時,可以通過拼接的方式進行注入來獲取數據或者改變查詢邏輯。

正常查詢:

mutation {
create(content: "test", id: 1) {
name
password
title
}
}

graphql注入:

mutation {
editPaste(content: "test", id: 1) {
name
title
}
changePassword(password: "admin123") {
name
password
title
}
}

XSS

GraphQL API同樣也會遭受xss攻擊,其實針對任何存在系統而言,如果沒有相應的防御手段,沒有對輸入性參數進行過濾都可能遭受一些輸入型漏洞攻擊。

攻擊載荷成功解析,此外也可以利用上傳功能上傳HTML腳本進行攻擊測試。

SSRF

如果在GraphQL相關查詢操作允許本地主機或其他服務器不限制輸入,就可能遭受服務端請求偽造攻擊

漏洞案例:

保護機制繞過

在GrapQL API中如果存在相關惡意輸入保護機制,可以利用修改請求頭參數進行繞過。

例如下面使用IDE時,進行命令執行時,存在保護機制。

發現Cookie中存在明顯的disable字段。

修改disable為enable。

成功繞過保護機制。

登陸爆破

GraphQL API通過可以實現弱密碼爆破來碰碰運氣,不過還得分無登陸次數限制和有登陸次數限制兩種情況。

如果無登陸次數的限制,直接可進行弱密碼爆破。

如果一些網站存在登陸次數的限制,比如下面在爆破過程中。

GraphQL對象不能夠包含多個同名的屬性,所以我們可以利用別名來實現多個同屬性的操作,這樣如果系統只限制了API請求速率,那么也可以通過別名查詢來實現登陸爆破。

JWT令牌偽造

可以通過相關工具獲取GraphQL API的數據結構,這里我們就發現了存在新建用戶的操作。

發現登陸操作。

利用新建用戶成功查詢到accessToken。

發現可以利用token進行管理員敏感信息查詢。

嘗試用剛才的token進行嘗試,發現還是新建用戶的信息。

偽造JWT,把新用戶的token解析后,修改為admin。

成功查詢到管理賬號密碼。

目錄穿越/任意文件寫入

在GraphQL API中相關文件上傳/下載操作也可能存在目錄穿越、任意文件讀取、任意文件寫入等漏洞。

例如通過目錄穿越成功任意文件寫入。

成功上傳至tmp目錄。

工具

除了傳統的滲透測試工具以外,使用GraphQL API的工具也變得十分重要。

文章轉自微信公眾號@sec0nd安全

上一篇:

10個人工智能驅動的API安全工具

下一篇:

WebHDFS Rest API 企業實戰:大佬手把手帶你堵住漏洞,企業實例解析
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費