GET 與 POST 的差異

看到這篇在講 HTTP (& HTTPS) 裡面 GET 與 POST 的差異,剛好把一些標準的定義拿出來翻一翻,算是複習基本概念:「Get safe」。

第一個基本概念主要是 idempotence (& idempotent),重複被呼叫不會造成狀態的再次改變:

Idempotence ([...]) is the property of certain operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application.


An element x of a magma (M, •) is said to be idempotent if:

x • x = x.

If all elements are idempotent with respect to •, then • is called idempotent. The formula ∀x, x • x = x is called the idempotency law for •.

這點在 HTTP 標準 (RFC 7231) 裡面的定義也類似:

A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. Of the request methods defined by this specification, PUT, DELETE, and safe request methods are idempotent.

第二個基本概念是 Safe method (也是在同樣的 RFC 裡被提到),主要的思想是 read-only,這也是文章作者的標題要講的事情:

Request methods are considered "safe" if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. Likewise, reasonable use of a safe method is not expected to cause any harm, loss of property, or unusual burden on the origin server.

然後標準的 HTTP method 是有定義的:

   | Method  | Safe | Idempotent | Reference     |
   | CONNECT | no   | no         | Section 4.3.6 |
   | DELETE  | no   | yes        | Section 4.3.5 |
   | GET     | yes  | yes        | Section 4.3.1 |
   | HEAD    | yes  | yes        | Section 4.3.2 |
   | OPTIONS | yes  | yes        | Section 4.3.7 |
   | POST    | no   | no         | Section 4.3.3 |
   | PUT     | no   | yes        | Section 4.3.4 |
   | TRACE   | yes  | yes        | Section 4.3.8 |

不過文章裡面提到的第一個例子並沒有很好,POST 不保證 safe 沒錯,但不代表 safe operation 就不能用 POST。

這邊用 URI resource 的概念 (以及 SEO?) 或是用 Post/Redirect/Get 的概念來說明會比較好:

<form method="get" action="/search">
<input type="search" name="term">


“Log out” links that should be forms with a “log out” button—you can always style it to look like a link if you want.

“Unsubscribe” links in emails that immediately trigger the action of unsubscribing instead of going to a form where the POST method does the unsubscribing. I realise that this turns unsubscribing into a two-step process, which is a bit annoying from a usability point of view, but a destructive action should never be baked into a GET request.

這兩個動作都會造成 server 端的狀態改變,不應該用 GET,而我自己常常忘記第一個... 這邊其實可以用 form 產生 POST 需求,並且用 css 效果包起來,達到看起來跟一般的連結一樣。


Google 與 Cloudflare 測試 Post-Quantum 演算法的成果


其中 Google Chrome 的團隊與 Cloudflare 的團隊手上都有夠大的產品,兩個團隊合作測試的結果在學界與業界都還蠻重視的:「Real-world measurements of structured-lattices and supersingular isogenies in TLS」、「The TLS Post-Quantum Experiment」。

Google Chrome 這邊是使用了 Canary 與 Dev 兩個 channel,有控制組與兩個新的演算法:

Google Chrome installs, on Dev and Canary channels, and on all platforms except iOS, were randomly assigned to one of three groups: control (30%), CECPQ2 (30%), or CECPQ2b (30%). (A random ten percent of installs did not take part in the experiment so the numbers only add up to 90.)

這兩個演算法有優點也有缺點。一個是 key 比較小,但運算起來比較慢 (SIKE,CECPQ2b);另外一個是 key 比較大,但是運算比較快 (HRSS,CECPQ2):

For our experiment, we chose two algorithms: isogeny-based SIKE and lattice-based HRSS. The former has short key sizes (~330 bytes) but has a high computational cost; the latter has larger key sizes (~1100 bytes), but is a few orders of magnitude faster.

We enabled both CECPQ2 (HRSS + X25519) and CECPQ2b (SIKE/p434 + X25519) key-agreement algorithms on all TLS-terminating edge servers.


Adobe Security Team 直接把 Private Key 貼到網誌上面...

Security Team 出這種包...:「In spectacular fail, Adobe security team posts private PGP key on blog」。

Adobe 這次的事情要怎麼說呢,hmmm...

Facebook 與 Google Chrome 以及 Firefox 的人合作降低 Reload 使用的資源

Facebook 花了不少時間對付 reload 這件事情:「This browser tweak saved 60% of requests to Facebook」。

Facebook 的人發現有大量對靜態資源的 request 都是 304 (not modified) 回應:

In 2014 we found that 60% of requests for static resources resulted in a 304. Since content addressed URLs never change, this means there was an opportunity to optimize away 60% of static resource requests.

Google Chrome 很明顯偏高:

於是他們找出原因後,發現 Google Chrome 只要 POST 後的頁面都會 revalidate:

A piece of code in Chrome hinted at the answer to our question. This line of code listed a few reasons, including reload, for why Chrome might ask to revalidate resources on a page. For example, we found that Chrome would revalidate all resources on pages that were loaded from making a POST request.


We worked with Chrome product managers and engineers and determined that this behavior was unique to Chrome and unnecessary. After fixing this, Chrome went from having 63% of its requests being conditional to 24% of them being conditional.

但還是很明顯比起其他瀏覽器偏高不少,在追問題後發現當輸入同樣的 url 時 (像是 Ctrl-L 或是 Cmd-L 然後直接按 enter),Google Chrome 會當作 reload:

The fact that the percentage of conditional requests from Chrome was still higher than other browsers seemed to indicate that we still had some opportunity here. We started looking into reloads and discovered that Chrome was treating same URL navigations as reloads while other browsers weren't.

不過這次推出修正後發現沒有大改變:(拿 production 測試 XDDD)

Chrome fixed the same URL behavior, but we didn't see a huge metric change. We began to discuss changing the behavior of the reload button with the Chrome team.

後來是針對 reload button 的行為修改,max-age 很長的就不 reload,比較短的就 reload。算是一種 workaround:

There was some debate about what to do, and we proposed a compromise where resources with a long max-age would never get revalidated, but that for resources with a shorter max-age the old behavior would apply. The Chrome team thought about this and decided to apply the change for all cached resources, not just the long-lived ones.

Google 也發了一篇說明這個新功能:「Reload, reloaded: faster and leaner page reloads」。

當 Facebook 的人找 Firefox 的人時,Firefox 決定另外定義哪些東西在 reload 時不需要 revalidate,而不像 Google Chrome 的 workaround:

Firefox chose to implement this directive in the form of a cache-control: immutable header.

Firefox 的人也寫了一篇「Using Immutable Caching To Speed Up The Web」解釋這個新功能。


利用隱藏的 form input 加上自動完成功能取得敏感資料

anttiviljami/browser-autofill-phishing 這邊示範了怎麼用隱藏的 form input 與自動完成功能取得敏感資料。在這邊可以看到示範 (把 POST 丟到 httpbin 上看 response)。

想法不算困難,但好像也不是很好防... 關掉 autofill 是比較簡單的解法 (我是裝好瀏覽器就會關掉,不過好像很多人都喜歡用這個功能),所以這個問題就丟回給這些 browser vendor 想了 :o

NIST 開始徵求 Post-Quantum Cryptography 演算法

現有常見的幾個加密基礎在量子電腦上都有相當快速的解 (像是整數質因數分解、離散對數),只是現在建不出對應夠大台的量子電腦... 但畢竟只是時間的問題了,所以 NIST 照著慣例對外尋求能夠抵抗量子電腦的演算法:「NIST Asks Public to Help Future-Proof Electronic Information」、「Announcing Request for Nominations for Public-Key Post-Quantum Cryptographic Algorithms」。

類似於 Google 先前在 Google Chrome 上實做的 CECPQ1,對 key exchange 的部份加上保護 (Google Chrome 引入 CECPQ1,開始測試 Post-Quantum Cryptography),這次 NIST 是針對 public key crytpsystem 的部份而發的...

投稿時間在 2017 的十一月底,大約一年後就可以看到有哪些演算法要參加競賽了... 不過因為 NSA 的惡名,不知道會不會有其他單位在同個時段啟動類似的活動...

Google 測試 CECPQ1 的一些資料...

七月的時候提到「Google Chrome 引入 CECPQ1,開始測試 Post-Quantum Cryptography」,剛剛看到 Adam Langley 寫了一些數據出來:「CECPQ1 results」。

目前看起來對於網路速度不快的使用者會影響比較大,最慢的 5% 使用者大約慢了 20ms,最慢的 1% 使用者會慢 150ms:

Although the median connection latency only increased by a millisecond, the latency for the slowest 5% increased by 20ms and, for the slowest 1%, by 150ms. Since NewHope is computationally inexpensive, we're assuming that this is caused entirely by the increased message sizes. Since connection latencies compound on the web (because subresource discovery is delayed), the data requirement of NewHope is moderately expensive for people on slower connections.

由於實驗算是完成了,加上 TLS 已經有規劃了,所以 Google Chrome 打算拔掉這個功能等標準出來:

At this point the experiment is concluded. We do not want to promote CECPQ1 as a de-facto standard and so a future Chrome update will disable CECPQ1 support. It's likely that TLS will want a post-quantum key-agreement in the future but a more multilateral approach is preferable for something intended to be more than an experiment.

nginx 1.10.2

之前在「谈谈 Nginx 的 HTTP/2 POST Bug」這邊提到了 nginx 的一個 bug:「當 HTTP/2 的第一個 request 是 POST 時連線會失敗」的問題,這個問題在 mainline 版本的 1.11.0 解決了,但 stable 版一直沒有出新版 back-porting 回來。

而剛剛看到 1.10.2 將 http2_body_preread_size 從 mainline 版本弄回來解決了:「[nginx-announce] nginx-1.10.2」。

*) Change: HTTP/2 clients can now start sending request body
   immediately; the "http2_body_preread_size" directive controls size of
   the buffer used before nginx will start reading client request body.

然後剛剛發現 Ondřej Surý 老大分別弄出了 nginx (stable 版本) 與 nginx-mainline (mainline 版本) 的 PPA,所以也可以考慮可以直接換到 mainline 上?這樣也是個方法...


英國衛報華盛頓郵報因報導 Snowden 事件而拿到 2014 年的普立茲獎後,華盛頓郵報正式公開立場,表達應該將 Snowden 弄回美國受審,而非現在大家在呼籲的特赦:「WashPost Makes History: First Paper to Call for Prosecution of Its Own Source (After Accepting Pulitzer)」。

In doing so, the Washington Post has achieved an ignominious feat in U.S. media history: the first-ever paper to explicitly editorialize for the criminal prosecution of its own source — one on whose back the paper won and eagerly accepted a Pulitzer Prize for Public Service. But even more staggering than this act of journalistic treachery against the paper’s own source are the claims made to justify it.


The complication is that Mr. Snowden did more than that. He also pilfered, and leaked, information about a separate overseas NSA Internet-monitoring program, PRISM, that was both clearly legal and not clearly threatening to privacy. (It was also not permanent; the law authorizing it expires next year.)

這從來就不是合法的問題,而是侵犯人權的問題,合法的事情在事後甚至被制定憲法修正案而推翻的事情多的是。美國的女性在 1920 年才擁有投票權 (透過「美國憲法第十九修正案」)。


Google Chrome 引入 CECPQ1,開始測試 Post-Quantum Cryptography

Quantum Computer 對現有密碼學的衝擊很大,像是 RSA 演算法是基於「質因數分解」的難題而架構出來的系統,在 Quantum Computer 上存在有效率的演算法,也就是 Shor's algorithm

雖然 Quantum Computer 在技術上還沒辦法對現有演算法造成有效的攻擊,但已經有人提出新的演算法來對抗,而 Google 打算在 Google Chrome 裡面引入測試:「Experimenting with Post-Quantum Cryptography」。

Google 也特別說明了,他們不希望這個實驗最後變成 de-facto standard (借測轉出貨的概念),而是希望當作一個開頭,希望之後可以用更好的標準換掉:

We explicitly do not wish to make our selected post-quantum algorithm a de-facto standard. To this end we plan to discontinue this experiment within two years, hopefully by replacing it with something better.