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