轉(zhuǎn)載鏈接:blog.nsfocus.net/rest-api-design-safety/
REST API 安全設(shè)計(jì)指南。REST的全稱是REpresentational State Transfer领炫,它利用傳統(tǒng)Web特點(diǎn)呵曹,提出提出一個(gè)既適于客戶端應(yīng)用又適于服務(wù)端的應(yīng)用的、統(tǒng)一架構(gòu)岛抄,極大程度上統(tǒng)一及簡(jiǎn)化了網(wǎng)站架構(gòu)設(shè)計(jì)。
目前在三種主流的Web服務(wù)實(shí)現(xiàn)方案中,REST模式服務(wù)相比復(fù)雜的SOAP和XML-RPC對(duì)比來(lái)講平斩,更加簡(jiǎn)潔,越來(lái)越多的web服務(wù)開(kāi)始使用REST設(shè)計(jì)并實(shí)現(xiàn)咽块。但其缺少安全特性绘面,《REST API 安全設(shè)計(jì)指南》就是一個(gè)REST API安全設(shè)計(jì)的指南,權(quán)當(dāng)拋磚引玉侈沪,推薦網(wǎng)站后臺(tái)設(shè)計(jì)及網(wǎng)站架構(gòu)師們閱讀揭璃。
1,REST API 簡(jiǎn)介
REST的全稱是REpresentational State Transfer亭罪,表示表述性無(wú)狀態(tài)傳輸瘦馍,無(wú)需session,所以每次請(qǐng)求都得帶上身份認(rèn)證信息应役。rest是基于http協(xié)議的情组,也是無(wú)狀態(tài)的。只是一種架構(gòu)方式箩祥,所以它的安全特性都需我們自己實(shí)現(xiàn)院崇,沒(méi)有現(xiàn)成的。建議所有的請(qǐng)求都通過(guò)https協(xié)議發(fā)送袍祖。RESTful web services 概念的核心就是“資源”底瓣。 資源可以用 URI 來(lái)表示〗堵客戶端使用 HTTP 協(xié)議定義的方法來(lái)發(fā)送請(qǐng)求到這些 URIs捐凭,當(dāng)然可能會(huì)導(dǎo)致這些被訪問(wèn)的”資源“狀態(tài)的改變拨扶。HTTP請(qǐng)求對(duì)應(yīng)關(guān)系如下:
對(duì)于請(qǐng)求的數(shù)據(jù)一般用json或者xml形式來(lái)表示,推薦使用json茁肠。
2屈雄,身份認(rèn)證
身份認(rèn)證包含很多種,有HTTP Basic官套,HTTP Digest酒奶,API KEY,Oauth奶赔,JWK等方式惋嚎,下面簡(jiǎn)單講解下:
2.1 HTTP Basic
REST由于是無(wú)狀態(tài)的傳輸,所以每一次請(qǐng)求都得帶上身份認(rèn)證信息站刑,身份認(rèn)證的方式另伍,身份認(rèn)證的方式有很多種,第一種便是http basic绞旅,這種方式在客戶端要求簡(jiǎn)單摆尝,在服務(wù)端實(shí)現(xiàn)也非常簡(jiǎn)單,只需簡(jiǎn)單配置apache等web服務(wù)器即可實(shí)現(xiàn)因悲,所以對(duì)于簡(jiǎn)單的服務(wù)來(lái)說(shuō)還是挺方便的堕汞。但是這種方式安全性較低,就是簡(jiǎn)單的將用戶名和密碼base64編碼放到header中晃琳。
正是因?yàn)槭呛?jiǎn)單的base64編碼存儲(chǔ)讯检,切記切記在這種方式下一定得注意使用ssl,不然就是裸奔了卫旱。 在某些產(chǎn)品中也是基于這種類似方式人灼,只是沒(méi)有使用apache的basic機(jī)制,而是自己寫(xiě)了認(rèn)證框架顾翼,原理還是一樣的投放,在一次請(qǐng)求中base64解碼Authorization字段,再和認(rèn)證信息做校驗(yàn)适贸。很顯然這種方式有問(wèn)題灸芳,認(rèn)證信息相當(dāng)于明文傳輸,另外也沒(méi)有防暴力破解功能取逾。
2.2 API KEY
API Key就是經(jīng)過(guò)用戶身份認(rèn)證之后服務(wù)端給客戶端分配一個(gè)API Key耗绿,類似:http://example.com/api?key=dfkaj134,一般的處理流程如下: 一個(gè)簡(jiǎn)單的設(shè)計(jì)示例如下: client端:
server端:
client端向服務(wù)端注冊(cè),服務(wù)端給客戶端發(fā)送響應(yīng)的api_key以及security_key砾隅,注意保存不要泄露,然后客戶端根據(jù)api_key,secrity_key,timestrap,rest_uri采用hmacsha256算法得到一個(gè)hash值sign债蜜,構(gòu)造途中的url發(fā)送給服務(wù)端晴埂。 服務(wù)端收到該請(qǐng)求后究反,首先驗(yàn)證api_key,是否存在,存在則獲取該api_key的security_key儒洛,接著驗(yàn)證timestrap是否超過(guò)時(shí)間限制精耐,可依據(jù)系統(tǒng)成而定,這樣就防止了部分重放攻擊琅锻,途中的rest_api是從url獲取的為/rest/v1/interface/eth0,最后計(jì)算sign值卦停,完之后和url中的sign值做校驗(yàn)。這樣的設(shè)計(jì)就防止了數(shù)據(jù)被篡改恼蓬。 通過(guò)這種API Key的設(shè)計(jì)方式加了時(shí)間戳防止了部分重放惊完,加了校驗(yàn),防止了數(shù)據(jù)被篡改处硬,同時(shí)避免了傳輸用戶名和密碼小槐,當(dāng)然了也會(huì)有一定的開(kāi)銷。
2.3 Oauth1.0a或者Oauth2
OAuth協(xié)議適用于為外部應(yīng)用授權(quán)訪問(wèn)本站資源的情況荷辕。其中的加密機(jī)制與HTTP Digest身份認(rèn)證相比凿跳,安全性更高。使用和配置都比較復(fù)雜疮方,這里就不涉及了控嗜。
2.4 JWT
JWT 是JSON Web Token,用于發(fā)送可通過(guò)數(shù)字簽名和認(rèn)證的東西骡显,它包含一個(gè)緊湊的躬审,URL安全的JSON對(duì)象,服務(wù)端可通過(guò)解析該值來(lái)驗(yàn)證是否有操作權(quán)限蟆盐,是否過(guò)期等安全性檢查承边。由于其緊湊的特點(diǎn),可放在url中或者 HTTP Authorization頭中石挂,具體的算法就如下圖
3 授權(quán)
身份認(rèn)證之后就是授權(quán)博助,根據(jù)不同的身份,授予不同的訪問(wèn)權(quán)限痹愚。比如admin用戶富岳,普通用戶,auditor用戶都是不同的身份拯腮。簡(jiǎn)單的示例:
上述是垂直權(quán)限的處理窖式,如果遇到了平行權(quán)限的問(wèn)題,如用戶A獲取用戶B的身份信息或者更改其他用戶信息动壤,對(duì)于這些敏感數(shù)據(jù)接口都需要加上對(duì)用戶的判斷萝喘,這一步一般都在具體的邏輯實(shí)現(xiàn)中實(shí)現(xiàn)。
4 URL過(guò)濾
在進(jìn)入邏輯處理之前,加入對(duì)URL的參數(shù)過(guò)濾阁簸,如
限定num位置為整數(shù)等爬早,如果不是參數(shù)則直接返回非法參數(shù),設(shè)定一個(gè)url清單启妹,不在不在url清單中的請(qǐng)求直接拒絕筛严,這樣能防止開(kāi)發(fā)中的api泄露。rest api接口一般會(huì)用到GET,POST,PUT,DELETE,未實(shí)現(xiàn)的方法則直接返回方法不允許饶米,對(duì)于POST桨啃,PUT方法的數(shù)據(jù)采用json格式,并且在進(jìn)入邏輯前驗(yàn)證是否json檬输,不合法返回json格式錯(cuò)誤照瘾。
5 重要功能加密傳輸
第一步推薦SSL加密傳輸,同時(shí)對(duì)于系統(tǒng)中重要的功能做加密傳輸褪猛,如證書(shū)网杆,一些數(shù)據(jù),配置的備份功能伊滋,同時(shí)還得確保具備相應(yīng)的權(quán)限碳却,這一步會(huì)在授權(quán)中涉及。
6 速率限制
請(qǐng)求速率限制笑旺,根據(jù)api_key或者用戶來(lái)判斷某段時(shí)間的請(qǐng)求次數(shù)昼浦,將該數(shù)據(jù)更新到內(nèi)存數(shù)據(jù)庫(kù)(redis,memcached)筒主,達(dá)到最大數(shù)即不接受該用戶的請(qǐng)求关噪,同時(shí)這樣還可以利用到內(nèi)存數(shù)據(jù)庫(kù)key在特定時(shí)間自動(dòng)過(guò)期的特性。在php中可以使用APC乌妙,AlternativePHPCache (APC) 是一個(gè)開(kāi)放自由的PHPopcode 緩存使兔。它的目標(biāo)是提供一個(gè)自由、 開(kāi)放藤韵,和健全的框架用于緩存和優(yōu)化PHP的中間代碼虐沥。在返回時(shí)設(shè)置X-Rate-Limit-Reset:當(dāng)前時(shí)間段剩余秒數(shù),APC的示例代碼如下:
7 錯(cuò)誤處理
對(duì)于非法的泽艘,導(dǎo)致系統(tǒng)出錯(cuò)的等請(qǐng)求都進(jìn)行記錄欲险,一些重要的操作,如登錄匹涮,注冊(cè)等都通過(guò)日志接口輸出展示天试。有一個(gè)統(tǒng)一的出錯(cuò)接口,對(duì)于400系列和500系列的錯(cuò)誤都有相應(yīng)的錯(cuò)誤碼和相關(guān)消息提示然低,如401:未授權(quán)喜每;403:已經(jīng)鑒權(quán)务唐,但是沒(méi)有相應(yīng)權(quán)限。如不識(shí)別的url:
,錯(cuò)誤的請(qǐng)求參數(shù)
,不允許的方法:
灼卢,非法參數(shù)等绍哎。上面所說(shuō)的都是單狀態(tài)碼来农,同時(shí)還有多狀態(tài)碼鞋真,表示部分成功,部分字符非法等沃于。示例如下:
8 重要ID不透明處理
在系統(tǒng)一些敏感功能上涩咖,比如/user/1123 可獲取id=1123用戶的信息,為了防止字典遍歷攻擊繁莹,可對(duì)id進(jìn)行url62或者uuid處理檩互,這樣處理的id是唯一的,并且還是字符安全的咨演。
9 其他注意事項(xiàng)
(1)請(qǐng)求數(shù)據(jù)闸昨,對(duì)于POST,DELETE方法中的數(shù)據(jù)都采用json格式,當(dāng)然不是說(shuō)rest架構(gòu)不支持xml薄风,由于xml太不好解析饵较,對(duì)于大部分的應(yīng)用json已經(jīng)足夠,近一些的趨勢(shì)也是json越來(lái)越流行遭赂,并且json格式也不會(huì)有xml的一些安全問(wèn)題循诉,如xxe。使用json格式目前能防止掃描器自動(dòng)掃描撇他。 (2)返回?cái)?shù)據(jù)統(tǒng)一編碼格式茄猫,統(tǒng)一返回類型,如Content-Type: application/json; charset=”UTF-8″ (3)在邏輯實(shí)現(xiàn)中困肩,json解碼之后進(jìn)行參數(shù)驗(yàn)證或者轉(zhuǎn)義操作划纽,第一步j(luò)son格式驗(yàn)證,第二步具體參數(shù)驗(yàn)證基本上能防止大部分的注入問(wèn)題了锌畸。 (4)在傳輸過(guò)程中勇劣,采用SSL保證傳輸安全。 (5)存儲(chǔ)安全蹋绽,重要信息加密存儲(chǔ)芭毙,如認(rèn)證信息hash保存。
總之卸耘,盡量使用SSL退敦。