相對路徑的攻擊方式 (Relative Path Overwite,RPO)

在「Large-scale analysis of style injection by relative path overwrite」這邊看到的,記得這個方式不是新方法,不過還是有人會中...

這種攻擊是組合技,基礎是引用 css 或是 js 時使用相對路徑 (像是 static/style.css 這樣的引用法),再加上 https://www.example.com/a.php 這樣的頁面通常也可以吃 https://www.example.com/a.php/,甚至是後面再加東西... 在某些情境下組不出來,但精心策劃後就有機會在頁面上弄出奇怪的 xss 或是其他攻擊了。而論文內列出了常見的的組合:

然後拿 Alexa 的排名來看,其實還是有些站台可以打:

防禦的方式也不算太難,absolute path 是個還不錯的方式:

One option is to use only absolute URLs, taking away the relative path expansion.

base tag 也是個方式 (不過在 IE 上還是有問題):

Alternatively you can specify a base tag, though Internet Explorer did not appear to implement the tag correctly (i.e., was still vulnerable) at the time of the evaluation.

另外作者也提到了 document type 的方式 (看起來是建議用 html5 的 <!DOCTYPE html>),然後 IE 另外做些處理避免失效:

One of the best mitigations is to avoid exploitation by declaring a modern document type that causes rendering in standards compliant mode. This defeats the attack in all browsers apart from IE. For IE it is also necessary to prevent the page being loaded in a frame by using X-Frame-Options , using X-Content-Type-Options to disable ‘content type sniffing,’ and X-UA-Compatible to turn off IE’s compatibility view.

不過大型站台本來就因為業務需求,會把 asset domain 切開 (然後透過 CDN 加速),而且會設計系統讓 programmer 很容易使用這樣的架構,反而因此比較不會用到 relative path,中這個攻擊的機會就低多了...

擋 Open Redirect 的問題...

Open Redirect 的問題可以參考:

這兩個連結。主要是要避免 phishing 的問題上。

一開始是以「只允許 / 開頭」為條件過濾,但 protocol-relative 的 //www.example.com 可以繞開。

如果變成「只允許 / 開頭,但不允許 // 開頭」,是不是就沒事了呢?

在「Evolution of Open Redirect Vulnerability.」這邊又看到新招:「/\www.example.com」。

想要用 parse_url() 檢查?沒問題:

$ php -a
Interactive mode enabled

php > var_dump(parse_url("/\\www.example.com"));
array(1) {
  'path' =>
  string(17) "/\www.example.com"
}

但實際測試會發現 IE8 與 Google Chrome 都會跳到 www.example.com (沃槽),其他瀏覽器就先不測了 ~_~

不過原文說的 ///www.example.comPHP 上測試應該是不會過的?

$ php -a
Interactive mode enabled

php > var_dump(parse_url("///www.example.com"));
bool(false)

反正又冒出一堆問題要處理了 ~_~

HTTP Header 裡的 Location 使用相對路徑...

HTTP Response Header 的 Location (俗稱「轉址」) 被用在不少地方,剛好今天被 ccn 戳到相關的問題...

在維基百科的「HTTP location」條目裡面有說明 HTTP/1.1 的規範裡要求必須是 absolute URI:

Location       = "Location" ":" absoluteURI

但實務上,目前市場上常見的瀏覽器都支援相對路徑。而且在 HTTP/1.1 修正版 (目前還在 draft) 裡被修正成:

Location = URI-reference

並且說明 relative 時的判定方式:

The field value consists of a single URI-reference. When it has theform of a relative reference ([RFC3986], Section 4.2), the final value is computed by resolving it against the effective request URI ([RFC3986], Section 5).

所以就大膽用吧...