張文盛,章紅琴
(1.安徽廣播電視大學 信息技術與網絡管理中心,安徽 合肥 230022;2.合肥恒卓科技有限公司 營銷二部,安徽 合肥 230022)
URL是Web應用的入口,URL安全是Web應用安全的重要組成部分。URL存在的安全問題主要包括信息泄露和信息篡改。信息泄露包括兩種情況:一種是給攻擊者一些有用的信息,攻擊者據此推斷內部實現細節,進而找到漏洞[1];另一種是URL本身包含一些敏感信息,例如密碼或SESSION ID,可直接為攻擊者所用[2]。信息篡改也包括兩種情況:一種是攻擊者修改URL中的參數,通過提交精心構造的數據,完成結構化查詢語言(Structured Query Language,SQL)注入、跨站腳本攻擊(Cross Site Scripting,XSS)注入等攻擊[3];另一種是通過分析URL中參數存在的規律,進而枚舉所有有效的參數,獲取非授權信息[4]。URL保護是針對上述安全問題提出的解決方案。URL保護目標包括信息完整性和信息保密性,完整性解決信息篡改問題,保密性解決信息泄露問題。
目前主流的URL保護方案是設計URL保護算法。URL保護算法采用密碼學提供的加密、解密、散列等工具,將這些工具進行一定的組合,形成算法后對URL進行保護。這些密碼學工具的構造有很堅實的理論基礎,也經過實踐檢驗,因此可靠性很高,能夠達到保護URL的目的。URL保護算法的缺點是需要保護密鑰,如果密鑰泄露,保護算法就形同虛設。此外保護算法在生成URL和檢驗URL時都要進行大量運算,增加系統開銷。針對這些缺點,本文選擇從另一個角度出發,設計基于短鏈接的URL保護模型,完成保護URL完整性和保密性的目的。
目前URL保護算法包括三種:保護完整性(I型)[5]、保護機密性(II型)[6]、同時保護完整性和機密性(III型)[7]。這三種算法中,使用散列函數保證完整性,使用對稱加密算法保證機密性。
以III型為例介紹URL保護算法的工作原理。假設該法采用消息摘要算法第5版(Message-Digest Algorithm Version 5,MD5)和高級加密標準(Advanced Encryption Standard,AES)共同保護URL。規定單引號為字符串定界符,單引號之間的字符為字符串內容,加號為字符串拼接運算符,則算法的具體執行過程如下。
(1)將請求參數s1和密鑰key1按規定順序裝配成字符串s2=key1+s1;
(2)計算s2的MD5檢驗和v=MD5(s2);
(3)將檢驗和v嵌入s1成為新的請求字符串s3=′v=′+v+′&′+s1;
(4)對s3使用密鑰key2執行AES加密得到字符串s4=AES(s3,key2);
(5)對s4使用改進base64編碼為字符串s5=base64_encode(s4),得到最終URL;
(6)解析過程逆向操作,期間驗證檢驗和,丟棄無效請求。
其工作原理如圖1和圖2所示。

圖1 III型保護算法生成URL過程

圖2 III型保護算法解析URL過程
短鏈接也是一種URL,只是長度非常短,只有幾個字符,優點是節省流量,方便生成二維碼,移動應用上使用很普遍[8]。本模型使用了短鏈接,工作原理如圖3所示。

圖3 基于短鏈接URL保護模型工作原理
圖3中,系統先生成URL,再根據URL在鍵-鍵(Key-Key,KK)緩存中查詢對應的短鏈接,如果沒有,則使用短鏈接生成算法,生成一個短鏈接,建立URL和短鏈接的映射關系,存入KK緩存,然后將短鏈接返回給用戶。用戶訪問短鏈接,系統在KK緩存中查詢該短鏈接對應的URL,如果沒有則報錯,否則再將URL傳給后端業務進一步處理。
根據工作原理,KK緩存是模型核心,實現將URL映射成短鏈接和將短鏈接映射成URL的雙重功能,要求URL唯一和短鏈接唯一,屬于Key-Key緩存,區別于普通的鍵值(Key-Value,KV)緩存。KK緩存支持三個操作:存入URL和短鏈接的映射關系,根據URL獲取映射的短鏈接,根據短鏈接獲取映射的URL。
本模型中,URL和短鏈接之間的映射關系需要長期維持,避免用戶過一段時間再訪問短鏈接就報錯,因此這種映射關系需要持久化,例如寫入硬盤。隨著系統的持續訪問,映射關系會越來越多,但其實經常用到的不多,為了在映射數量和可用性之間找到平衡,需要定期清理映射關系,例如采用過期策略,超過一段時間沒有訪問的映射關系,可以銷毀。
短鏈接使用短鏈接算法生成。該算法應該基于URL生成短鏈接。為了保證系統安全,根據短鏈接很難推測出對應的URL,需要設計安全高效的短鏈接生成算法,散列函數具有較好的單向性,可以用在生成算法中。為了保密,可以設置密鑰,密鑰泄漏了也沒有關系,可以換一個,對模型的執行和安全性沒有任何影響。短鏈接很短,碰撞概率很高,因此算法需要加鹽,例如隨機數,萬一發生碰撞,可以再生成一個。
短鏈接只有幾個隨機字符,不包含任何敏感信息。短鏈接是隨機字符串,假設長度為6,采用26個大小寫英文字符和10個數字,則短鏈接空間大小是626=56 800 235 584≈568億。合法的短鏈接最多也就十幾萬個,只有總空間的萬分之一不到,也就是枚舉1萬個短鏈接,才有一個可能是合法的。完全遍歷短鏈接空間進行攻擊,需要花費很長時間和代價。即使遍歷整個空間,由于所有的URL都是合法生成的,造成攻擊的的可能性幾乎不存在。
本模型和普通的URL保護算法屬于兩種不同的方案,稱采用URL保護算法的方案為基于加密保護URL的算法模型,簡稱算法模型,稱本模型為基于短鏈接保護URL的映射模型,簡稱映射模型。映射模型僅在URL和短鏈接之間進行高速的映射操作,不涉及復雜的加解密算法,理論上性能高于算法模型。算法模型需要保護密鑰,一旦密鑰泄漏,保護就失效了。映射模型可以設置密鑰,但密鑰泄漏不影響模型的安全性,安全性要高于算法模型。此外使用短鏈接也節省傳輸流量,適合移動互聯網應用。
算法模型中,服務器根據URL進行編碼和解碼,不依賴于其他狀態。映射模型中,服務器根據KK緩存中的數據進行編碼和解碼,依賴于KK緩存。因此本質上,算法模型是無狀態模型,映射模型是有狀態模型。
KK緩存有多種選型,例如關系型數據庫MySQL;非關系型數據庫MongoDB;KV數據庫Memcache和Redis等。MySQL和MongoDB等數據庫可以建立唯一索引,并且本身已具備持久化能力,完全滿足KK緩存的要求,唯一的缺點是性能不如KV數據庫。Memcache屬于純內存數據庫,不具備持久化能力,Memcache基于內存,速度最快,但無法滿足KK的唯一性要求,需要改造。Redis的MSETNX命令可以一次設置多個KV,使用MSETNX

表1 KK緩存選型對比
純內存KK緩存中的數據只保存在內存中,因此速度最快,屬于高速緩存,但缺點也明顯,一但系統重啟或崩潰數據便會丟失,還需從其他地方重新加載,例如和其他可持久型數據庫進行合作。純內存KK緩存重啟后,要重新初始化,從后端數據庫中加載所有映射關系。系統運行中有新的映射關系建立,KK緩存中存一份,數據庫也要存一份。
為了測試各種選型的性能差異,改造Memcache實現純內存KK緩存。Memcache的add操作在key存在的時候出錯返回,該操作最接近KK需求。修改add操作的邏輯,實現Redis MSETNX相同功能,執行兩次set,一次是set(key=url,value=短鏈接),一次是set(key=短鏈接,value=url),并且任何key存在的時候,都出錯返回。后端再配合MySQL數據庫,就可以滿足KK緩存需求。
短鏈接生成算法有很多種實現方法,為了測試方便,選用的短鏈接生成算法偽代碼如下:
function ShortText(url,key,rand){
用a-z,0-9,A-Z共62個字符構建字符表chars;
str=md5(rand+key+url);
//字符串連接,輸出為128位二進制數據
取str前4個字節,作為32位無符號整數賦值給變量a;
b=0x3fffffff&a;
//將最高2位抹掉,變成30位數
ret=〃;
for(i=0;i<6;i++){
//循環6次
c=b&0x3d;
//限制c在0-62之間
ret=ret+chars[c];
//字符串連接
b=b>>5;
}
return ret;
//返回一個長度為6的字符串
}
由于KK緩存選型和短鏈接生成算法實現有很多種,為了兼容各種選擇,映射模型采用接口的方式實現,這樣不管采用什么系統,都可以無縫使用。接口定義如下:
interface Iurlmap
{
public function createShortLink($url);
//根據URL生成短鏈接
public function createMap($url);
//獲取URL映射短鏈接
public function resolvMap($shortlink);
//獲取短鏈接映射的URL
}
比較算法模型(選用III算法,實現同參考文獻[7])和映射模型的性能開銷,映射模型中的KK緩存選型包括MySQL、MongoDB、改進Memcache和Redis。在PHP中單機(不經過交換機和路由器)測試,配置是AMD EPYC 7281 16-Core Processor,內存128 GB,操作系統Ubuntu 18.04.3 LTS,PHP 7.2.19-0ubuntu0.18.04.1 (cli,NTS),MySQL 5.7.27-0ubuntu0.18.04.1,MongoDB 3.6.3,Redis 4.0.9,改進Memcached基于1.4.5版本修改。Memcache等服務采用C/S模式訪問,網絡通信很慢,作為對比,本測試還使用PHP的數組模擬純內存KK緩存,簡稱mem。測試項目包括生成URL和解析URL,采用兩組不同長度的URL作為輸入或輸出,分別是25字符和250字符。每組包括2種耗時測試:運行100萬次和運行1 000萬次,每種測試5次,取耗時均值,耗時單位為秒,測試結果如表2所示。
表2中,L*表示URL長度,例如L25表示URL長度為25字符;R*表示運行次數,例如R100表示運行100萬次,T*表示該列測試類型所需的平均時間,例如T1表示URL長度25字符運行100萬次所需的平均時間;P1=(T4-T2)×100/T2,統計URL長度增加10倍,耗時增加多少;P2=1 000/T2,統計每秒執行操作次數(Query Per Second,QPS),單位為萬/s。從表2可以看出,運行次數增加10倍,所有操作的耗時也增加10倍,耗時與運行次數為線性關系;URL長度增加10倍,算法模型耗時增加50%,而映射模型耗時變化很小,說明算法模型耗時與輸入強相關,映射模型耗時與輸入弱相關;QPS比較,mem > III型> Memcache > Redis > MySQL > MongoDB,純內存KK緩存速度比III保護算法快20倍,但C/S模式因為涉及網絡通信等IO操作,導致Memcache比III型保護算法慢將近20倍。

表2 算法模型和映射模型的性能測試
保護URL能提高Web應用的安全性,傳統基于加密保護URL的算法模型存在處理慢和密鑰泄漏問題,本文設計一種基于短鏈接保護URL的映射模型,詳細描述模型的工作原理,通過KK緩存實現URL和短鏈接的高速轉換,保證了安全性和可用性。在探討了系統實現關鍵技術后,測試了算法模型和映射模型的性能,結果表明映射模型理論性能比算法模型要高一些,但由于實現的原因,實際性能要低一些。此外映射模型的結構比算法模型復雜,穩定性也要差一點。總體上,映射模型無密鑰泄漏問題,節省流量,處理速度也不慢,可以滿足大多數Web應用的需求。