在電商行業,線上的營銷活動特別多。在移動互聯網時代,通常爲了活動的快速上線和內容的即時更新,大部分的業務場景仍然經過 Web 頁面來承載。但因爲 Web 頁面天生「環境透明」,相較於移動客戶端頁面在安全性上存在更大的挑戰。本文主要以移動端 Web 頁面爲基礎來說述如何提高頁面安全性。html
對於營銷活動類的 Web 頁面,領券、領紅包、抽獎等活動方式很常見。此類活動對於普通用戶來講大多數時候就是「拼手氣」,而對於非正經常使用戶來講,能夠經過直接刷活動 API 接口的「做弊」方式來提高「手氣」。這樣的話,對普通用戶來講,就變得很不公平。前端
對於活動運營的主辦方來講,若是風控措施作的很差,這類刷接口的「拼手氣」方式可能會對企業形成較大的損失。如原本計劃按 7 天發放的紅包,在上線 1 天就被刷光了,活動的營銷成本就會被意外提高。主辦方想發放給用戶的滿減券、紅包,卻大部分被黃牛使用自動腳本刷走,而真正想參與活動的用,卻沒法享受活動優惠。web
終端用戶究竟是人仍是機器,網絡請求是否爲真實用戶發起,是否存在安全漏洞而且已被「羊毛黨」惡意利用等等,這些都是運營主辦方要擔憂的問題。算法
爲了提高活動 Web 頁面的安全性,一般會引入專業的風控服務。引入風控服務後,安全防禦的流程大體如圖所示。segmentfault
對於活動 Web 頁面來講,加入的風控服務主要爲了作人機識別驗證。在人機識別驗證的專業領域上,咱們能夠先看看業界巨頭 Google 是怎麼作的。後端
Google 使用的人機驗證服務是著名的 reCAPTCHA(Completely Automated Public Turing Test To Tell Computers and Humans Apart,區分人機的全自動圖靈測試系統),也是應用最廣的驗證碼系統。早年的 reCAPTCHA 驗證碼是這樣的:瀏覽器
現在的 reCAPTCHA 已經再也不須要人工輸入難以識別的字符,它會檢測用戶的終端環境,追蹤用戶的鼠標軌跡,只需用戶點擊「我不是機器人」就能進行人機驗證(reCAPTCHA騙用戶進行數據標註而進行AI訓練的驗證另說)。緩存
reCAPTCHA 的驗證方式從早先的輸入字符到如今的輕點按鈕,在用戶體驗上,有了較大的提高。安全
而在活動場景中引入人機識別驗證,若是隻是簡單粗暴地增長驗證碼,或者只是像 reCAPTCHA 那樣增長點擊「我不是機器人」的驗證,都會犧牲用戶體驗,下降用戶參加活動的積極性。網絡
Google 的普通 Web 頁面的瀏覽和有強交互的活動 Web 頁面雖是不一樣的業務場景,但對於活動 Web 頁面來講,強交互剛好爲人機識別驗證提供了用戶交互行爲數據收集的契機。
理想的方案是在用戶無感知的狀況下作人機識別驗證,這樣既確保了安全又對用戶體驗無損傷。
從實際的業務場景出發再結合 Web 自己的環境,若是想實現理想的方案,可能會面臨以下的技術挑戰:
在上述的三個挑戰中,(1)已經實現了人機識別驗證的功能,而(2)和(3)都是爲了確保人機識別驗證不被破解而作的安全防範。接下來,本文會分別針對這三個技術挑戰來講明如何設計技術方案。
先來分析一下用戶的使用場景,正經常使用戶參與活動的步驟是用戶進入活動頁面後,會有短暫的停留,而後點擊按鈕參與活動。這裏所說的「參與活動」,最終都會在活動頁面發起一個接口的請求。若是是非正經常使用戶,能夠直接跳過以上的實際動做而去直接請求參與活動的接口。
那麼區別於正經常使用戶和非正經常使用戶就是那些被跳過的動做,對實際動做進一步概括以下:
以上的動做又能夠分爲必需的操做和可選的操做。對這一連串動做產生的日誌數據進行收集,在請求參與活動的接口時,將這些數據提交至後端,驗證其合法性。這就是一個簡單的人機識別驗證。
在驗證動做的合法性時,須要考慮到這些動做數據是否是能被輕易模擬。另外,動做的發生應該有一條時間線,能夠給每一個動做都增長一個時間戳,好比點擊按鈕確定是在進入頁面以後發生的。
一些特定的動做的日誌數據也會有合理的區間,進入頁面的動做若是以 JS 資源加載的時間爲基準,那麼加載時間可能大於 100 毫秒,小於 5 秒。而對於移動端的按鈕點擊,點擊時記錄的座標值也會有對應的合理區間,這些合理的區間會根據實際的環境和狀況來進行設置。
除此以外,設備環境的數據也能夠進行收集,包括用戶參與活動時使用的終端類型、瀏覽器的類型、瀏覽器是否爲客戶端的容器等,若是使用了客戶端,客戶端是否會攜帶特殊的標識等。
最後,還能夠收集一些「無效」的數據,這些數據用於障人耳目,驗證算法會將其忽略。儘管收集數據的動做是透明的,可是驗證數據合法性不是透明的,攻擊者沒法知道,驗證的算法中怎麼區分哪些是有效、哪些是無效。這已經有點「蜜罐數據」的意思了。
收集的敏感數據要發送給風控服務端,進而確保通訊過程的安全。
Token 是一個簡短的字符串,主要爲了確保通訊的安全。用戶進入活動 Web 頁面後,請求參與活動的接口以前,會從服務端獲取 Token。該 Token 的生成算法要確保 Token 的惟一性,經過接口或 Cookie 傳遞給前端,而後,前端在真正請求參與活動的接口時須要帶上該 Token,風控服務端須要驗證 Token 的合法性。也就是說,Token 由服務端生成,傳給前端,前端再原封不動的回傳給服務端。一旦加入了 Token 的步驟,攻擊者就不能直接去請求參與活動的接口了。
Token 由風控服務端基於用戶的身份,根據必定的算法來生成,沒法僞造,爲了提高安全等級,Token 須要具備時效性,好比 10 分鐘。可使用 Redis 這類緩存服務來存儲 Token,使用用戶身份標識和 Token 創建 KV 映射表,並設置過時時間爲 10 分鐘。
雖然前端在 Cookie 中能夠獲取到 Token,可是前端不能對 Token 作持久化的緩存。一旦在 Cookie 中獲取到了 Token,那麼前端能夠當即從 Cookie 中刪除該 Token,這樣能儘可能確保 Token 的安全性和時效性。Token 存儲在 Redis 中,也不會由於用戶在參與活動時頻繁的切換頁面請求,而對服務形成太大的壓力。
另外,Token 還能夠有更多的用處:
通訊時,傳遞的敏感數據可使用常見的對稱加密算法進行加密。
爲了提高加密的安全等級,加密時的密鑰能夠動態生成,前端和風控服務端約定好動態密鑰的生成規則便可。加密的算法和密鑰也要確保不被暴露。
經過對敏感數據加密,攻擊者在不瞭解敏感數據內容的前提下就更別提模擬構造請求內容了。
有經驗的 Web 開發者看到這裏,可能已經開始質疑了:在透明的前端環境中折騰安全不是白折騰嗎?這就比如費了很大的勁卻只是造了一個「紙老虎」,質疑是有道理的,可是且慢,經過一些安全機制的增強是可讓「紙老虎」儘量的逼真。
本文一再說起的 Web 環境的透明性,是由於在實際的生產環境中的問題:前端的代碼在壓縮後,經過使用瀏覽器自帶的格式化工具和斷點工具,仍然具有必定的可讀性,花點時間仍然能夠理解代碼的邏輯,這就給攻擊者提供了大好的代碼反編譯機會。
若是要化解「紙老虎」的尷尬,就要對前端的代碼進行混淆。
前端的 JS 代碼壓縮工具基本都是對變量、函數名稱等進行縮短,壓縮對於混淆的做用是比較弱。除了對代碼進行壓縮,還須要進行專門的混淆。
對代碼進行混淆能夠下降可讀性,混淆工具備條件的話最好自研,開源的工具要慎用。或者基於 Uglify.js 來自定義混淆的規則,混淆程度越高可讀性就越低。
代碼混淆也須要把握一個度,太複雜的混淆可能會讓代碼沒法運行,也有可能會影響自己的執行效率。同時還須要兼顧混淆後的代碼體積,混淆先後的體積不能有太大的差距,合理的混淆程度很重要。
斷點工具的防範會更麻煩些。在使用斷點工具時一般都會致使代碼延遲執行,而正常的業務邏輯都會當即執行,這是一個能夠利用的點,能夠考慮在代碼執行間隔上來防範斷點工具。
經過代碼混淆和對代碼進行特殊的處理,可讓格式化工具和斷點工具變得沒有用武之地。惟一有些小遺憾,就是處理後的代碼也不能正常使用 Source Map 的功能了。
有了代碼混淆,反編譯的成本會很是高,這樣「紙老虎」已經變得很逼真了。
在講解完如何解決關鍵的技術挑戰後,就能夠把相應的方案串起來,而後設計成一套能夠實施的技術方案了。相對理想的技術方案架構圖以下:
下面會按步驟來說解技術方案的處理流程:
Step 0 基礎風控攔截
基礎風控攔截是上面提到的頻次、名單等的攔截限制,在 Nginx 層就能直接實施攔截。若是發現是惡意請求,直接將請求過濾返回 403,這是初步的攔截,用戶在請求 Web 頁面的時候就開始起做用了。
Step 1 風控服務端生成 Token 後傳給前端
Step 0 可能還沒進入到活動 Web 頁面,進入活動 Web 頁面後才真正開始人機識別驗證的流程,前端會先開始獲取 Token。
Step 2 前端生成敏感數據
敏感數據應包含用戶交互行爲數據、設備環境數據、活動業務邏輯數據以及無效數據。
Step 3 使用 HTTPS 的簽名接口發送數據
Token 能夠做爲 Authorization 的值添加到 Header 中,數據接口的簽名能夠有效防止 CSRF 的攻擊。
Step 4 數據接口的校驗
風控服務端收到請求後,會先驗證數據接口簽名中的 Token 是否有效。驗證完 Token,纔會對敏感數據進行解密。數據解密成功,再進一步對人機識別的數據合法性進行校驗。
Step 5 業務邏輯的處理
前面的步驟爲了作人機識別驗證,這些驗證不涉及到業務邏輯。在全部這些驗證都經過後,後端業務服務纔會開始處理實際的活動業務邏輯。處理完活動業務邏輯,最終纔會返回用戶參與活動的結果。
爲了提高活動 Web 頁面的安全性,使用了各類各樣的技術方案,咱們將這些技術方案組合起來才能發揮安全防範的做用,若是其中某個環節處理不當,均可能會被看成漏洞來利用,從而致使整個驗證方案被攻破。
爲了驗證技術方案的有效性,能夠持續觀察活動 API 接口的請求成功率。從請求成功率的數據中進一步分析「誤傷」和「攔截」的數據,以進一步肯定是否要對方案進行調優。
經過上述的人機識別驗證的組合方案,能夠大幅提高活動 Web 頁面的安全性。在活動 Web 頁面應做爲一個標準化的安全防範流程,除了美團,像淘寶和天貓也有相似的流程。因爲活動運營的環節和方法多且複雜,僅僅提高了 Web 頁面也不敢保證就是鐵板一塊,安全須要關注的環節還不少,安全攻防是一項長期的「拉鋸升級戰」,安全防範措施也須要持續地優化升級。
益國,美團點評 Web 前端開發工程師。2015年加入美團,曾前後負責過風控前端SDK和活動運營平臺的研發,現負責大數據平臺的研發工做。