快轉到主要內容
  1. Posts/

基礎滲透 GraphQL 架構

·918 字·2 分鐘

在網頁滲透專案中,第一次遇到使用 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 呼叫時的流程如下圖

  1. Client HTTP Request 呼叫時,將想取得的欄位放入 POST 中

  2. HTTP Server 依據 Request 的請求,跟 GraphQL 的 schema 取得需要的欄位資訊

  3. GraphQL 的 schema 將需求資訊給 HTTP Server

  4. 由 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 執行變更操作,導致未經授權的存取。