第三方CSS安全嗎?

原文:jakearchibald.com/2018/third-…css

前一段時間,有不少關於用CSS構建的「鍵盤記錄器」的討論(源代碼見:github.com/maxchehab/C…html

有些人要求瀏覽器「修復」它。 另有一些人挖掘得更深一些,發現它隻影響使用React及相似框架編寫的網站,併爲此指責React。 不過真正的問題在於第三方內容是否是「安全的」。git

下面咱們逐一分析這些第三方內容。github

第三方圖片

<img src="https://example.com/kitten.jpg">
複製代碼

若是由於我信任example.com,就在本身的代碼中包含上述內容。那麼 他們可能會刪除資源,從而給我返回一個404,使個人網站看起來支離破碎,從而辜負了這種信任。同時他們也有可能會用一些不恰當的內容取代原來的圖片。數據庫

不過圖像的影響僅限於元素自己的內容框。 我能夠向本身的用戶解釋「這是來自example.com的內容,若是它變冒犯了你,那是他們的錯,可別來找我」,並寄但願於用戶們可以相信我。 可是這種事確定不會影響我數據庫中密碼字段之類的東西。vim

第三方腳本

<script src="https://example.com/script.js"></script>
複製代碼

與圖片相比,第三方腳本有更多的控制權。 若是個人代碼中包含上述內容,就會給example.com徹底控制本身的網站的機會。 他們能:瀏覽器

  • 讀取/更改頁面內容。
  • 監控用戶交互的每個步驟。
  • 運行計算量很大的代碼(好比用你的瀏覽器挖礦)。
  • 盜取用戶的cookie向個人來源發出請求,並轉發響應數據。
  • 讀取/更改原始存儲。
  • 幾乎能夠作任何他們想作的事。

「原始存儲」位很是重要。 若是腳本影響了IndexedDB或緩存存儲API,即便你把腳本刪掉,攻擊也可能會仍然繼續。緩存

若是你在本身的代碼中引用了來自其餘來源的腳本,那麼必須絕對信任它們,並保證其安全性。安全

若是遇到惡意腳本,則應使用 Clear-Site-Data 標頭清除全部站點數據。服務器

第三方CSS

<link rel="stylesheet" href="https://example.com/style.css">
複製代碼

CSS的做用更接近於腳本而不是圖像。和腳本同樣,它適用於整個頁面。 它能夠:

  • 刪除/添加/修改頁面內容。
  • 根據頁面內容發出請求。
  • 對許多用戶交互做出響應。

CSS不能修改原始存儲,你不能用CSS寫一個挖礦程序(也有可能,或許我還不知道),但惡意CSS仍然能夠形成很大的破壞。

鍵盤記錄器

我們從最開始的那個問題開始

input[type="password"][value$="p"] {
  background: url('/password?p');
}
複製代碼

若是輸入的 value 屬性以 p 結尾,上面的代碼將觸發對 /password?p 的請求。 對每一個字符都會執行此操做,這樣你會得到大量鍵盤輸入的數據。

默認狀況下,瀏覽器不會將用戶輸入的值存儲在 value 屬性中,所以攻擊每每在同步這些值的內容時發生,例如React。

爲了緩解這種狀況,React可使用另外一種同步密碼字段的方法,或者瀏覽器能夠限制與密碼字段的 value 屬性匹配的選擇器,但這僅僅是一種虛假的安全感。 你只不過是解決了一個特定的問題,但其餘狀況下一切照舊。

若是 React 切換到使用data-value屬性,則上述手段將失敗。若是站點將輸入更改成type ="text",那麼用戶能夠看到他們正在輸入的內容,則這種手段失敗。 若是站點建立<better-password-input>並將值做爲屬性公開,一樣上述手段失敗。

此外,還有許多基於CSS的攻擊:

消失的內容

body {
  display: none;
}

html::after {
  content: 'HTTP 500 Server Error';
}
複製代碼

這是一個極端的例子,但想象一下,若是第三方代碼爲你的一小部分用戶作了這種事,會出現什麼樣的後果:將會侵蝕掉用戶對你的信任,同時很難排查問題到底出在何處。

更加腹黑的黑客可能會偶爾刪除「購買」按鈕,或着從新排列內容中的段落。

添加內容

.price-value::before {
  content: '1';
}
複製代碼

哎呀,你這麼快就漲價了!

移除內容

delete-everything-button {
  opacity: 0;
  position: absolute;
  top: 500px;
  left: 300px;
}
複製代碼

把一個有「刪庫跑路」功能的按鈕設爲不可看,而後再把它放在用戶可能會點擊的地方。

值得慶幸的是,若是按鈕執行的是後果很是嚴重的操做,該網站可能會首先顯示確認對話框。 不要緊,只需使用更多的CSS來誘騙用戶單擊「是的我肯定!」按鈕而不是「哦天吶!不是!」按鈕。

想象一下,若是瀏覽器確實試圖消除「鍵盤記錄」這種小伎倆的影響。攻擊者還能夠在頁面上放一個非密碼文本輸入框(多是搜索字段)並將其覆蓋在密碼輸入框之上,呵呵,如今他們又回來了。

讀取屬性

你擔憂的可不只僅是密碼。 一些私有內容可能會保存在屬性中:

<input type="hidden" name="csrf" value="1687594325">
<img src="/avatars/samanthasmith83.jpg">
<iframe src="//cool-maps-service/show?st-pancras-london"></iframe>
<img src="/gender-icons/female.png">
<div class="banner users-birthday-today"></div>
複製代碼

全部這些均可以被CSS選擇器設爲目標,而且能夠把結果發到某個服務器上。

監控互動

.login-button:hover {
  background: url('/login-button-hover');
}

.login-button:active {
  background: url('/login-button-active');
}
複製代碼

能夠將hover和active等動做發送回服務器。 適當的使用CSS,你能夠很好地瞭解用戶想要幹什麼。

讀取文本

@font-face {
  font-family: blah;
  src: url('/page-contains-q') format('woff');
  unicode-range: U+71;
}

html {
  font-family: blah, sans-serif;
}
複製代碼

在這種狀況下,若是頁面包含q,將發送請求。 你能夠爲不一樣的文字建立大量的這種請求,並能夠定位特定的元素。 字體還能夠包含連字,所以還能夠檢測字符序列。 你甚至能夠將字體技巧與滾動條檢測相結合,從而能推斷出更多相關內容的信息。

結論:第三方內容並不安全

這些只是我所知道的一些技巧,我相信還會有更多相似的小技巧。

第三方內容在其沙箱中具備很高的影響力。 雖然圖像或沙盒iframe有着很是小的沙箱,但腳本和樣式的做用範圍卻影響你的整個頁面,甚至是整個站點。

若是你擔憂用戶會欺騙你的網站去加載第三方資源,可使用CSP(內容安全策略)保證安全,從而限制從中獲取圖像,腳本和樣式的位置。

還可使用子資源完整性來確保腳本/樣式的內容與特定的哈希匹配,不然將沒法執行。

若是你對這種安全技術感興趣,包括滾動條技巧的更多細節,能夠去看看Mathias Bynens在2014年的演講,Mike West在2013年的演講,或Mario Heiderich等人的2012年論文。 沒錯,這些技術並非最新的。

相關文章
相關標籤/搜索