在網頁滲透專案中,第一次遇到使用 GraphQL API 的網站,了解了 GraphQL 的原理與攻擊手法後,發現客戶未關閉 Introspection Query 功能,讓我能夠列舉並獲得整個 schema 資訊。由於客戶在權限上有進行設定,本次滲透測試僅取得 schema 資訊與測試 DoS 攻擊。本文記錄了 GraphQL 的基本介紹與列舉的方法。
GraphQL:新世代開源的 API 資料查詢操作語言#
GraphQL 是一個 API 的查詢語言,基本元件與簡介如下圖

Schema:描述整個資料框架與關係的圖,如上圖
Directive:以@作標記,於Schema中做客製化架構
Operation Type
Query:查詢操作
Mutation:變更操作
Argument
Input Type:將輸入的值傳給 Mutation 進行處理
Object Type:由Field組成,定義物件資料結構。Object Field:物件的欄位,用來篩選要處理的資料
Variable Types
Scalar Type:ID, String, Int, Float, Boolean 等。
Enum Type:自定義的變數型態,預先設定好變數值放入集合中,在Field使用時只能選擇集合中的值,範例如下
enum ROLES{
EDITOR
ADMIN
}
type user{
role: ROLES
}API 呼叫時的流程如下圖

Client HTTP Request 呼叫時,將想取得的欄位放入 POST 中
HTTP Server 依據 Request 的請求,跟 GraphQL 的 schema 取得需要的欄位資訊
GraphQL 的 schema 將需求資訊給 HTTP Server
由 HTTP Server 回應內容給 Client
GraphQL Introspection Query 功能開啟,導致框架可被列舉而造成資訊外洩#
Introspection Query 功能開啟,可以列舉以下內容
列舉所有類型名稱#
POST 中輸入以下字串,可以列舉 schema 中所有 name 的值,而造成所類型的名稱洩漏
{"query":"query { __schema { types { name fields { name } } } }"}列舉所有類型參數資訊#
POST 中輸入以下字串,可以列舉schema中所有name、description、type中的值
{"query":"query {__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}"}列舉schema架構#
POST 中輸入以下字串,可以列舉schema的架構
{"query":"query IntrospectionQuery { __schema { queryType { name } mutationType { name } subscriptionType { name } types { ...FullType } directives { name description args { ...InputValue } } } } fragment FullType on __Type { kind name description fields(includeDeprecated: true) { name description args { ...InputValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields { ...InputValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name description isDeprecated deprecationReason } possibleTypes { ...TypeRef } } fragment InputValue on __InputValue { name description type { ...TypeRef } defaultValue } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name } } } }"}總結#
由於 GraphQL 是一種可由 Client 端控制獲取資訊項目的 API 查詢語言,Client 端可以在 POST 內容中嘗試許多 GraphQL 語法。因此建議程式開發人員在正式環境關閉 Introspection Query 功能,若開發與測試需要使用該功能,僅在開發和測試系統上開啟即可。正式環境開啟此功能會使攻擊者可以輕易了解 GraphQL 架構,並且如果權限設定不當,攻擊者可利用 Mutation 執行變更操作,導致未經授權的存取。