利用上傳的檔案跳過 CSP 限制

CSP 可以做到一些簡單的保護機制,但在設計不良的情況下還是有辦法繞過。

這次是上傳合法的 JPEG 檔案,但當作 javascript 檔案繞過去:「Bypassing CSP using polyglot JPEGs」。

開頭的「FF D8 FF E0」可以在「List of file signatures」這邊看到是「JPEG raw or in the JFIF or Exif file format」,而這四個字元在 javascript 不會出問題。接下來的「2F 2A」表示 JPEG header 長度,剛好就是「/*」,把後面的東西給包起來,後面再用類似的方式一直組合就打穿了...

這種攻擊要跳過的是「用 CSP 的 self 限制不能引用外部網站 javascript」的限制,但還是有些前提:

  • 允許使用者傳到同一個 domain 上面。
  • 網站上有 XSS 漏洞。

其中第一個問題常見的解法是另外開一個 domain 來放使用者上傳的檔案 (最好是連 top domain 都不一樣,完全隔開),才可以透過 CSP 降低風險...

利用 HSTS 資訊得知網站紀錄的 sniffly

看到「sniffly」這個工具,可以利用 HSTS 資訊檢測逛過哪些網站,程式碼在「diracdeltas/sniffly」這邊可以找到:

Sniffly is an attack that abuses HTTP Strict Transport Security and Content Security Policy to allow arbitrary websites to sniff a user's browsing history. It has been tested in Firefox and Chrome.

測試網站則可以在這邊看到,作者拿 Alexa 上的資料網站來掃,所以熱門網站應該都會被放進去...

主要是利用 HSTS + CSP policy 的 timing attack (有逛過網站而瀏覽器裡有 HSTS 時的 redirect 會比較快,沒有逛過的時候會因為有網路連線而比較慢):

Sniffly sets a CSP policy that restricts images to HTTP, so image sources are blocked before they are redirected to HTTPS. This is crucial! If the browser completes a request to the HTTPS site, then it will receive the HSTS pin, and the attack will no longer work when the user visits Sniffly.

When an image gets blocked by CSP, its onerror handler is called. In this case, the onerror handler does some fancy tricks to time how long it took for the image to be redirected from HTTP to HTTPS. If this time is on the order of a millisecond, it was an HSTS redirect (no network request was made), which means the user has visited the image's domain before. If it's on the order of 100 milliseconds, then a network request probably occurred, meaning that the user hasn't visited the image's domain.

由於這個技巧,HTTPS Everywhere 必須關閉才會比較準確。

CSP (Content Security Policy)

Twitter 上看到 Dan Kaminsky 的 retweet:

開頭的幾篇就列出不少 CSP 常見的情況,並且說明 CSP 應該要在軟體開發時就引入:

另外提到的 CSP Level 2 也是個很有趣的觀念,像是 nonce:

以及 hash:

不過 Level 2 目前還在 working draft:「Content Security Policy Level 2」,這個功能應該還要等...

用 Content-Security-Policy 攻擊

在「When Security Generates Insecurity」這篇文章裡,介紹了如何利用 Content-Security-Policy 攻擊網站。

首先,我想要知道是不是有登入 Facebook 或是 Google

Interest piqued by the report-uri feature, I looked into abusing it to glean information about user state, my idea was this: when a user is not logged into Google Calendar, accessing calendar.google.com redirects them to accounts.google.com via a Location header. If I whitelisted calendar.google.com but not accounts.google.com, accessing that resource within my web page would break CSP, subsequently sending me a message telling me whether they were logged into Google.

也就是說,利用 CSP 的 report-uri 以及重導的特性,可以分辨出使用者是否有登入。以 Facebook 以及 Google 的例子:

The implementation was like this: I had a single image on the page <img src="http://calendar.google.com"/>, and I sent the Content-Security-Policy header Content-Security-Policy: image-src calendar.google.com. The test was a success, I was able to detect login on Google. The same extended to Facebook; apps.facebook.com would redirect to www.facebook.com only if the user was logged in.

另外,由於實務上可以偵測 path,所以可以去「猜測」使用者是不是某個特定的人,在文章裡假設的是美國總統 Barack Obama:

By using CSP to whitelist facebook.com/me and facebook.com/barackobama and embedding http://facebook.com/me as an image, I can conditionally create a CSP report only if the current user on Facebook is not Barack Obama.

很有趣的安全性問題...

HTTP Header 裡與安全相關的 Header 的分析...

還是在 Zite 上看到的,對最大的一百萬個網站分析與安全有關的 HTTP Header:「Security Headers on the Top 1,000,000 Websites: November 2013 Report」。

數字大致上都有增加,不過對我來說的重點在於有列出所有與安全有關的 HTTP Header...

可以看到有這幾個:

  • Access-Control
  • Content-Security-Policy
  • Strict-Transport-Security
  • X-Content-Security-Policy
  • X-Frame-Options
  • X-Webkit-CSP

剛好可以拿來 review 設定...