CloudFront 有台灣機房了...

這是從 HiNet 機房連到 AWS 官方 d36cz9buwru1tt.cloudfront.net 的 SmokePing 資料:

從中華 HiNet 機房到 test.gslin.org:

  3.|-- 211.22.229.2               0.0%    10    0.2   0.2   0.2   0.6   0.0
  4.|-- 220.128.5.226              0.0%    10    0.4   2.6   0.4  11.9   4.4
  5.|-- 220.128.2.174              0.0%    10    2.7   5.4   2.6  12.5   3.3
  6.|-- 220.128.4.177              0.0%    10    0.4   2.0   0.4  16.2   5.0
  7.|-- 203.75.228.29              0.0%    10    1.3   1.3   1.1   1.6   0.0
  8.|-- 223.26.66.19               0.0%    10    1.7   1.4   1.3   1.7   0.0
  9.|-- 202.133.255.122            0.0%    10    1.1   6.8   1.0  38.8  12.2
 10.|-- 54.230.215.52              0.0%    10    1.2   1.2   1.1   1.3   0.0

從台灣固網 TFN 機房到 test.gslin.org:

  3.|-- 60.199.236.110             0.0%    10    0.3   0.3   0.3   0.5   0.0
  4.|-- 60.199.255.3               0.0%    10    0.3   0.3   0.3   0.3   0.0
  5.|-- 60.199.20.149              0.0%    10    0.2   0.2   0.2   0.2   0.0
  6.|-- 60.199.3.161               0.0%    10   37.9   4.1   0.2  37.9  11.9
  7.|-- 60.199.17.194              0.0%    10    0.7   3.0   0.5  14.1   4.7
  8.|-- 210.62.255.28              0.0%    10   11.0  18.1   1.9 139.9  42.9
  9.|-- 223.26.66.19               0.0%    10    1.5   1.6   1.4   1.8   0.0
 10.|-- 202.133.255.122            0.0%    10    1.9   1.8   1.6   2.4   0.0
 11.|-- 54.230.215.131             0.0%    10    3.8   3.5   1.2   5.4   1.4

雖然官方還沒公佈,但已經上線了,代碼是 tpe50

就路徑與反解資訊看起來是在是方的網路裡,不過不是很確定... 另外 Route53 看起來還沒有導過去,所以是還在 setup?

Anyway,在台灣有 PoP 的 CDN 又多了一家:

所以什麼時候會正式公佈呢...

在 HTML 內嵌 JSON object 時要注意的事情...

有時候我們會因為效能問題,在 HTML 內嵌入 JSON object,而不是再多一個 HTTP request 取得。

但「嵌入」的行為如果沒有處理好,就產生非常多 XSS attack vector 可以玩。

首先最常犯的錯誤是使用錯誤的 escape function:

<!DOCTYPE HTML>
<html>
<body>
<script>
var a = "<?= addslashes($str) ?>";
</script>
</body>
</html>

這樣可以用 </script><script>alert(1);// 攻擊 $str。因為 addslashes() 並不會過濾到這個字串,而產生這樣的 HTML:

<!DOCTYPE HTML>
<html>
<body>
<script>
var a = "</script><script>alert(1);//";
</script>
</body>
</html>

而這個字串會造成 DOM parser 解讀上產生不是我們預期的行為:

可以看到在字串裡面的 </script> 被拆開了。

這是因為瀏覽器會先拆解產生 DOM tree,再把 <script></script> 內的程式碼交給 JavaScript engine 處理。所以在一開始產生 DOM tree 的時候,是看不懂 JavaScript 程式邏輯的...

正確的方法是用 json_encode() 處理,因為 PHPjson_encode() 預設會把 / (slash) 變成 \/ (這是 JSON spec 裡合法的轉換):

<!DOCTYPE HTML>
<html>
<body>
<script>
var a = <?= json_encode($str) ?>;
</script>
</body>
</html>

這會產生出:

<!DOCTYPE HTML>
<html>
<body>
<script>
var a = "<\/script><script>alert(1);//";
</script>
</body>
</html>

但上面這段 HTML 與 PHP code 仍然有問題,如果 $str<!--<script 時,你會發現 DOM 又爛掉了:

<!DOCTYPE HTML>
<html>
<body>
<script>
var a = "<!--<script>";
</script>
</body>
</html>

escape.alf.nu 的 Level 15 就是利用這個問題,再加上其他的漏洞而完成 XSS 攻擊。

為了這個問題去 StackOverflow 上問:「Why does <!--<script> cause a DOM tree break on the browser?」,才又發現上面這段 code 並不是合法的 HTML5 (先不管 head & title 的部份,補上後仍然不是合法的 HTML5)。

原因在於 DOM parser 對 <script></script> 的特殊處理:「4.3.1.2 Restrictions for contents of script elements」。(話說這段 ABNF 差點讓我翻桌...)

解法是在 <script></script> 的開頭與結尾加上 HTML 註解:(這剛好是 HTML 4.01 建議的方法)

<!DOCTYPE HTML>
<html>
<body>
<script>
<!--
var a = "<!--<script>";
-->
</script>
</body>
</html>

那段 ABNF 的目的是希望可以盡可能往後找到 --></script> 結尾的地方。

當然你也可以用 json_encode()JSON_HEX_TAG<> 硬轉成 \u003c\u003e 避開這個問題,但這使得呼叫 json_encode() 時要多一個參數 (而非預設參數),用起來比較卡...

這個問題會變得這麼討厭,是因為 DOM parser 與 JavaScript 語法之間有各自的處理方式,然後又有些 pattern 是之前的 spec 遺留下來的包袱 (像是 HTML 4.01 在「18.3.2 Hiding script data from user agents」裡有提到用 <!----> 包裝 <script></script>),變成在設計 HTML5 時都要考慮進去相容...

之前會習慣用 <!--//--> 包裝 <script></script> 倒不是這個原因,而是因為不這樣做的話,jQuery 在 IE 使用 html() 時遇到有 <script></script> 的字串會爛掉,所以後來寫的時候變成習慣了...

反而因為這個習慣而避開了這個問題...

超難搞啊...

PSR-4

剛剛看到「Composer now supports PSR-4」才發現有 PSR-4,而且出了好幾個禮拜了...

PSR-4

This PSR describes a specification for autoloading classes from file paths. It is fully interoperable, and can be used in addition to any other autoloading specification, including PSR-0. This PSR also describes where to place files that will be autoloaded according to the specification.

在已經有 PSR-0 的情況下,設計 PSR-4 讓人感覺有點怪,因為功能跟 PSR-0 是衝突的。

不過仔細看看以後發現 PSR-4 規則比較「乾淨」,有種想要汰換 PSR-0 的想法... 而且 Composercomposer.json 的設計也允許針對不同的 prefix 使用不同的邏輯,看起來是把 PSR-0 當作過渡期的設計,希望大家換到 PSR-4?

PSR-0 與 PSR-4 最明顯的差異是對底線 (underscore) 解讀不同,在 PSR-4 中的底線沒有任何意義:

Underscores have no special meaning in any portion of the fully qualified class name.

在 PSR-0 裡則是說 class name 的底線必須換成 DIRECTORY_SEPARATOR:

Each _ character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR. The _ character has no special meaning in the namespace.

來想看看要怎麼轉換現有的系統...

Command Line 下把 Hex 轉成 Base64...

每次都忘記,寫一篇之後查比較方便... 重點在對 xxd 的變化應用,而 xxd 被包在 Vim 裡,所以應該都會裝... 吧...

xxd 預設是把 binary 轉成 hex,但你可以用 -r 參數變成反向,也就是 hex 轉 binary。

所以剩下的就很簡單了,先把 hex 轉成 binary 再轉成 base64:

echo 0123456789ABCDEF | xxd -r -p | base64

這邊有裝 Base64 所以可以直接用,如果沒有的話,可以用 OpenSSL 替代:

echo 0123456789ABCDEF | xxd -r -p | openssl enc -base64

可口可樂公司取得 Mac Address...

Slashdot 上看到「Coca-Cola Reserves a Massive Range of MAC Addresses」:

  FC-D4-F2   (hex)		The Coca Cola Company
  FCD4F2     (base 16)		The Coca Cola Company
				One Coca Cola Plaza
				Atlanta GA 30313
				UNITED STATES

可以從「IEEE-SA - Registration Authority MA-L Public Listing」這邊查到...

所以可口可樂公司想要做什麼... @_@

ESR 解釋 C 的 Compiler 對 Structure Packing 的處理...

ESR (Eric S. Raymond) 寫了一篇 C Compiler 對 struct 實際如何佔用記憶體空間的說明:「The Lost Art of C Structure Packing」,全文在「The Lost Art of C Structure Packing」。

以前都學過也都還記得,但沒用就不容易想起來...

以文章裡的例子用這個 struct 說明:

struct {
    char *p;
    char c;
    int x;
};

(下面就不列出 struct 的部份了)

實際上在記憶體裡面會因為 alignment requirement 的關係,多了一個 padding (pad):

char *p;      /* 4 or 8 bytes */
char c;       /* 1 byte */
char pad[3];  /* 3 bytes */
int x;        /* 4 bytes */

而如果 x 是 8 bytes 的 long 時:

char *p;
char c;
long x;

padding 會變成:

char *p;     /* 8 bytes */
char c;      /* 1 byte
char pad[7]; /* 7 bytes */
long x;      /* 8 bytes */

這是因為硬體架構的關係。有些是因為硬體只支援切齊 alignment 的存取指令,有些是因為效率的差異而預設會增加 padding。

在處理 protocol 這類必須依照原始的 struct 設計時,需要指定

#pragma pack

強迫 compiler 關掉,不然 compiler 還是會補上 padding。

而在一般的情況下,調整 struct 裡元素的位置就能夠在不影像存取效能的前提下節省空間,如果是大量的 struct 時效果就會變得很明顯...

GitHub 的 SSL (HTTPS) 也支援 PFS 與 AE 了...

GitHub 在 2013 年底的公告:「Introducing Forward Secrecy and Authenticated Encryption Ciphers」。

愈來愈多服務升級 & 調整 SSL (HTTPS) 的設定,支援 PFS (Perfect Forward Secrecy) 與 AE (Authenticated Encryption)。

PFS 要預防的事情我可以理解,但對 AE 的必要性不熟啊... 再去看看整個理論基礎與目的好了...

Zerigo DNS 換到 Akamai,然後漲價...

Zerigo 年底發了兩篇公告:

Zerigo 是好用在 GeoDNS 的服務上 (不用自己寫程式 & 更新 GeoDNS database,更不用自己做 HA 機制),一般的 DNS 服務到是還好... 漲了也只能接受啊,就當作換上 Akamai 後的成本調漲好了?(看了看,檯面上 GeoDNS 沒幾家好用的服務啊...)

繼續觀察看看吧...

原來 Adblock Plus 有 IE 版了...

在「Year 2013 in retrospect」這邊看 Adblock Plus 官方回顧 2013 年時才發現原來有 IE 版了:「Adblock Plus - Surf the web without annoying ads!」。

繁體中文版的預設值跟其他平台相同,都是 ChinaList+EasyList (完整的列表可以參考「已知的 Adblock Plus 過濾條件集」):

這是安裝後「Yahoo奇摩」首頁的樣子:

晚點來幫老人家電腦裝...