美國政府 NLRB 給出競業及禁止挖角條款違法的判決

在「NLRB judge declares non-compete clause is an unfair labor practice (nlrbedge.com)」這邊看到的,原始文章是:「In First Case of its Kind, NLRB Judge Declares Non-Compete Clause Is an Unfair Labor Practice」。

NLRB (National Labor Relations Board) 這次是針對 J.O. Mory 的判決,原始判決本來想連結到 NLRB 的網站上,但發現現在連不上,先給這份好了:「09031d4583d765f7.pdf」。

裡面有兩個面向的判決,一個是競業的部分,另外一個是禁挖的部分。細節可以直接看原文,或是直接丟 Google Translate 或是叫 ChatGPT & Gemini 翻譯都可以。

競業條款的部分不算太意外,因為整個州政府與聯邦政府都在修法大幅限制企業在合約上面可以設定的競業條款,不再讓自由市場機制決定勞工的工作權益 (通常是弱勢方)。

禁挖條款的部分是這次看到覺得比較新鮮的,認定違法的原因與禁業的部分類似,都是以會影響勞工的工作權益而宣告違法。

這塊應該是進行式,這幾年應該還是可以看到不同的判決出現...

實做 RSS/Atom feed 的最佳實踐

前陣子看到的文章,在講實做 RSS/Atom feed 的 best practice:「RSS Feed Best Practises」。

最簡單的當然還是丟個 Atom feed 就好,接下來就是一些延伸出來可以多做的事情。

首先有提到 discovery,可以讓 crawler 在抓到 HTML 頁面的時候知道 feed 在哪裡,這對於 user experience 來說蠻重要的,大多數的 feed reader 都可以透過這個方式抓到真正的 feed 位置。舉個例子來說,我丟 https://blog.gslin.org/ 進 feed reader,可以透過 discovery 的方式告訴 feed reader 我的 feed 位置在 https://blog.gslin.org/feed/

<link rel="alternate" type="application/rss+xml" title="Gea-Suan Lin&#039;s BLOG &raquo; Feed" href="https://blog.gslin.org/feed/" />

另外是常見的 cache 問題,這個設起來不算太難,主要是細節很多 XD

後面提到的 WebSub,以前叫做 PubSubHubbub,是一個在 feed 更新後主動通知讓 crawler 來抓的機制。不做的話也還好,現在的 crawler 現在都還蠻聰明的,會針對更新比較頻繁的 feed 常常去確認,但這樣總是會有一些時間差。

不過裡面好像沒提到 Update Services,這是比較早期的方法,走 XML-RPC,雖然也不知道現在有什麼用途了,大概就是這樣所以沒提...

一些不太容易注意到的 Python 安全性問題

前幾天看到「10 Unknown Security Pitfalls for Python」這篇,講 Python ecosystem 裡面的一些設計造成的安全性問題,裡面很多東西都很有趣,而且有些算是共通的,其他程式語言也會中獎...

第一個是開發者用 assert() 確認權限,但 assert() 的設計是 debug 用的功能,所以可以預期在 optimization 後會被拿掉 (其他程式語言也有類似的功能),而導致權限沒被檢查而產生 security incident。

第二個是 os.makedirs() 所指定的 mode,依照說明看起來是 Python 改變行為了,變成只有最終的那個目錄照著設定:

In Python < 3.6, the folders A, B and C are each created with permission 700. However, in Python > 3.6, only the last folder C has permission 700 and the other folders A and B are created with the default permission 755.

這個設計就有點討厭了,我測了一下 umask 077 的情況下在 shell 下執行 mkdir a/b/c,所有的目錄都會是 700

第三個是串檔名的 os.path.join(),遇到 / 開頭的部份會把前面的部份都拔掉,也就是這樣:(嗯... 這樣搞的嗎 XDDD)

>>> os.path.join('var', 'lib', 'tmp', 'abc.png')
'var/lib/tmp/abc.png'
>>> os.path.join('var', 'lib', 'tmp', '/etc/shadow')
'/etc/shadow'

第四個就是蠻標準的 variable injection 了。

第五個算是每次處理 .zip 檔都很頭痛的問題,不限於 Python,因為壓縮檔裡面可能會有 ../../ 開頭這種看起來就很邪惡的檔案名稱,只要有安全意識的工程師都覺得處理起來很麻煩的東西...

第六個一看就是壞東西,想要用黑名單擋 injection 一定會有更多有創意的方法打進來。比較特別的是這邊有提到在 Python 裡 re.search()re.match() 的差異,這點真的是寫起來有時後會忽略掉的...

第七與第八個都是 Unicode 相關的問題,也是個超級麻煩的東西,大原則是先 normalize 再 escape,但還是有點見招拆招去看...

第九個也是類似的問題,沒有先 normalize 再確認,不過一般機器都會有 private ip address,還是可以試著打... 這個有機會用架構面去解決,像是用 MQ 架設 proxy service,隔出另外一區來跑;或是已經有 zero trust 的架構,內部網路也是要帶 token 跑來跑去,可以減少一些傷害...

第十個算是 Python 自己的歷史因素,早期同時吃 &; 當作 separator,而非只吃 &x-www-form-urlencoded (HTML spec 內定義的標準):

In Python < 3.7 the function urllib.parse.parse_qsl allows the use of the ; and & characters as separators for URL query variables.

查了一下官方文件可以看到 3.10 之後才變成 x-www-form-urlencoded

Changed in version 3.10: Added separator parameter with the default value of &. Python versions earlier than Python 3.10 allowed using both ; and & as query parameter separator. This has been changed to allow only a single separator key, with & as the default separator.

有些應該是有安全意識時會去翻 spec 看看就可以避開的,但有些就真的是蠻雷的 XDDD

Simon Willison 提出來的 PAGNIs

Simon Willison 提出來「PAGNIs: Probably Are Gonna Need Its」,整理一下裡面提到的功能。

第一個是 kill switch,在 API 設計上一開始納入強制升級的傳回值,文章裡面有提到一些情境。

第二與第三剛好就是 Test + CI + CD,常常是 best practice,除了文章裡面提到的東西,在其他人的文章裡面應該也都有類似的討論。

第四是 API 的分頁,這個部份只講了要分頁,沒講到分頁時資料庫的效率問題,這部份可以參考「API pagination best practices」這邊的討論,key-based 的 pagination 效能會比較好,也可以避免對資料庫的 DoS 攻擊。

第五是 API 的 log,作者的建議是一開始什麼都存起來,等量大的時候再拔掉,會對於初期開發與除錯很有幫助。我是會掛 Sentry 這類的東西,有錯誤的時候會記錄起來。

第六看不懂他想要幹什麼,先跳過去。第七是在講要盡早實做這些 practice,等專案都推出去後再回過來實做都很花時間。

有些可以練手一下...

Shell Script 裡面 [ "x$var" = "xval" ] 的歷史

看到「What exactly was the point of [ “x$var” = “xval” ]?」這篇,在講為什麼不直接寫 [ "$var" = "val" ] 而是會加上 x 而寫成 [ "x$var" = "xval" ],被稱為 x-hack 的 workaround... (其實已經變成 best practice 了)

最常被拿出來講的是 - 開頭的字串,不過文章作者找到更多奇怪的 bug report,像是 () 之類的問題 XD

雖然作者提到大概在 2010 (或是 2015) 都修完了,但我應該還是會繼續這樣寫 (算是 best practice 了),可以避免在遇到老系統上遇到問題...

Bash Script 的好習慣

這篇給了一份 bash script 用的 tempalte,但更重要的反而是裡面提到的 best practice:「Minimal safe Bash script template」。

首先是不要寫 /bin/bash 這件事情,因為有些系統是沒有 /bin/bash 的,像是 FreeBSD

如果程式是可以用 POSIX sh 語法的話,應該優先考慮 /bin/sh,如果用到非 POSIX 標準的語法的話,用 env 帶出來會少一些問題:

#!/usr/bin/env bash

再來是 fail 時就趕快停止,不要再往下執行,這點算是老生常談了,文章作者也有給一個範例說明:

set -Eeuo pipefail

再來另外一個還蠻有用的事情是攔下常見的 signal 處理「後事」:

trap cleanup SIGINT SIGTERM ERR EXIT

cleanup() {
  trap - SIGINT SIGTERM ERR EXIT
  # script cleanup here
}

其他的可以看一看,但未必要全盤收下...

RFC 裡面的 MUST/SHOULD/MAY

讀 RFC 文件時常看到會使用這組定義,甚至有些非 RFC 文件也會使用:

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

這邊提到的 RFC 2119 就是 1997 年訂的「Key words for use in RFCs to Indicate Requirement Levels」這篇,以 2020 年的現在來說,這組定義已經被人熟知,用這組定義可以讓閱讀的人很輕鬆的了解條件的強制性。

剛剛在讀新的文件時發現這段文字有更新,往回查發現是針對大小寫的差異提出更新:「Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words」,主要是這兩條:

  • The words have the meanings specified herein only when they are in all capitals.
  • When these words are not capitalized, they have their normal English meanings and are not affected by this document.

然後也更新了引用的部份:

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

不過就算是 2017 年之前應該也是這樣讀就是了...

教你怎麼設計爛 API

看到「API Practices If You Hate Your Customers」這個,在講如果你不想給客戶用 API,或是你被迫要給,你要怎麼設計這些 API XDDD

作者在文章後面有把重點整理成一張表,你也可以先看再拉回去看感興趣的細節部份:

裡面超多奇怪的技巧,像是把文件藏起來不讓 Google 搜的到之類的都出現了 XDDD

然後我發現我在接某個印度公司的 API 的時候滿滿的既視感 XDDD

PostgreSQL 的 Don't Do This

Hacker News Daily 上看到的資料,整理了 PostgreSQL 上不要使用的功能:「Don't Do This」,而且是放在官方網域 wiki.postgresql.org 上。

裡面這些想法不知道出處是哪邊... 有不少功能算是 PostgreSQL 特有的功能 (以 open source RDBMS 這個領域來看),而且大概也還想的到用的場景,你卻在上面叫大家不要用,再寫的時候大概是吸了一批很純的,已經不知道要從哪邊開始吐槽...

要看的話連同 Hacker News 上的留言一起看會比較有前因後果:「https://news.ycombinator.com/item?id=19817531」。

FTC 找了七家 ISP 業者要研究隱私問題...

FTC 要研究 ISP 手上有哪些客戶的資料,然後提供給誰:「FTC Seeks to Examine the Privacy Practices of Broadband Providers」。

The Federal Trade Commission issued orders to seven U.S. Internet broadband providers and related entities seeking information the agency will use to examine how broadband companies collect, retain, use, and disclose information about consumers and their devices.

包括了這七家,裡面的六家都算大業者,被 FTC 納入不算意外,第七家包括了 Google Fiber Inc.,到時候不知道會有什麼資訊出來:

The orders were sent to: AT&T Inc., AT&T Mobility LLC, Comcast Cable Communications doing business as Xfinity, Google Fiber Inc., T-Mobile US Inc., Verizon Communications Inc., and Cellco Partnership doing business as Verizon Wireless.

看了一下 PDF,應該是 45 天後要回覆,加上整理的時間,應該是下半年會看到一些整理?