1. 程式人生 > >管理API訪問令牌的最佳安全實踐

管理API訪問令牌的最佳安全實踐

【51CTO.com快譯】如今,無論是基於Web的應用、還是本地原生的各種程式,都需要通過後端的API來實現資源的訪問保護。要想得到API的授權,各種訪問請求就必須包含相應的訪問令牌或金鑰。本文將向API提供者和應用程式開發人員重點介紹,我們在管理訪問令牌中的各種最佳安全實踐。

管理API訪問令牌

一、安全的第一原則

在我們處置安全性時,首先要考慮的一條原則是:不可相信任何人。如果您是一名API提供者,您不能保證正在呼叫API的應用程式就是您所預期的那個,您無法確信收到的令牌沒有被盜,或者客戶端和伺服器之間的通訊沒有被截獲。特別是在客戶端,您無法確認應用程式沒有被反編譯過(而且已暴露了內嵌在應用程式之中的密碼)。當然,您也無法確定應用程式的儲存不會受到跨站指令碼式攻擊(詳見https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)),更無法保證您的使用者沒有在被欺騙的狀態下進行偽造請求的提交(詳見https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF))。可見,您必須採取適當的措施,來安全地獲取、儲存和管理那些呼叫後端API所需的安全令牌。

另外,您也許會認為:只要不被公開發布出去,自己的API就是安全的。您甚至還可能認為:由於API僅被自己的企業應用程式所用到,它們理所當然是私有的。可殊不知,如果它們可以在某個移動應用中被呼叫,那麼它們就置於了公網之上。也就是說,任何暴露在企業網路外部的API,都應被視為公開的(詳見

https://www.42crunch.com/a10-owasp/)。

二、獲取令牌的API金鑰

在使用API​​時,我們通常有兩種選擇:一種是將一段靜態資訊與API呼叫同時進行傳遞;另一種是在呼叫API之前,動態地獲取一段資訊。這段資訊通常被稱為訪問令牌或API金鑰。由於一些歷史遺留的問題,BasicAuth(譯者注:BasicAuth認證方式是在每次請求API時,僅提供使用者的username和password)仍在被某些API所使用著,但實際上,它已經不再是主流的認證解決方案了。

因此,在設計API的安全性方面,您必須謹慎地考慮到API使用者將如何去訪問它。而在考慮所採用的安全措施時,您需要全面地分析各種風險因素。顯然,我們對於諮詢天氣資料的API、與銀行支付型別的API的保護,會採用截然不同控制措施。

雖然API​​金鑰能夠被開發人員輕鬆地實現和使用,但它的安全級別不及於使用訪問令牌,通過雙因素身份驗證,來正確地識別出客戶端應用身份的方式。此外,API金鑰並不攜帶任何有關使用者的資訊,因此它不能被後端級別(backend level)用來決定API使用者可以進行哪些呼叫操作。再者,除非API提供者主動撤銷,否則API金鑰永遠不會過期。

針對上述缺點,OAuth應運而生,其特點如下:

訪問資源的應用程式是已知的(用到了客戶端應用程式的信任憑據)。
API提供者可以通過定義範圍,來限制對某些操作的訪問(您可以GET到某個目錄條目,但是就算使用的是有效的令牌,您仍然無法PUT新的目錄條目)。
令牌具有有限的生命週期。
三、讓我們從一些術語開始

OAuth所用到的術語有時會讓人感到費解,讓我們通過下面的表格,來了解一些與開發有關的重點術語。

四、Opaque與JWT

由於OAuth並不限制使用訪問令牌的格式,因此按照OAuth伺服器的實現規則,訪問令牌既可以是Opaque(通常是一條不帶有任何有用資訊的長字串),也可以是一種JSON Web令牌(JWT)。

JWT的優勢在於它能夠包含各種宣告、或是有關使用者的資訊,而後端服務則可以籍此來進行各種業務邏輯的決策。

五、學習“OAuth舞蹈”

OAuth的授權型別決定了客戶端將如何獲取令牌。這在我們自己團隊內部,常被戲稱為“OAuth舞蹈”。因為雖然在OAuth世界中,有著很多種“跳舞形式”,但是有一種您必須記住,那就是:授權程式碼。雖說在某些情況下,其他授權型別可能也非常實用,但授權程式碼型別則是包括Web應用、原生應用、和移動應用在內的所有應用程式,獲取訪問令牌的推薦方法(詳見

http://www.pingidentity.com/en/company/blog/posts/2018/securely-using-oidc-authorization-code-flow-public-client-single-page-apps.html)。

特別對於公共客戶端和移動應用而言,我們建議採取額外的安全措施,來防止授權程式碼被盜。此類安全層往往被稱為“程式碼交換證據金鑰”(Proof Key for Code Exchange,PKCE)標準。您可以通過連結:https://tools.ietf.org/html/rfc7636,瞭解更多有關PKCE,以及如何使用它的資訊。如果您是API提供者,請確保自己的OAuth伺服器能夠支援此選項。

同時,您應該特別注意資源所有者的密碼授權。雖然它實現起來最為簡單,但是由於其核心要求是在客戶端與伺服器間建立信任關係,因此您可能永遠也用不到它。

六、令牌管理的建議

  1. 注意OAuth應用的憑據洩漏

您會把應用程式的程式碼儲存在GitHub中嗎?您的OAuth應用憑據是否也會儲存在那兒,特別是客戶端的金鑰?可您知道嗎?這已經成為了當今信任憑據洩密的頭號來源。只要這些憑據被盜,任何人都可以偽裝成您的身份,發起中間人攻擊。因此,如果您一旦發現憑據可能已被洩露,那就請立即重新生成新的憑據。

此外,請永遠不要將客戶端的密碼放置在分散式程式碼之中,例如:通過應用軟體商店、或客戶端JavaScript下載的各類應用裡。

  1. 不要在應用程式中對令牌進行硬編碼

千萬不要為了圖省事,而簡化獲取令牌的程式碼,並將其長時間儲存在自己的應用程式之中。

  1. 像處置密碼一樣去處置令牌

由於任何掌握了令牌和API金鑰的人都能訪問到對應的資源。因此,我們需要像處置各種密碼那樣,去認真地處理和儲存各種令牌。

  1. OAuth並非是身份驗證協議

OAuth處理的是對資源訪問許可權的委派,因此它並非是一種身份驗證協議(儘管名稱很像)。我們可以將令牌看作酒店房間的鑰匙。您需要讓自己的身份得以驗證,方可獲得酒店鑰匙。但是,一旦您手中已有了鑰匙,它就不能再去驗證您是誰了。最近發生的一些使用者資訊洩露事件證明了,API提供者不可單一地將是否持有令牌作為身份驗證的依據。

另外,我建議您也參考一下OpenID Connect(OIDC,詳見https://www.oauth.com/oauth2-servers/openid-connect/)。不過,它只是一種補充性的規範,而並非是想在OAuth之上實現身份驗證的功能。OIDC允許使用者與應用程式共享其配置檔案裡的某些資訊,但並不是他們的信任憑據。

  1. 注意您在JWT中儲存的內容和誰有許可權訪問

JWT能夠以各種宣告的形式儲存大量的資訊,如果這些資訊被捕獲,攻擊者就能夠輕鬆地解析出具體的內容(除非它們被加密了)。因此,如果您想使用JWT向後端服務傳遞有用的資訊,那麼您可以採用如下的實現方法:

在客戶端和後端之間,僅使用Opaque字串、或是基本的JWT。
在後端,驗證某個請求、並注入一個新的JWT,它的有效負載中可包含一個能夠被下游用到的宣告。許多API安全閘道器都能以“開箱即用”的方式提供該功能。
如果想在整個流程中使用相同的令牌,並且讓該令牌攜帶一些敏感的資訊,那麼請您務必加密該令牌的有效負載。也就是說,請永遠不要使用JWT來攜帶使用者的信任憑據,例如:密碼!

  1. 徹底驗證JWT

當您在伺服器端收到JWT時,請務必徹底驗證其內容。需要特別注意的是:您應該直接拒絕任何不符合預期的簽名演算法、使用了弱簽名演算法、和使用了弱非對稱/對稱金鑰進行簽名的JWT。此外,您必須驗證所有的宣告、到期日期、釋出者和受用者。

在市面上,有些庫和工具可以直接為您執行該操作、有些則需要您事先進行適當的配置、而另一些可能只能做到部分檢查。因此,具體該使用哪一種方式,還取決於您所使用到的庫。

  1. 不要將令牌儲存在本地,請使用安全的Cookie

任何在瀏覽器上的本地儲存、和會話儲存,都有可能被JavaScript所讀取到。可見,用此方式來儲存令牌之類的敏感資訊是極不安全的。因此,您可以使用安全的Cookie、帶httpOnly的標識、以及CSRF等措施,來防止令牌被盜。

  1. 始終通過HTTPS和請求正文(Request Body)的方式傳輸令牌

通過這種方法,您可以限制令牌在傳輸過程中被捕獲,或是被寫到代理日誌、以及伺服器日誌之中的風險。您還應該確保只使用TLS的1.2/1.3版本,以及在頒發和驗證令牌的各個環境中,使用最安全的密碼套件。

  1. 使用專用的瀏覽器檢視來請求資訊

許多應用程式都用到了嵌入式的使用者代理,但是,由於它遮蔽了使用者去驗證與之通訊的網站真偽,因此,我們實際上應當避免使用這樣的代理。此外,應用程式應當能夠完全掌握使用者所輸入的憑據。正如那些OAuth原生應用所採用的最佳做法那樣,一些API提供者會採取強安全措施,來應對此類問題。

七、結論

訪問令牌是如今各種應用程式的實現基礎,因此我們在處置的時候一定要倍加小心。如果您是一名後端開發者,您必須確保提供適當的授權型別,以獲取訪問令牌;同時還應該支援移動應用的PKCE;以及對JWT進行全面驗證。而如果您是一位前端開發者,則必須能夠管控JWT的儲存、並保護應用的各種信任憑據。

參考

PKCE(https://tools.ietf.org/html/rfc7636)
JWT的驗證實踐(https://tools.ietf.org/html/draft-ietf-oauth-jwt-bcp-03)
原生應用程式的最佳實踐OAuth(https://tls.mbed.org/)
原文標題:Security Best Practices for Managing API Access Tokens,作者:Isabelle Mauny