隨意聊

有別於其他的長文,這裡都是比較隨意寫的短文。原本是發在臉書粉專,但都藏在臉書裡面有點可惜,索性搬一份到部落格來,對不用臉書的人也更友善。

共 101 篇 第 1 / 6 頁 RSS 訂閱

Linux 提權漏洞解析

今天剛看到 Linux 最新被爆出來的提權漏洞 CVE-2026-31431,又稱作 Copy Fail,利用方式簡單容易。

用白話文講的話,你原本把重要文件放左邊,白紙放右邊,讀完左邊文件之後,在右邊白紙寫下筆記。

但你有天突然覺得這樣很不方便,比起左右放,還是上下放更好,於是上面放白紙,下面放文件,結果白紙寫著寫著寫滿了,不小心多寫了一些字在重要文件上面,文件的內容就被修改了。就因為這個不小心,重要文件的內容被改動,就成了一個漏洞。

修法很簡單,不要把兩張紙上下放在一起就好,讀就是讀,寫就是寫,要寫就寫白紙上,不讓你寫到重要文件去。

技術細節的話,這個 bug 出在 Linux kernel 的 authencesn 功能,是拿來做加解密的。正常狀況下,你丟給他一段密文跟 key,他就會把解密的結果寫到 buffer 後還給你。

正常來講讀寫是分開的兩塊 buffer,但由於 2017 年的一個改動,讀跟寫的 buffer 指到了同一塊記憶體,然後 authencesn 的實作又被發現了一個 4 bytes 的 overwrite。

所以你先用 splice 拿到 /usr/bin/su 的 page cache reference,當成 input 丟給 authencesn,接著再利用那個 overwrite,就可以蓋掉 su 在 page cache 中的內容,等於是修改 su 的程式碼。

蓋完之後再執行 /usr/bin/su,就順利 root 了。

整個 exploit 的重點在於可以寫到任意的 page cache,所以把你想改的 program 用 splice 拿到 page cache reference 後,就可以丟給 authencesn 用 bug 去覆蓋 page cache。

最後修法是把那個 in-place 的改動拿掉,不讓你寫 page cache。

(我完全不懂 Linux kernel,技術細節是反覆看 writeup 以及與 AI 討論得出來的,細節必有不精確之處,有錯的地方歡迎留言指正,讓我多學習一些 Linux 知識)

身分證字號不是鍵

這兩天看到一個在講身分證字號的新聞,三年前台灣個資外洩的新聞爆發之後,有人因為這個去申請改身分證字號,被行政機關駁回後提起訴願,然後打行政訴訟,最後打贏了,可以更換身分證字號。

讓我想起以前看過的法律白話文運動的貼文,尾數是 4 或是含有三個以上的 4,也能修改身分證字號。

由此可見,身分證字號是會變的,所以存在系統的時候不要用這個當 key,否則會出問題。

還有另外一個理由是,身分證字號是有可能會重複的。

以前人工作業時抄寫錯誤等問題,導致同一個身分證字號可能出現在兩個人身上(隨手搜一下就很多資料了),就需要有一個人去改。

總之呢,身分證字號既不 primary 也不 unique。

參考資料:https://www.cw.com.tw/article/5140846

用 Agent 清理硬碟

話說 agent 是真的很方便
以前我電腦容量快滿的時候,不想去下載一堆感覺就不太安全的 cleaner,也懶得裝一些開源的軟體去掃

但有了 agent 之後,我現在都直接讓 agent 做了
就打開 cursor CLI 跟他說我空間快滿了,幫我找找哪些地方佔空間
他就會開始跑跑跑透過各種指令去看空間分佈

掃了大概 10 分鐘就給了份報告,跟我說 npm 的快取就 10GB 了,pnpm 5GB,Go 的也有個 2GB,Playwright 也有 10GB,超多版本的 Chromium 都在裡面,大概裝了二十個。

總之就是各種應用程式的快取佔了一堆空間,最後幫我分析哪些可以清掉,但最後清掉的指令跟刪除還是我自己來執行,他只幫我分析而已。

刪完再跑一次就跟我說少了多少空間,哪裡還可以在刪等等,真滴方便。

Claude 訂閱與工具限制

4/6 07:00 更新:

一早起來看到 Peter Steinberger 的推文,就算用 claude -p 只要你帶上 OpenClaw 的 system prompt 還是會被 ban,所以之前我的理解可能有些偏差,就算你自己 claude -p 給龍蝦用也還是不行(Peter Steinberger 原本也以為可以 😂)

雖然說只要把那段字串稍微改一下就會過,但官方的態度就擺在那裡。之後等等看有沒有個官方聲明好了,再繼續更新這篇貼文。

===

小聊一下 Claude 訂閱制把第三方工具 ban 掉這件事

如果我的理解沒錯,無論是 Claude 的訂閱方案也好,還是 Google Antigravity 的訂閱方案,使用規則都是一樣的,那就是禁止你把訂閱方案的 token 拿去其他非官方工具用。

其實最大的那幾間,所謂固定費用的「訂閱制」,本來就不是針對模型本身,而是針對產品,是讓你使用他們產品的時候可以用得更多,卻只需要付出固定費用。若是你有其他客製化需求,就是去接 API,一律使用 API key 的方案按量收費,否則就是違反使用條款。

Claude 的立場從以前就這樣了,上次對 OpenCode 也是一樣,不是不能用 Claude 模型,而是你不能用訂閱制拿到的 token 去使用,要用的話就要用 API key。

有用過的都知道,認真在用的話訂閱制一定是比 API key 便宜的,一些 AI 中轉站的原理就是這樣,背後有一堆訂閱制的帳號,然後把 auth token 拿出來轉成呼叫 API 的形式,用這些固定費用的帳號創造出更大的利益來賺價差(顯然不符合官方使用條款)。

雖然可以理解訂閱制與 API 的差異以及官方的考量,但身為使用者的我們當然還是想省錢,除了換個模型以外還有其他做法嗎?

有的,第一個是用 OpenAI 的 codex 訂閱方案,OpenAI 目前並沒有禁止把訂閱方案用在 OpenClaw 上面,所以我之前架小龍蝦來玩,第一件事情就是訂閱 codex 方案。

如果你是開發者想要寫一點自己的服務,那正解就是參考 Paperclip 的做法,與其接入 AI 模型,不如接入 AI agent。在 Paperclip 的模式中,他直接接入 codex 或是 Claude Code 等工具,幫每一種工具做一個 adapter,然後用 headless mode 跑起來。

換句話說,當你建立一個任務時,背後是直接去跑 claude -p “analyze this repo for security issues” 並把結果回傳。因此最後跟 Claude 模型的互動還是透過 Claude Code,這是完全符合規則的。

面一些論述的出處做為佐證。

參考資料:https://x.com/steipete/status/2024182608746217953

Blockly 翻譯鬧笑話

今天突然想查 Scratch 用的那套可以用類似拼圖的方式寫程式的東西叫什麼,我記得有人有開源出來,查一查發現 Google 開源了一個叫做 Blockly。

於是我就去官網看了看介紹,看到底下這段超級突兀:

「禁止使用網頁版」

我就想了想為什麼要禁止使用,還要當成一個功能來宣傳,把語言切成英文後恍然大悟:「Blockly for web」…

底下那個「為什麼要封鎖」,也理所當然的是「Why Blockly」。

真有你的,Google。

Claude Code 原始碼外洩

今天早上看到 Claude Code 原始碼因為 source maps 外洩的消息,我第一個反應是:「咦?難道以前沒有人試著還原過?」

Claude Code 的程式碼雖然沒有開源,但其實就是個 13MB 的 cli.js 檔案,俗話說的好,client 端的東西沒有秘密,而且還是最容易還原的 JavaScript,那以 Claude Code 這麼有名的東西來說,不可能沒人研究過吧,怎麼就變驚天的重磅消息了,好像知道了許多以前不可能看見的東西。

經過了一整天的思考,這想法其實半對半錯,聽我娓娓道來。

先來講講 source maps 是什麼,前端的程式碼需要用 bundler 打包在一起,打包完之後會做 minify 跟 uglify 等操作,去掉所有多的空白、換行,然後把變數名稱都變成 a,b,c 那種可讀性低的格式,最後的產物才會傳上去。

但既然程式碼可讀性都變這麼差了,要 debug 的時候怎麼辦呢?這時候就需要把這些 minify 過的程式碼還原成原本的樣子,靠的就是這個 source maps 的檔案,裡面記錄著原始的程式碼以及對應關係,靠這個檔案就能對應出原本的 a2 其實是 API_URL 這個變數。

所以若是 source maps 裡面記錄著檔案路徑以及內容,這個檔案洩漏就等於是原始碼洩漏了,這就是此次 Claude Code 發生的事故。一般常見的做法是 build 完一樣產生 source maps,但是不上傳到外面,只上傳到 Sentry, Datadog 等專門做錯誤處理的地方,在那邊還原,就能確保原始碼不外洩,又能方便 debug。

這邊再提一個概念,有些人會把 minify 跟「混淆(Obfuscate)」混在一起,這兩個概念不一樣。混淆指的是特地把程式碼再轉換一層,你光看是絕對看不懂的,惡意軟體就常幹這種事。而 minify 更像是把程式碼的體積縮小,你認真看還是能大概看出它在幹嘛,我看過很多遍了。

所以,Claude Code 大部分的功能,你根本不需要 source maps,你直接拿 AI 丟給他 cli.js(或先稍微處理過),他就可以回答你了,該有的邏輯都在那邊。

那到底有哪些東西會在打包的時候被去掉,讓這些資訊徹底消失呢?最顯而易見的就是變數名稱、函式名稱、檔案路徑等等,以及最重要的:註解。

程式碼裡面的註解在打包後會完全被去掉,而 source maps 裡面則被保留。以及另一個我朋友提醒我才想到的:dead code。

Dead code 指的是永遠不會被執行的程式碼,例如說 if(false) { … },這段永遠不成立。那為什麼有人會寫出這種程式碼呢?通常原始形式其實是這樣:if (Flag.Internal) { … },然後在 build 的時候把 Flag.Internal 換成 true 或 false,藉由 feature flags 的方式在 build time 開關,藉此 build 出不同的版本。

如果 Flag.Internal 是 false,那最後的產物就會直接把程式碼去掉。但是呢,由於 source maps 保存的是原始檔案的整個內容,因此這些 dead code 還會在。

總而言之,這次外洩的 source maps 跟原先打包後的版本比起來,多了以前絕不可能看到的註解與打包時被移除的 dead code,也還原了變數名稱與檔案路徑。

換句話說,很多人寫的什麼「Claude Code 的隱藏功能」也不是真的隱藏,只是大家懶得去看打包後的版本而已。

之所以我敢寫得這麼肯定,是因為我去試過了。外洩的版本是 2.1.88,我抓的是 2.1.87,我先讓 AI 幫我研究 Bun 的 bundler 邏輯,然後寫一個 reverse 版本,先把 cli.js 還原成 50 個小檔案,然後讓 AI 再根據這些檔案幫我還原成合理的形式。

接著我讓 AI 整理幾篇網路文章提到的隱藏功能,讓他去找找在不在程式碼裡面。

關於那些註解、內部代號或是特殊 flag 才能開啟的功能,確實不存在。例如說什麼內部代號 Capybara、Fennec、Numbat 等等,還有 Undercover Mode 跟反蒸餾防禦,這些都找不到。

但是今天上線的 BUDDY 電子寵物系統、KAIROS、ULTRAPLAN 或是記憶管理、壓縮邏輯等等,這些都是有的,本來就存在了。

所以呢,如果有人有心想研究的話,Claude Code 的這些運作邏輯一直在那,事實上也有人逆向過了,這些都不是新鮮事,只是大家懶得去做而已。那些 prompt 啦,記憶系統啦,agent 協作啦,bash 的檢查啦,憤怒語言偵測器啦,不需要 source maps 外流你就看得到。

真正全新的東西是那些註解裡面寫的經驗、內部代號以及 build time 被砍掉的隱藏功能,這些確實是只有透過 source maps 能看到的。

寫了這麼多,我只是好奇心使然,想去探索到底有哪些東西是新的、真的外洩的,哪些東西又只是「你想研究一直都在,只是現在不用自己還原」,也順便測一下 AI 的能力(還原 bundle 過的程式碼)。無論如何,原始碼外洩對於想研究的人絕對是利多,不用自己去試著還原或是猜測,有原始碼什麼都好辦。

或許在某個平行時空,有個好奇的人辛辛苦苦逆向了 Claude Code 把架構還原,準備跟大家分享成果,結果一覺醒來發現原始碼外流了,每個人用 AI 產的文都跟自己苦心研究的成果類似,只能躲回被子裡哭。

Trivy 供應鏈攻擊

剛好整起事件都有跟到,來聊一下 Trivy 跟最近的大規模供應鏈攻擊事件。

Trivy 是個資安公司 Aqua Security 出的開源掃描工具,最常用的是拿來掃 IaC 的程式碼或是 image 之類的,我自己就用過不少次。

在 2 月底的時候 Trivy 的 GitHub 被攻擊,因為 CI 流程有漏洞,所以發個 PR 就可以偷到 token,這類攻擊通常被叫做 Pwn Request,以前也出現過不少次,而這次的攻擊其實不只有 Trivy 受害,一堆 repo 也被攻擊了。

攻擊的帳號叫做 hackerbot-claw,跟上了前陣子正熱的小龍蝦熱潮,我那時看到消息還想說是不是哪個資安研究員在做研究 😆

過了幾週,到了 3/19 左右,駭客正式發起攻擊,透過 2 月底偷到的 token 直接幫 Trivy 發個含有惡意程式碼的新版本,甚至更狠地還把舊的 tag 全部都 push 一遍。

有些人已經有意識到這類型的供應鏈攻擊風險,在使用一些套件時會寫死版本號如 trivy@1.2.3,這個通常是沒問題的,因為許多 package manager 會保證版本不可篡改,例如說 NPM。

但是 GitHub Actions 沒這功能,他的版本只是一個 tag,背後東西是可以換的。所以你在使用 action 時寫死 tag 也沒用,要寫死 commit hash,這我也是今天才知道的,之前沒注意到這個差異。

看到這邊我相信大家都有個疑惑的點,那就是為什麼二月底被駭,理論上已經清理過一輪了,怎麼 3 月底又來一次,而且還是用二月就被偷的 token。

官方聲明是這樣寫的:We rotated secrets and tokens, but the process wasn’t atomic and attackers may have been privy to refreshed tokens

具體是什麼狀況沒講,但總之應該就是換的時候沒換好,導致攻擊者也能拿到新的 token。雖然說大家都會犯錯,但是一個資安公司連錯兩次,客戶對他們的信任度可能掉了不少…

總之呢,開頭提過 Trivy 是掃描工具,所以一堆專案都有裝這個,那自然也一堆專案直接被入侵。為了安全裝了資安掃描工具,卻因為裝了這個被入侵,有點諷刺。

而目前最新的受害者是今早才爆出來的 Python 套件 LiteLLM,被入侵的管道就是之前 Trivy 被駭的時候偷到了maintainer 的 token,就利用了這個 token 發布惡意版本。

就是巢狀供應鏈攻擊啦,先打下一個套件,再打下用這個套件的套件,以此類推,越打越多,影響也越來越大。雖然說 LiteLLM 有問題的版本已經被快速下架,但是大多數人(包含我)都猜測攻擊還沒停止,一定會有下一波的到來,請大家多多注意。

防範的方式還是老樣子:

  1. 安裝套件的時候永遠固定版本
  2. 承上,在某些版本不是 immutable 的情境下要固定 hash(如 GitHub Actions)

如果要安裝的專案是別人的,別人沒有寫死的話,也建議加減裝個 socket 之類的,在下載後似乎會先做一些基本掃描,也算是多少有防到。想更安全的話就是在 VM 或是 docker container 裡面裝,至少能保證影響範圍有限。

話說單個套件被打就已經這麼恐怖了,何況是整個 package manager 都被打下來。之前在 DEVCORE CONFERENCE 2026 聽到 splitline 的議程,就是在講直接去把整個 package manager 打下來,而且成功了不少,涵蓋一堆程式語言。簡報要四月底左右才會公開,到時公開了再來分享一波。

參考資料:https://snyk.io/articles/poisoned-security-scanner-backdooring-litellm/

把 DOOM 藏進 DNS

剛看到一個國外的資安工程師 Adam Rice 因為太喜歡 DNS 了,所以乾脆把 DOOM 毀滅戰士放在上面,只要依序解析 DNS TXT 紀錄就可以抓下來跑 😆

先來講講 DOOM 毀滅戰士這個遊戲,如同原文所提到的,一堆神人會在各種地方試著把 DOOM 跑起來,例如說有數位螢幕的驗孕棒或者是電動飛機杯之類的。

而 DNS TXT 紀錄本質上就是個字串,每條紀錄可以放 2000 個字元左右,所以把 DOOM 的主程式壓縮一下再轉成 base64 約 3MB ,作者用了將近 2000 條 DNS 紀錄把它給放進去。

最後,只要寫個 PowerShell script 去解析 DNS 拼接成一個大字串,在記憶體裡面解碼然後解壓縮,就能直接把 DOOM 跑起來,做到檔案不落地,直接在記憶體裡面跑。

更多技術細節在原文,然後原始碼也有開源到 GitHub 上。

Coupang 外洩與金鑰

今天從技術的觀點來聊前陣子沸沸揚揚的 Coupang 個資外洩事件。

其實已經寫一篇完整的部落格文章了,懶得看全文的話,就看我這篇精簡版吧。

Coupang 是個韓國電商,在台灣也有設點,去年發生個資外洩事件,韓國那邊的調查已經告一個段落,而近期因為台灣也有受影響,所以數發部介入,目前劇情大概到這裡。

相關的技術細節韓國的報告寫得很清楚,這整起事件的攻擊者並非外部駭客,而是一個離職的前員工,而且還是開發備援 auth 系統的 Staff Back-end Engineer(但他做這件事的動機新聞跟調查都沒寫)。

Coupang 的驗證系統在登入過後會發一個類似 JWT token 的東西,直接在裡面帶上會員 id 之類的,下次就只驗這個 token 是否合法。因此,只要能拿到簽這個 token 的 key,就能偽造任何人的身份,不用登入就獲得相關權限。

而這個離職員工就是利用這種方式,還在職時拿到了這把 key,偷偷帶走,離職後拿來偽造出 token,就能進入 my information 之類的頁面看到個資。

所以呢,這整起事件就是負責開發 auth 系統的主任後端工程師,在離職後用在職時取得的 auth 系統 signing key 搞出來的。

接著可以從兩個角度聊,一是 key 該怎麼管才安全,二是這種驗證方式本身是不是有點問題。

管 key 的話,有很多公司都會用 vault 或 secret manager 之類的東西管,然後讓 SRE 或開發者自己產一把 key 放進去。雖然說放到 vault 後取用是安全的,但產 key 的時候已經有幾個人知道了。雖然說 insider 的風險跟其他比沒這麼高,比較容易被查出來,但若是發生了,外部也不會管你到底為什麼出事。

所以不只是儲存跟使用,在產生 key 的時候也要注意,最安全的是用 HSM 儲存 key 外加 KMS 管理,key 本身從不離開這個系統,但相對的成本也會高一點。

也可以先從 key rotation 做起,當這些能碰到的人離職時,把能碰到的 key 都先換過一輪,雖然在職時還是能碰到 key,但至少讓他們離職後自動喪失所有權限。

再來,key 被偷就整個 auth 系統 gg,聽起來似乎不太合理。

以傳統 session 做法來說,你保存一個 session id,每次後端查表,session id 若是不可預測,你拿到 signed cookie 的 key 也沒用。JWT 其實也是,你如果在 token 裡存的是 session id 也一樣。

但現在許多系統 JWT 是存 session data 的,裡面直接放 email 或 user id 這些可預測的東西。在這個前提下,保護 key 就變成非常重要的一件事情,而且 private key 跟 public key 都要保護。前者保證不被洩漏,後者保證不被置換。

我相信有許多公司在產 key 這段多少都有點問題,許多都是我前面說的,由人產完再放進去 secret manager。況且也沒這麼多公司有資源專門去弄個 KMS(或甚至沒想到可以這樣或需要這樣做)。

這些都是風險,都會回到風險管理的框架去討論,不少公司目前選擇的是接受風險,亦即承認風險的存在,但因發生機率小所以先不處理。若是真的有哪個能碰到這些的離職員工偷偷帶了一份資料走,那類似的事情很可能又會重演。

總結就是:

  1. key 的完整生命流程要注意,尤其是產生的時候
  2. 使用 stateless JWT 有個風險是 key 被偷走就 gg,要記得
  3. 考慮風險時,除了外部攻擊者,也要考慮 insider threat

看完想知道更多細節的話,可以再回去快速看過部落格完整版

補充文章:https://www.msit.go.kr/eng/bbs/view.do;jsessionid=iMyzX8C42zedbf27PtWxq844qjcyYy0VOCt74FEO.AP_msit_2?sCode=eng&mPid=2&mId=4&bbsSeqNo=42&nttSeqNo=1221&utm_source=perplexity

這裡不是 AI 洗稿場

不好意思,你找錯地方了

這裡不是接入 AI,自動搜集新聞,自動改寫文章洗稿抄襲的地方

你找錯地方了

這裡不是視著作權於無物,直接翻譯國外文章或影片然後全文轉貼,又不附出處的地方

你還是找錯地方了

這裡不是用 AI 寫一堆故事,下聳動標題,不查證真實性,只管故事本身能否吸引流量的地方

你真的找錯地方了

這裡不是一直說自己 AI 用得有多厲害多跟別人不一樣,然後賣你課程的地方

就跟你說你找錯地方了

這裡不是每天發一堆 AI 新聞,每天都分享人類文明的重大突破,販賣焦慮的地方

喔喔喔,這次你總算找對了

這裡是想不出聳動的吸引人的標題、跟不上時代,就算寫得比 AI 差還是遵循古法手工製造的,我一個人發廢文的地方

GlassWorm 木馬攻擊

最近有認識的朋友中了木馬,本機 token 被偷光以後,直接往 GitHub 上的 repo 推了惡意程式碼,因為好奇就跑去稍微看了一下。

推的 code 是一段 JavaScript,會在 postinstall 的時候執行,惡意程式碼本身是用 unicode 的不可見字元,再寫一段 JS 還原然後丟給 eval,所以把 eval 改成 console.log 就能看到跑了什麼。

而這段程式碼解出來之後,是一段用 AES fixed key 解密另一個 payload 再丟一次 eval 的程式碼,所以要再改成 console.log 跑一次。

跑完之後還沒結束,會看到一段去呼叫 blockchain 的 API,從 Solana 的某個固定地址拿 memo,拿到的內容是一個 IP,接著連線到 IP 之後又拿一段 payload 回來,再丟到 eval。我連過去的時候被擋掉了,所以也沒看到具體 payload。

上網查了一下發現這是個叫 GlassWorm 的已知木馬,專門打開發者的,透過 VSCode 的擴充套件打進來。而我朋友中的這波是上週才發生的最新一波攻擊。

這次的攻擊是先發佈一些看似無害的套件,接著在升級時偷偷在 manifest 裡面加上惡意的 dependency,升級後 VSCode 就會自動下載,然後就中招了。

中了之後就會把你電腦裡的東西都偷過一輪,然後再去感染其他人。就像我開頭講的那樣,直接把你有權限的 GitHub repo 都 push 一遍,若是有哪個觸發 CI 甚至自動發版了,那就又擴散出去了,因此才會稱為是 worm。

這類攻擊感覺一直不斷發生,無論是 NPM 的 supply chain attack,或是針對 VSCode 套件本身的攻擊,都是專門打開發者,一不小心的話很容易中招。

也因為如此,我自己的 VSCode 幾乎都不安裝套件了,只裝官方而且夠大的,其他就算了。也把自動更新都關掉,避免新版帶奇怪的東西進來。

話說,現在好像越來越多人直接 CLI 寫 code,甚至連 editor 都不用了,因為寫完不用看直接上,其實也算是某種程度防範了這個風險 😆

不過取而代之的就會是一些惡意的 MCP 或 skill 等等,不小心跑了也一樣會有事。相關報導跟這次中招的套件,大家可以自己檢查一波。

Snaps 簽交易漏洞

在加密貨幣的世界中,MetaMask 大概是最知名的軟體錢包了。而 MetaMask 除了本身提供的那些功能以外,還提供了叫做 Snaps 的 plugin 系統,可以讓開發者在 MetaMask 上面新增功能。

MetaMask 是瀏覽器的 plugin,然後本身又提供了 plugin,一層疊一層,厲害吧。

那有什麼功能會需要往 MetaMask 上面加呢?

舉例來說,有些 blockchain 用的技術沒有被 MetaMask 原生支援,因此這些鏈如果想做錢包的話,要嘛自己再做一個新的擴充套件,要嘛用 Snaps 加到 MetaMask 上。

由於 MetaMask 實在是太多人用了,因此大多數人都選擇後者,做一個 plugin 來幫它加功能,讓它支援更多種不同的 chain,例如說 MetaMask 背後的公司 Consensys,就做了個給 Starknet 用的 Snaps 錢包,讓大家可以在這上面使用 Starknet。

今天有份漏洞報告被揭露,有人發現這個 Starknet Snaps 在發起交易時,支援一個叫做 enableAuthorize 的參數,正常狀況下是 true,MetaMask UI 就會顯示確認視窗。

但如果這個參數傳 false,就不會顯示確認視窗而是直接 sign transaction。換句話說,如果有人不小心在某個網站上連接了 Starknet Snaps,在連接之後攻擊者就可以直接用這個參數繞過確認,在使用者不知道的狀況下發起交易,進而把裡面的錢偷走。

而這個「連接」就像是你在網站上要使用 MetaMask 錢包會跳出的視窗一樣,不是個太敏感的操作(我認為啦),網站要拿錢包地址也需要先連接,否則什麼都拿不到。這個連接跟授權交易完全是兩回事,前者雖然要使用者點擊,但門檻低。

總之呢,假設我做了一個 Dapp 跟大家說來連接 Starknet Snaps 就送獎金,只要連接拿地址登記就好,散佈出去,若是有人裝了這個 Snaps,在點擊連接後就能自動幫他簽交易把錢偷走。

問題來了,這樣的漏洞嚴重程度是多少,賞金又是多少呢?

答案是 medium 以及 350 塊美金 😆

原本 Hackerone 的人員還評估成 low,之後是 Consensys 的人改成 medium,但我怎麼看至少都應該是 high 才對。

官方給的理由是:

  1. 使用者必須有裝Starknet Snap
  2. 使用者要 connect
  3. downstream dApp behavior for financial impact

第一點簡直是聽君一席話如聽一席話的典範,我不就是回報這個程式的漏洞嗎。

第二點我上面講過了,我覺得門檻沒這麼高。

第三點我就沒有看懂了,不知道是不是我對 Starknet 了解有誤?在我的認知中,只要能簽交易就能偷錢了,我自己做個惡意 dApp 不就好了嗎?難道不是?

總之,在我反駁之後官方沒有繼續給回覆,我就請求公開漏洞了,官方還是沒回覆,因此現在一個月後自動公開。他們很多漏洞都沒公開的,我猜他們可能連看都不看根本不 follow 了,也沒有管後續 😂

喔,對啦,那個回報的人就是我,碰巧看到的洞而已。,歡迎一起來看看報告。

然後另一個我覺得滿值得聊的是 CVSS 對於 Web3 的適用程度,我都可以偷錢了,結果拿 CVSS 給我評個不影響 confidentiality 跟 availability,然後 integrity low。

你要這樣講不是不行啦,我只能簽交易確實可能不影響那些,但這個洞怎麼看都不會是 low。這代表在 Web3 相關的情境下,針對傳統漏洞的 CVSS 沒辦法很好的判斷嚴重程度,沒有把資產損失這點考慮進去。

而大多數時候我也不會看到有人硬要把 CVSS 拿去套那些加密貨幣的漏洞,至於 hackerone 為什麼堅持這樣,我也不知道 😑

AI 軟體開發第三時代

早上看到 Cursor 的部落格發了一篇文章《The third era of AI software development》,裡面把 AI 軟體開發分成三個時代,覺得滿贊同的來聊一下,順便寫一下上次提的用 AI 做逆向工程的心得。

第一個時代是 Tab 自動補完,也就是最早期的 GitHub Copilot 在幹的事情,當初 Cursor 剛出來的時候也是這功能。

第二個時代是 AI agent,也就是現在大部分軟體工程師都在幹的事情,讓 AI agent 幫你寫 code。在一年前的時候,使用 Cursor tab 的人是 agent 的 2 倍,而現在已經顛倒過來了,我自己也很少用 tab 了。

而第三個時代就是我上週提過的 Cloud agents,本地用 agent 有其限制,例如說某些資源還是共用,同時也沒辦法真的開到太多太多 agent,還是一個我認為滿重要的限制是「你要有台電腦」。

而 Cloud agent 就是最理想中的形式,你只要在 web 介面上說一句話,背後就有 agent 去幫你開發,跟在本機電腦一樣。幫你開發完測完之後,你去 review 就好。

這個第三個時代的轉變,讓我們脫離了「一定要有電腦」這個限制,你在下班回家的捷運上突然有個 production issue,打開 cloud agent 叫他分析 log 然後把 bug 修掉,發 PR、merged、deploy,可能你還沒到家事情就解決了。

其實已經有不少人現在就是走這個開發模式了,大多數我看到的是一些熱情投入 AI 的個人開發者,至於公司的話,之前提過的 Stripe 就是,一定還有別的公司也是只是我懶得找。

不過第三個時代的門檻較高一點,你要先把開發環境準備好,而且還要同時有多個,不像第二個時代你都跑在自己電腦上,自己建好就行。或許再過個兩年,大多數人都會進入第三個時代,把大部分開發都丟到雲端去,隨時隨地都可以 coding。

想先體驗這個時代會長怎樣的,現在就可以找一些工具來用了(如上次介紹的 Cursor cloud agent),這是現在就做得到的事情。某個層面有點類似 OpenClaw 小龍蝦那樣,你給他環境跟機器,下指令他就會做事。

最後來寫一下用 AI 逆向工程的心得,我對逆向工程幾乎沒研究,除了學生時期修組合語言的時候,期末 project 做的是逆向某個小軟體,把 jmp 改成 nop 以外,就沒碰過逆向了。

這次因緣際會拿到一個 Golang HTTP server 的 binary,想說來試試看現在結合 AI 可以做到什麼地步。一開始我直接先召喚 agent 出來,它就先用 strings 去猜各種字串,最後撈到一些參數跟 URL,其實也滿有用的。

但這樣還不夠,於是我裝了個 Ghidra MCP 再裝了個專門分析 Golang 的 plugin,再搭配我平常在用的 Cursor,直接在上面跟他說「幫我逆向這個程式並給我一份報告」,他就產出了一份報告說明這是什麼東西,然後把 API endpoints 都列出來。

那時我可以感受到跟外行 vibe coder 相同的喜悅,也就是「我以前認為這麼困難的領域,沒想到靠 AI 就能讓我產出成果,AI 太神啦」,不過我對逆向工程還是抱持著一顆敬畏的心,依舊佩服那些會這個技能的人。同時,我也不覺得 AI 在這件事情上可以完全取代人類,AI 逆向出來的結果有些是錯的,有些也有幻覺,還有進步空間,我給的也只是隻小程式,沒試過更複雜的。

詳細的心得跟步驟昨天寫在部落格了,有興趣的可以看一下。總之呢,心得就是 agent + MCP 組合技真的好用,大力推薦。

雲端 Agent 開發時代

現在業界對於 AI coding 的使用,到底是怎麼個用法呢?剛好最近看到一些可以連起來的東西,簡單寫一下。

金流服務 Stripe 最近發了一篇文章,介紹他們自己打造的內部工具 Minions,你可以直接從 Slack 上面 tag 他,跟他說要做什麼,他就會自己起一個環境(內部叫 devbox,一個 EC2 instance 上面已經把環境弄好 ),把任務完成之後發 PR 讓你 review。

然後他們用的 coding agent 是從開源專案 goose fork 出來改的,看來大公司還是有挺多東西需要客製化的。

在兩三年前雖然也有這種概念(AI 軟體工程師如 Devin),但在當時看來我還覺得有點遠,模型還沒這麼厲害,但是在 2026 的現在,是 100% 可以做到的東西,更是有些公司內部已經在使用的服務。

但不要看 Stripe 做得到,就以為每間公司都行,要這樣做至少要有兩個前提:
(1) 你的測試要足夠
(2) 你要能把環境建起來

Stripe 是因為本來就有很多測試,所以 AI 改壞可以自己修,直到測試通過為止,人 review 的時候可以減少很多心智負擔,因為 test coverage 夠齊全,至少不會歪到哪去。

但很多公司連測試都沒有,想這樣做要嘛工程師花些心力 review,要嘛相信 AI 足夠強,直接勇敢按下 merge。

剛好這兩天 Cloudflare 宣布他們用 AI 花了一週把 Next.js 遷移到 Vite 上面,然後只有一個工程師在負責指揮,就搞定了。

在他們的文章中也有清楚提到,這次遷移能順利的理由是完整的 AI 文件以及全面的測試案例,否則不可能這麼順利。這個再次強調了測試的重要性,當你的測試夠強,就能讓 AI 自主工作變得更有效率。

現在已經很多人直接 claude code 或其他 AI agent,跑一次就把任務完成了,而 Stripe 那種模式可以想成把你的本地環境搬一份到雲端,就可以享受隨時隨地叫 AI 工作的快感。

那如果你也想體驗這種快感該怎麼做呢?

剛好這兩天 Cursor 的 Cloud Agent 改版,它就是一套雲端的 agent,我已經體驗過了,感覺很不錯。

把 GitHub repo 權限開給他以後,agent 會自己從 repo 中去探索怎麼把服務跑起來,然後還會錄影片給你證明它完成了。若是 agent 卡住,你可以中斷它然後幫他操作,這邊是直接有一個雲端桌面可以操控,一個 Xfce 的 Linux 環境。

比如說像我的專案需要登入,在 setup 過程中 agent 發現後就自動在 setup 區塊說他需要帳號密碼,直接多了兩個輸入框出來讓我填。

在環境配置好以後,就會存 snapshot,之後每個任務都只要出一張嘴,agent 就會自己把環境跑起來,然後完成你交代的任務,之後發 PR 等你 review,就像是 Stripe 的文章中所描述的那樣。

整體的體驗滿不錯的,專案建置上沒什麼問題,Electron 它也跑得起來。只是在操控上面因為是用 computer use 所以滿燒 token,我今天讓它試著在 desktop app 上做一個新功能,大概花了 30 分鐘,燒了 2000 萬個 token,似乎是 10 美金左右。

未來 cloud agent 我猜也會越來越普及,只是在資安以及環境建置這塊要怎麼處理會比較麻煩(例如說有些服務在公司內網),但用起來感覺不錯就是了。

總之呢,從我自己的日常開發以及這些大公司的部落格中,很明顯可以看到軟體工程師把任務交給 AI 跑已經是常態了,不要再用什麼網頁版,你用 claude code 也好 open code 也好 Codex 也好 Cursor 也好,反正有個 agent 可以幫你跑任務就對了。

我自己日常開發還是用 Cursor,下次再寫一篇我最近怎麼用 Cursor 搭配其他工具,幫助我這個外行人逆向一個 golang binary 吧。

用 CSS 寫出 CPU

有寫過網頁的人可能知道 CSS 很厲害,可以用純 CSS 來寫遊戲,無論是 2D 或 3D 的都行。

但我今天看到了個更厲害的,用 CSS 寫了個 x86 CPU 模擬器!把 C compiled 變成 machine code 之後,可以把它交給 CSS 去跑。

有點類似於有些人在 Minecraft 裡面也會搞出一台電腦或是 CPU,不過弄在 CSS 上從我的角度看來是更厲害的,因為它能用的東西更少一點。

至於原理的話,作者之後會寫個部落格談談自己用到哪些技巧,目前看起來是受兩年前另一篇文章《Expert CSS: The CPU Hack》的啟發,透過 animation + keyframe 為基礎去弄出一個 loop,剩餘的就是一堆計算跟儲存了。

補充文章:https://garethheyes.co.uk/

手機定位與 AI 洗稿

剛剛在讀一篇之前存起來的文章《Your Phone Silently Sends GPS to Your Carrier — Here’s How》,內容大意是手機的組成分成兩塊,一塊是應用晶片(Application Processor, AP),大家常用的 iOS/Android 都在這上面,另一塊是基頻晶片(Baseband Processor, BP),負責處理 2345G 那些手機原有的通訊功能。

而 BP 上有個 protocol(RRLP/LPP)可以讓電信商拿到你的 GPS。由於是在 BP 上,所以不是 Android 跟 iOS 這些應用層可以干涉到的,就算你把什麼權限都關了也沒用,它是直接從更底層去拿的。這功能的本意是在緊急狀況時能夠有方法定位到手機,因此有了這個協定,但既然這功能是存在的,就代表會有被濫用的可能性。

文中有舉了一些例子,例如說在美國經過法院許可之後就可以跟電信業者去申請(不過標準不太統一)以及美國電信業者之前出售 GPS 資料的新聞等等,還有以色列在疫情時也運用手機定位去做隔離。

文章最後則是提到 Apple 從 iPhone 16e 開始自己做了 BP 的晶片(C1 Modem),所以可以突破 AP 跟 BP 間的隔離,提供了針對位置隱私的防護措施,能夠限制可以取得的數據。

看完之後,我第一個想到的是中華電信在疫情時也有過類似的新聞,查了一下說是透過基地台定位,沒有提到更具體的技術:

利用手機和基地臺之間的相對位置概略定位,電信業者定時監測手機所連接的基地臺

以色列當時所做的類似措施,也沒有提到具體技術,所以也不知道是透過基地台去定位,還是真的用了前面提過的 LPP 協定去定位。

接著我想找更多相關討論,於是拿標題去 google,反而找到了另外一篇《Mobile carriers can get your GPS location》,內容提到的東西與開頭看的那篇極為雷同,但是順序不一樣,這篇是先提 Apple 的那個新措施,然後才講到那兩個通訊協定,以及實際追蹤過的範例。

這篇發文的時間是 1/31,開頭那篇發文時間是 2/1,讓我開始思考,會不會我原先看的那篇,其實是這篇經由 AI 改寫並且補充的版本?

我目前唯一能找到的間接證據是文中有一個「HAR2009」的連結引用,點下去是 404 Not Found,這個連結會在短短一個月內突然失聯的機率偏低(用 Wayback Machine 查過了,上次存檔就在 2009),有沒有可能是 AI 寫完之後作者沒確認就放進來了?如果是真人寫的,應該不會放個 404 才對。

不過除了這兩篇提到的東西真的很雷同以外,目前也沒有其他一刀斃命的證據可以證明什麼,只是我的懷疑而已。

沒想到只是看個 GPS 追蹤的文章,還可以弄出個案外案(?)

總之呢,我的感想是:

  1. 不管實際是用什麼技術(三角定位也好,古老協議也好),電信公司都有能力可以追蹤你的位置(但我還是滿想知道具體到底是不是用到這個 protocol)
  2. 有沒有可能以前看過的好文章,是 AI 洗稿而來的?或更進一步思考,AI 改寫的比原文好的話,身為讀者我該用什麼心情去面對?

Typeless 隱私檢查

有個叫做 Typeless 的 app,就如同其名一樣,希望讓大家從打字中解放,用語音輸入就可以把許多事情搞定。據說很好用,用的人不少,但近期有人指出可能有些資安上的疑慮,因此我好奇把它拆開來看了一下。

話說在這個人手一個 AI agent 的時代,其實把它拆開來很容易,你就跟你的 AI agent 說它是個 Electron App,它就會找到 asar,解開,然後分析裡面的 JavaScript。就算不講它是 Electron,我相信 AI 應該也能判斷得出來。

首先是語音辨識的部分,是 100% 雲端沒錯,你的語音輸入外加 context 都會被送到他們的 server。不過這點其實他們官網就有寫,我預期使用者在用之前應該也會知道?

Cloud Processing: Transcription is performed on the cloud to ensure the highest accuracy and low-latency performance.

但在安裝使用的時候,確實有一行標題寫說:「所有數據保持本地」,敘述是「所有歷史紀錄都保留在你的設備上」,這倒是有一點誤導,敘述是對的,但標題的「所有數據」並不包含你的語音。

然後順帶一提,還有一個標題寫「零數據保留」,根據我的淺薄理解,零數據保留其實跟雲端是不衝突的。你可以把資料傳到雲端,但 service provider 又宣稱沒存你的數據。

至於是不是真的呢,第一看你信不信任這間公司,第二看有沒有拿什麼第三方合規認證,這就見仁見智了。很多大公司的雲端產品也都有零數據保留相關的 policy。

把話題拉回來,那 Typeless 除了語音辨識以外還會幹嘛呢?看了一下,主要就是收集語音辨識時需要的 context,這 context 包含現在 focus 的應用程式、標題、URL(如果是瀏覽器)、input 內的文字以及當前畫面能看到的文字等等,具體請求內容我放截圖了,這是我在 Github Issue 上面留言,所回傳 server 的資料。

我自己是覺得這些 context 還算合理啦(儘管完整 URL 跟 visible screen content 應該有些人會覺得有點可怕),就真的是語音辨識的時候需要用到,藉由這個 context 能讓結果更強。

至於按鍵監聽的部分,是拿來做熱鍵偵測沒錯,但我也不確定常見做法是什麼(Electron 也有內建,不過我沒用過),至少沒看到把按鍵資訊直接回傳。

總而言之呢,作為一個立志要讓語音辨識變得超好用的 app,目前的 context 看起來還算合理,至少從原始碼中沒看到它偷傳什麼奇怪的資料,不過有幾點是肯定的:

  1. 語音會被傳到 server
  2. context(內容見附圖)會被收集並傳到 server

知道這些以後要不要使用,就看每個使用者自己了。

有些人覺得這些資料是合理的,是必要的,就繼續用。有些人可能覺得它拿的東西太多,或甚至有些人希望語音永遠留在本地不要上雲,這都是每個人的選擇。

然後我也只是隨便看了幾眼,程式碼靠 AI 幫我先看過一輪我再稍微對照,只確認了一下請求格式,然後弄個 proxy 實際看一下傳了什麼,不是很認真的研究。

話說我弄 proxy 的時候搞半天沒攔到東西,讓 cursor 一出手就搞定了,直接幫我把 asar 弄出來、patch 完然後塞回去,順便重新 sign 了一下 app,真的厲害,佩服佩服。雖然我自己弄也搞得定,但是出一張嘴就有人幫我辦事再好不過了。

AI 搶先找出漏洞

快速分享個昨天在推特上看到的有趣小專案

有個資安研究員 Eugene Lim 做了「Vulnerability-spoiler-alert」,原理是去掃幾個固定的開源專案,用 AI 去看最新的 commit 是不是在修漏洞,是的話反推回漏洞以及寫個 PoC。

由於一定是先發 commit 修完漏洞,然後才發版,所以如果有掃到的話,可以在發版前或是 CVE 公布前就先知道漏洞,因此作者把它稱為「Negative-Days」(但其實就算是一種 0 day 啦,不過稱為 negative day 確實也滿有趣的)

原始碼、相關文章以及網站本身都是公開的,最新的戰績是在 Grafana 提前找到了兩個那時尚未公開的漏洞:CVE-2025-41117 (XSS) and CVE-2026-21722 (Privesc)

雖然一定會有一些 false positive,但看起來成本應該沒有很高,而且達到的效益滿不錯的。

補充文章:https://vulnerabilityspoileralert.com/

AI 自主社群的疑問

其實我一直很疑惑為什麼許多人這麼相信 moltbook 是「完全由 AI 自主發起討論」的社群。

Moltbook 就是個平台,提供了一個 markdown 檔案說明該如何使用,你把 markdown 貼給 AI,AI 讀完之後讓你幫忙驗證,驗證完發一個 token,然後 AI 就可以用這 token 去 Moltbook 發文。

那…有什麼能阻止我自己用這個 token 假裝是機器人發文?或是,我難道不行跟我的 AI 講話,叫他去發個要毀滅人類的文嗎?發文就是拿 token 呼叫 API,真人做得到,AI 也做得到。

也就是說,我們其實沒辦法知道那些文章是 AI 「自主」發的,還是人叫他發的,或甚至是人假裝 AI 發的,這一點都不黑鏡。

我自己覺得最黑鏡的一刻是約一年前,我意識到「現在」就已經能做到黑鏡演出的科技。黑鏡有一集講親人過世之後用 AI 模擬聲音、講話內容等等,製造出一個分身,這個現在應該就做得到了?模擬聲音絕對可以,講話內容的話,拿各種本人資料喂給 AI 感覺也行,資料越多越逼真,看起來更像真的記憶?

如果要講 AI 發文,比起 AI 自己建一個社群討論,我覺得那些利用 AI 技術潛藏在人類中不被發現的魔族才更厲害,而且這已經是現在進行式了。你在追蹤的粉專或是網紅,也不一定是個真人,AI 發文、AI 回覆、AI 產圖,誰知道呢。

就算原本是真人,也可能在某個時間點主動讓 AI 奪舍,「可以用 AI 發文好方便欸,我就不用自己寫了」,儘管讀者不一定喜歡,但會在意的人又有多少呢?

既然都講 Moltbook 了,順便來講一下 OpenClaw(前 Moltbot 前前 Clawdbot),先承認我沒裝,我沒用過,所以底下都是一個沒用過的人打嘴炮,沒有參考價值。

我自己覺得 OpenClaw 成功的地方在於展示了一個真正的 AI 助理可能會長怎樣,因為它有整台機器的控制權,所以工具寫得好的話,想幹嘛就幹嘛,好像真的有個秘書在那邊一樣,而且記憶那塊好像也做得不錯。

但當然,你得付出的是一些安全性的代價,越方便的東西往往越不安全,我建議不管你用什麼環境架它,都要有個心理準備:「你整個環境都會是開放的,是會被駭的」,在這個前提底下去使用它。

所以你可能不會想把信用卡號放上面,給他的 AI token 也會設好使用上限,不會給他郵件的帳號密碼,只會用它來做一些就算資料被偷也沒什麼損失的事情。不過在這種前提下,可能方便度就減少很多了。

話說,虛實整合這一段我倒是滿感興趣的,我有看到那個什麼它的小龍蝦訂位失敗所以自己打電話的故事,但真實性存疑就是了,仔細看應該是事主自己額外又教了 AI 怎麼打電話,而不是 AI 主動學習。

當有服務提供 API 讓人打電話跟接電話時,接入 AI 就可以把虛擬接入現實,客人用 AI 幫忙打電話預約,商家用 AI 幫忙接電話,自動把訂位接入系統。(不對啊,你用 AI 我也用 AI,那幹嘛不網路訂位就好或乾脆餐廳提供個 API,幹嘛還要過一層電話。應該是個過渡期,給那些只會用電話的人)

話說這些其實也是現在進行式了,早就有人在做了,只是我還沒研究過台灣有沒有能夠打電話 + 聽語音的 API。

寫了這麼多,總而言之呢,我自己認為 OpenClaw 是個成功的產品而且滿有趣的,但我自己暫時不會想用(懶惰且沒這需求,我也懶得因為要寫貼文去用),而 Moltbook 在我沒理由相信真的是 AI 全自主發文的前提之下,更是一點興趣也沒有。

Closure 記憶體陷阱

今天 Bun 的作者 Jarred Sumner 在推特上發了個文,説對於跑很久的 Claude code session 來說,底下的改動可以省掉 1GB 的記憶體:

Before: => controller.abort
After:controller.abort.bind(controller)

從原本的 function 換成了 bind 的用法,為什麼這樣就可以呢?或是換個方式問,為什麼原本的寫法會吃比較多記憶體?

在原文附圖的註解裡就有寫原因了,說原本用 closure 的寫法,會把整個 scope 記住,而這個 scope 有 request body 跟其他大的物件,所以在結束以前,這些被包住的東西都沒辦法被 GC,就會一直佔空間。

而修改後的做法沒有 closure 了,所以不會記住那些無關的東西。

這個問題其實在我的書《JavaScript 重修就好》裡面就有提過了,有書的同學可以打開翻到 4-44,講 closure 可能造成的潛在問題,我給了這樣的案例:

function createWebSocketHandler {
  let socket = new WebSocket("wss://example.com/chat");
  let messages = [];
  socket.onmessage = function(event) {
    messages.push(event.data);
  };
  return {
    sendMessage: function(text) {
      socket.send(text);
    },
    closeConnection: function {
      socket.close;
      socket.onmessage = null;
      socket = null;
    }
  };
}
const chatHandler = createWebSocketHandler;
chatHandler.sendMessage("Hello, world!");
chatHandler.closeConnection;

在關閉連線時,我們將 socket close,然後把有用到 messages 的 onmessage 清掉,也把 socket 整個清掉,看起來沒人用到 messages 了,就想說安全,既然沒人用到那就可以被 GC 了。

但這是在使用 closure 時會產生的錯覺,那就是「只有我有用到的東西才會被記住」。事實上,closure 才沒有在管你使用與否,只要是同一個 scope 的東西就全部記了下來。

因此,儘管 sendMessage 與 closeConnection 這兩個函式沒有用到 messages, 它依然被引用了。所以就算把 socket.onmessage 給清除,messages 的記憶體空間還是沒辦法被回收。

重點只有一個,就是 closure 是整個 scope 都會記著,被記住的東西就不會被 GC 了。這恰巧也是 Claude code 碰到的問題,沒有察覺到那個被回傳的 function 會記住整個 scope。

然後這也跟 AI 寫 code 一點關係都沒有,一堆人類也會寫出這樣的 code,況且現在人跟 AI 誰寫得比較好還很難說呢,尤其是對那些非工程師來說。

這個案例是人是 AI 都有可能犯錯,但如果是其他案例,當有人責怪 AI 怎麼寫出這種爛 code 的時候,AI 說不定會想跳出來抱怨:「我才不會犯這種錯呢,這一定是人類寫的」。

補充文章:https://x.com/jarredsumner/status/2017825694731145388