文章來源于前端黑洞 ,作者拓巖
在某乎上,最近有一個很火的問題:前端能否限制用戶截圖?
當我瀏覽這個問題的時候,我覺得提問者應該是個萌新,或者已經被產品經理或 SB leader 折磨的失去理智。因為下方有一個非常直中要害的回答:
無論多么牛的技術手段限制了軟件的截圖, 用戶只要簡單的掏出手機對著屏幕拍照就好了。
這個問題,真的說明一切的前端安全,其實都是紙老虎。
接下來,我結合自己遇到的幾個場景,來談一些做前端以來,自己遇到的那些偽前端安全需求。
曾經那些被懟回去的安全需求
最近幾年互聯(lián)網數(shù)據泄露非常頻繁,我上一家公司是做金融貸款的,非常強調數(shù)據安全,這兩年也做了不少關于安全的需求。
前端數(shù)據脫敏
前端數(shù)據脫敏是一個很常見的需求,特別是當今隱私被賣的這么猖狂的時代,所以很多公司都開始注重這些細節(jié),最基礎的就是數(shù)據脫敏。
數(shù)據脫敏,就是將用戶的隱私信息,用一些手段,讓這些信息有一定辨識度,但又無法準確獲取,比如:
上面一般是我們常見到的數(shù)據脫敏格式,我又叫他數(shù)據馬賽克
。前端能不能做,肯定能做,一個正則配上一個String.replace
方法就搞定。但如果產品讓我們實現(xiàn)這種需求,我們肯定要拒絕,因為前端做數(shù)據脫敏就是被單里眨眼睛
- 自欺欺人。
歸根結底,一個稍微有點IT常識的人,如果想要這些數(shù)據,直接從請求拿就是了,何必從頁面復制。
所以數(shù)據脫敏這種事,一定要交給后端做,從源頭開始脫敏。
可能后面一些場景,有些被脫敏的數(shù)據,在前端又要被用到。比如列表數(shù)據脫敏,到詳情/表單編輯操作時又需要脫敏前的,那就根據ID再發(fā)一次請求獲取脫敏前的數(shù)據,然后對這個接口調用做權限限制和日志記錄
,讓敏感數(shù)據的使用相對安全。
表單校驗是為了安全么
我們在做表單時,很多時候都會針對數(shù)據格式做校驗,比如郵箱、電話號碼、銀行卡號這些,甚至還有一些非常 復雜的聯(lián)動校驗。
前端做校驗是為了安全么?
可能有那么一丁點意思吧,比如以前我們總是在提校驗輸入防XSS
攻擊。但現(xiàn)在前端這種格式校驗,更多是為了: 提升用戶體驗
,提升用戶體驗
,提升用戶體驗
。
?首先提醒并引導用戶,應該怎么輸入;?其次,如果用戶輸入半天,前端不校驗,直接到后臺,后臺發(fā)現(xiàn)格式不正確,再提示用戶,這是一個非常耗時且不專業(yè)的交互體驗;?如果前端沒校驗,后端也沒校驗,那這就是一條臟數(shù)據插入到數(shù)據庫,有可能造成XSS攻擊
或 SQL攻擊
, 這就非常危險了。
數(shù)據報表加水印
頁面加水印,其實在前端很普遍,比如釘釘
, 企業(yè)微信
的群聊都是加了水印的,很多在線圖片編輯工具也是加了的,比如我常用的圖怪獸[2],你想白嫖,他就給你加個水?。?/p>
而當時我們有些列表,因為運營需要,有些數(shù)據沒法做數(shù)據脫敏,所以領導說,前端能不能做個水印,讓數(shù)據安全一點:防止運營人員不按規(guī)范處理問題,私自截圖。所以當我看到知乎那個提問時,我特別慶幸,沒有讓我做:限制用戶截圖
。
從我個人經驗來講,前端加水印有三個層次:
- 通過 CSS 背景加水印,簡單粗暴,能騙一點文科運營。但稍微懂行的人,就知道通過
Elements
編輯面板屏蔽這個水印。正所謂你加的簡單,別人去掉更簡單。 - 通過 JS 定向植入水印dom節(jié)點,這個比上一個稍微復雜點,但還是通過
Elements
編輯面板屏蔽,只不過多思考一下,操作步驟多點。 - 終解: 服務端加水印生成
列表圖片
,實現(xiàn)思路和圖怪獸網站一致。但這個操作描述起來簡單,具體實現(xiàn)就非常復雜,需要考慮投入產出比
。有可能你會疑問,為什么是服務端加水印生成圖片,而不是前端自己通過 canvas 生成?- 第一,同上面提到過的,通過請求拿到敏感數(shù)據,本身就是不安全的;
- 第二,JS 本身是不安全的,可篡改;
JS 可篡改
我上面反復在說前端安全是個偽需求,你可能不信。但如果你知道 JS 是可篡改
的,那你就明白為什么了。我們總是在提JS丑化,但丑化更多是減少包的體積,在某種程度上,可以讓發(fā)布的js資源可讀性更差,但做到不可讀很難。
接下來體驗一下什么叫 JS 可篡改吧
實戰(zhàn)演練
- 第一步:Chrome 下載安裝
Header Editor
插件
- 第二步:找一個目標網站,并找到一個你想篡改的 JS 資源。我這里以我常用的作圖網站的jquery 資源(js.tuguaishou.com/js/jquery-1.11.3.min.js)引用為例;
- 第三步:拷貝代碼帶編輯器,輸入你想篡改的內容,我這里就只加了個console輸出, 然后本地起一個靜態(tài)資源服務
// ...
console.log('do some change, ho ho ho');
var c = []
, d = c.slice
, e = c.concat
// ...
- 第四步,使用插件重定向網站靜態(tài)資源,我這里就是使用本地的jquery 代替網站原有的,保存配置并啟動那個規(guī)則;
- 第五步: 強刷瀏覽器,使代理資源生效,當你看到請求被標成了307的響應,說明篡改生效,然后看console,就有了對應的輸出;
至此,一次完整的篡改完成。但這個教程并不是讓你用這個方法去做一些XX的事情,而只是讓你明白由于JS的可篡改,我們在做網站設計時,你需要時刻思考代碼安全的事,能做不代表可以做
。
分享個趣事
年初,前公司要做一次大的系統(tǒng)融合:就是兩個子公司各有各的權限系統(tǒng),然后資本青睞的一方占優(yōu)(以系統(tǒng)設計來講,我們的權限系統(tǒng)設計更專業(yè)),被遺棄的我們不得不改我們現(xiàn)有系統(tǒng),去對接對方的系統(tǒng)。
這中間因為異地溝通問題,對方開始沒把規(guī)則說好,然后對接人將我們清洗重組后的數(shù)據導入了數(shù)據庫。后面由于需要修改一些數(shù)據,網站頁面提示我們導入數(shù)據key的格式不對,而這個key,又被設置成了只讀,這就走入了死路。然后溝通能不能把數(shù)據庫數(shù)據刪除了重新導入,對方一萬個不情愿,讓我們自己在網站上自己刪除再添加數(shù)據,那可是200多條數(shù)據啊,侮辱誰呢????
這真的把我同事們惹毛了,然后就試了上面的招數(shù),看了對方的JS,代理然后再一提交,成功?。?!
知道對方業(yè)余,但沒想到這么業(yè)余:僅在前端做了限制,服務端沒校驗。
這個案例提醒我們,前端重在交互,服務端重在安全,JS是可篡改的;所以不要產品以為,要你以為,用你的專業(yè)Say no!!!
;也告訴我們做技術,謙虛點,能幫忙就盡量幫,做個好人。
結語
又摧拉枯朽扯了一堆,但愿對你以后的需求評審和方案設計有用。前端安全重要嗎?重要。網站的安全全交給前端合適嗎? 不合適。
以上就是W3Cschool編程獅
關于前端安全就是紙老虎,唬人用的的相關介紹了,希望對大家有所幫助。