[英]Securing a session-less RESTful API endpoint
我為一個項目創建了一個簡單的RESTful API,部分遵循了Riyad Kalla的這篇非常好的博客文章 。 現在,我已經在Stack Overflow上閱讀了幾十個類似的問題,但我似乎無法找到我的安全問題的答案。
簡而言之,我的要求是這樣的:
我擔心有人使用我的服務可以獲取公共API密鑰(通過嗅探網絡流量),然后簡單地通過他們的瀏覽器使用AJAX直接向開發人員的服務器發出相同的請求。 因此,惡意用戶可以被認證為合法用戶並使用其他秘密API密鑰訪問API。
我會嘗試舉一個具體的例子。 通常我會這樣做:
但我很害怕:
我還缺少什么,或者這只是RESTful API游戲的一部分?
更新:我自願省略任何形式的時間戳驗證,以保持簡單,只關注身份驗證問題。
更新2:我已向流程添加了$_SERVER['HTTP_REFERER']
驗證。 這里的目標是客戶端必須與請求一起發送引用者,並且它必須與API側數據庫中列出的引用者匹配。 不幸的是,HTTP引用可以很容易偽造。 這是另一個安全級別,但仍然不完美。
更新3:我已經更改了服務器端代碼,將引用者設置為遠程IP地址。 這會強制發送到我的服務器的每個請求使用秘密API密鑰進行哈希處理,最終使用原始請求IP地址到達API服務器。 然后可以驗證此IP並且請求可以通過。 我相信它還有可能偽造$_SERVER['REMOTE_ADDR']
,但它比偽造$_SERVER['HTTP_REFERER']
更復雜......我想還是不完美。
更新4 :根據這些帖子: 如何偽造$ _SERVER ['REMOTE_ADDR']變量? 和https://serverfault.com/questions/90725/are-ip-addresses-trivial-to-forge ,偽造$_SERVER['REMOTE_ADDR']
雖然很難。 但是,由於您無法控制偽造網絡,因此無法接收偽造請求的響應。 該請求可以成功驗證,但其響應不會落入惡意手中。
通過使用HMAC,您走在正確的軌道上。 但是,還有兩件事可以使您的應用程序更安全。
我發現阻止其他腳本使用公共API密鑰並向服務器端HMAC哈希腳本發送請求的解決方案是發送原始請求者的身份以及請求。 我正在使用$_SERVER['REMOTE_ADDR']
來確定原始請求者的身份,因為它更難偽造,偽造它通常意味着他們不會得到響應。
/* $this as a class that handles requests */
// Build hash and include timestamp
$this->vars['timestamp'] = time();
$this->vars['hash'] = hash_hmac('sha1', http_build_query($this->vars).$this->vars['token'], API_SECRET);
// Send request to API
curl_setopt_array($this->curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url,
CURLOPT_POST => $this->method == 'post' ? 1 : NULL,
CURLOPT_POSTFIELDS => $this->method == 'post' ? $this->vars : NULL,
CURLOPT_CONNECTTIMEOUT => 15,
CURLOPT_TIMEOUT => 15,
CURLOPT_REFERER => $_SERVER['REMOTE_ADDR'], // Referer here!
CURLOPT_MAXREDIRS => 3,
CURLOPT_HTTPGET => $this->method == 'get' ? true : false
));
一旦發送,API不僅會檢查數據庫中的秘密API密鑰,還會檢查$_SERVER['HTTP_REFERER']
是否被列為允許! 這也允許API基於每個用戶接受服務器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.