
使用這些基本 REST API 最佳實踐構建出色的 API
Query: {
adminResolver: async (parent, args, context) => {
if(!context.user || !context.roles.includes("admin")) throw new Error("Permission denied!");
...
return data;
},
},
};
過去,開發人員會在前端生成 SQL 查詢,并將其發送到 API 以從 SQL 數據庫中獲取數據;因此,SQL 注入應運而生。攻擊者可以編寫 SQL 并將其發送到 API,API 會執行該查詢,而無需進一步詢問。
雖然沒有人阻止 GraphQL API 開發人員創建接受在服務器上盲目執行的 SQL 字符串的類型,但這種情況很少見。
但接受來自客戶端的數據始終存在風險。這就是為什么在獲取任何數據之前,所有輸入都應經過驗證和規范化。特別是自定義標量由于它們不進行默認驗證,因此很容易受到這種威脅。
GraphQL 為其 API 使用者提供了便捷的自省功能,允許 GraphQL 客戶端詢問 API 提供哪些類型的數據。這很棒,因為現在客戶端開發人員不必查看文檔,而是可以直接詢問 API 服務器有哪些數據可用。
但如果不嚴格控制,內省也可能被濫用。例如,當提供管理功能的 GraphQL 類型可以被普通用戶發現和使用時。
GraphQL API 創建者必須使用嚴格的授權方案進行自省,以使攻擊者更難找到 API 漏洞。如果外部開發人員不使用您的 API,在生產環境中禁用自省功能也是一個好主意。
例如,Apollo 服務器允許使用簡單的配置標志禁用自省:
const IS_PRODUCTION = process.env.ENVIRONMENT === "production";
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: !IS_PRODUCTION,
});
server.listen();
GraphQL 查詢為 API 消費者提供了很大的靈活性,只需一個請求就可以準確獲取他們想要的數據,但此功能也可能以多種方式被濫用。
惡意客戶端可能會出于各種原因創建非常深入、復雜或通常長時間運行的查詢。如果這些攻擊者發現導致大量計算的極端情況或利用N+1 查詢問題,它們會導致 API 超載并嚴重降低其他客戶端的性能。
這就是為什么 GraphQL API 應該將查詢執行時間限制在合理的最大值。更好的是,實現此目標的另一種方法是限制查詢深度或復雜性,從而使執行常見的 GraphQL DDoS 攻擊變得更加困難,這些攻擊往往使用遞歸和深度查詢來破壞服務。
如前所述,GraphQL API 不是數據存儲機制;這意味著它使用上游服務(如數據庫或其他 API)來獲取實際數據。這些服務也可能出現錯誤。如果您將上游服務的錯誤傳遞給客戶端,攻擊者可以利用它們來了解您的架構。
為了減輕這種威脅,您應該始終在將上游錯誤傳遞給客戶端之前對其進行處理;這樣,您可以隱藏獲取數據的服務,并禁止攻擊者利用這些服務可能存在的錯誤或安全漏洞。
我們來看下面的代碼示例:
const resolvers = {
Query: {
myResolver: async (parent, args, context) => {
try {
const data = await fetchFromRemoteDataSource();
return process(data);
} catch (upstreamError) {
const cleanError = analyzeUpstreamError(upstreamError);
throw cleanError;
}
},
},
};
解析器嘗試從遠程數據源獲取一些數據,但這可能會失敗。我們捕獲的錯誤來自遠程數據源,因此它可能包含有關數據源的信息。
我們需要分析錯誤并清除所有上游信息,然后再將其傳遞給客戶端。
GraphQL API 是改善前端團隊開發人員體驗的絕佳方式。它通過為客戶提供一種指定所需內容的方式來幫助優化數據獲取。但這是以 API 架構的復雜性增加為代價的,這增加了 API 的攻擊面。
隨著GDPR和加拿大注冊會計師協會法律規定罰款高達數百萬美元,API 創建者比以往任何時候都更需要保持常見的 API 威脅在開發 API 時要牢記這一點,并留意可能出現的 GraphQL 特定弱點。
原文地址:https://www.moesif.com/blog/technical/security/5-Security-Tips-for-Your-GraphQL-API/