隨意聊

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

共 110 篇 第 3 / 6 頁 RSS 訂閱

AI 讓想像力變現

AI 出來以後一直讓我想到以前的一句廣告詞:「想像力就是你的超能力」,很多有想法卻礙於沒有該技能的人,有了能夠施展魔法的空間。

儘管有些東西在專業人士眼中還是不及格或勉強及格,但對於使用者來說,已經足夠好了,至少能有個 70 分。或是說,有些東西只要能滿足自己的需求就好,就已經是 100 分了。

產生畫面、影片如此,寫一個程式也是如此,我覺得很多人可以靠 AI coding 寫出自己想要的東西是件很讚的事情。

昨天試了一下 Nano Banana Pro 是真的厲害,雖然我功力不足,想產的東西有些細節沒有很完美,但出來的成果還是 ok 的。

感覺每個月可以找一天,或是每週一兩個小時定為 AI FOMO time,在那時間內專注來試試看目前 AI 的上限到底在哪,其他時間就別管那些 AI 的新消息了。

話說其實還有很多有趣的話題可以聯想,例如說 AI 可以讓你在 3 分鐘內做出一個 60 分的東西的話,那會不會想要花 300 分鐘做到 80 分的人就變少了?還是說那些人不會受影響?不過換個角度看,把平均分數從 40 分拉到 60 分,好像也是件幫助很大的事情

之後再找時間寫篇部落格文章聊聊吧,很多東西可以想像

別把密鑰貼上工具

你各位阿,不要輕易把敏感資料貼在網路上啊
有很多很方便的小工具網站如 json beautifer 或是 json formatter 之類的,可以美化你的 json,這些我自己也偶爾會用

昨天看了資安公司 watchTowr 的一份報告之後才發現,原來這些工具有個分享功能,會產生一個 URL 讓你可以分享你的 json 給別人
但是這個分享功能其實有個 public page 會直接顯示整個網站最近分享過的東西(這功能就是這樣設計的)

因此如果你把 key 貼在上面之後分享出去,就等於直接分享給整個網際網路了

那真的有人會這樣做嗎?有,而且還不少

文章中指出他們在歷史紀錄裡找到不少公司的敏感資料,各種 secret 跟 key 都在裡面😅

話說哪天如果幫你解析 JWT 的網頁被駭了,應該可以蒐集到一大堆的 token 😆

補充文章:https://labs.watchtowr.com/stop-putting-your-passwords-into-random-websites-yes-seriously-you-are-the-problem/

試用Antigravity後感

滑臉書看到一堆人狂吹猛吹 Google Antigravity,真的讓人很懷疑到底那些人有沒有真的用過,還是只是讓 AI 水了一篇幻想文。

昨天一早興奮地下載 Google Antigravity,想說免費的真香來玩玩看,用 Gemini 3 Pro(high) 做三四個 task 之後就報錯了,說 quota 已經用完,要再等半天才能繼續。

我本來就知道有 quota,只是我以為會比想像中更多,還是我用得太過頭了(?),不過後來換成 cluade 模型之後 quota 另外計算,還是可以再撐一陣子,體驗一下 IDE 的功能。

昨天短暫試用大概半小時沒 quota 之後,我就切回去用我的 Cursor + 超快的 composer-1 了,目前還是最喜歡用 composer-1,天下武功唯快不破。

可能需要等之後 quota 變多再來試試看到底 Google Antigravity 厲害在哪,我目前還沒看出什麼毀天滅地的差別。

從React學底層運作

從大型開源專案的發展歷程以及原始碼裡面,其實可以學到不少東西。最近把之前去 JSDC 線上前導活動分享的主題:「從 React 中學習 JavaScript 底層運作」寫成了文章,主要在談三件事情:

  1. React 早期版本(真的很早了,10 年前 2015 的時候)的 XSS 漏洞,以及如何從這個漏洞的 fix 中學習 Symbol 的使用方式

  2. React fiber 是把大任務切成多個非同步小任務,那這個「非同步」又是怎麼被執行的?文章會談到 React 如何從最早的 requestIdleCallback 切到自己做的 requestAnimationFrame + postMessage,再把後者換成 MessageChannel,這中間的考量是什麼,這些的觸發時機點又有什麼不一樣

  3. React profiler 碰過的 V8 bug,從這個 bug 學習 V8 底層的運作方式,例如說從規格來看 JavaScript 只有浮點數,但 V8 其實還是分成 small integer(簡稱 smi) 跟其他,才能保證性能是好的。
    以及 V8 中物件是怎麼被儲存的,shape 又是什麼,這些又是如何跟 React profiler 有所關聯。

以上大概就是文中會提到的內容,文章了,有興趣的可以看看,一次看 React 原始碼外加學習 JavaScript,一舉兩得。

補充文章:https://github.com/aszx87410/blog/issues/153

AI駭客攻防報告

話說 Anthropic 前幾天發佈了個報告:《Disrupting the first reported AI-orchestrated cyber espionage campaign》,主要在講他們偵測到中國國家級駭客組織發起的網路攻擊,其中大量使用了 AI,並且用 jailbreak 繞過了 Claude 模型的限制來讓他做一些壞壞的事。

攻擊主要分幾個階段,第一階段由人選出 target,第二階段由 AI 負責去做偵查(俗稱的 recon),搜集各種目標的資訊,接著由人去 review 結果之後,再由 AI 去發起攻擊。

從頭到尾真人都只負責監督,剩下的事情都由 AI 來幹,並且整合了各種 MCP tool,讓 AI 可以去做一堆事情甚至開瀏覽器自動化之類的,從偵察到寫 exploit 到橫向移動全部給 AI 自己做。

我自己看到這報告並不太意外就是了,我們現在寫 code 不就是這樣嗎,讓 AI 自己看 Figma 設計稿然後寫 code,寫完自己呼叫 Browser / DevTools MCP 看畫面然後自己改,改完給我 review,review 完自動產生 summary 跟 PR。

既然寫 code 都可以這樣了,攻擊也能如此也不太意外。而且前一兩年就有些公司開始做全 AI pentester 了,CTF 也開始用 AI 輔助甚至全自動,儘管還是有些細節會出錯(如幻覺),但技術面怎麼想都是有可能的。

不過現階段可能僅限於比較簡單且單點的漏洞?就像寫 code 一開始也只能改改單個檔案或是新專案,後來才進化成可以看整個 codebase 並融入現有風格。比起寫 code,感覺 AI security 還在相對偏早的階段,我能想像簡單的可以都交給 AI 打,困難的可能還需要點時間。

也就是說,看到 AI 在寫 code 上的進化,應該不會讓人懷疑他在資安這塊的潛力,只是現階段到底可以全自動化到什麼程度,這個就滿值得討論的。而這篇 Anthropic 的報告基本上是在講說自動化程度已經比很多人想像中的高了。

看了看推特上跟 hackernews 上的討論,有些人看到這報告則是覺得比較偏行銷用途,畢竟報告裡其實沒太多技術細節,就算有,也都是偏工程的細節,例如 AI 駭客的流程或是架構,但絲毫沒有提到任何資安面的東西,像是他們到底實際給什麼任務,產生了什麼結果。

相比之下,OpenAI 上個月出的報告就《Disrupting malicious uses of AI: an update》就專業多了,裡面就詳細寫到每一個駭客組織都拿他們的模型幹了些什麼,內容滿詳細的。

說不定在不遠的未來,主流就變成機器人對決了,攻擊方寫一個 AI 駭客組成 AI 紅隊 24 小時不間斷攻擊,防守方寫出一個 AI 藍隊不斷防守,碰到可疑流量就自行阻斷,24 小時監督,看誰的機器人比較厲害。

那要怎麼讓機器人變得更厲害呢?當然還是需要真人來教他了,就像目前的 AI coding 一樣,原本就沒料的人用了之後也還是沒料;本來就強的人,用了之後強強聯手,強強強強。

參考資料:https://cybermap.kaspersky.com/

localhost繞過權限

「(叩叩叩)你好」 『你是誰?』 「我是 localhost」 『請進』

今天早上看到了做檔案共享的系統 Triofox 的漏洞 CVE-2025-12480 的細節,差不多就是上面這樣 😆

有個 AdminDatabase.aspx 的頁面是拿來設置 DB 用的,有擋權限所以直接訪問會給你一個 access denied,但如果你把 Host header 改成 localhost,就可以直接繞過權限檢查。

設定完 DB 之後下一步是設定 admin account,於是用同樣方法就能繞過檢查,新增一個 admin account,有了 admin account 之後再透過其他功能就能在 server 上執行腳本,拿到 RCE,剩下想幹什麼就幹什麼了。

Google 發的技術細節文章裡面有給一些程式碼,有個叫做 CanRunCriticalPage 的函式,開頭就先檢查 base.Request.Url.Host 是不是 localhost,是的話就回傳 true,這就是漏洞的 root cause。

雖然看起來滿誇張的,但我自己還真的看過類似的系統,當偵測到來源是 localhost 或是內網時直接通過,就不檢查權限了。會有這種設計通常是懶得實作內網的驗證機制,覺得內網很安全,或者是讓工程師方便測試之類的。

但問題往往是這類的檢查很多都沒做好,導致外部可以竄改這些 header,讓外網偽裝成內網,就直接進來了。再者,若是系統本身被找到一個 SSRF 的話也直接沒救。總之,不管怎麼看都是個危險的機制。

Google 的,裡面有更多細節。

教學計畫學生近況

離上次開教學計畫已經是將近四年前的事了,前陣子突然心血來潮想調查一下學生們的狀況,做了個表單讓他們填,回收了 48 份。

有一半的人做前端,後端佔 10%,全端佔 15%,其他還有一些做手機 app 或是轉去做 PM 的。

在工作年資的部分,有八成的人是 3 年以上工作經驗,其他大多數是 1~3 年。

至於薪水的話,只看工作 3~5 年而且工作地點在台灣的,年薪 120 萬以上有 3%,100 萬以上有 35%,80 萬以上 79%(是算累積的比例)。由於沒有其他類似數字可以比較,我也不知道這樣客觀來看是好是壞。

完整的數字的寫在文章裡發到部落格了,有興趣的可以去看看,除了更詳細的數字以外,還稍微寫了一下沒有繼續開課程的理由。

F1系統權限漏洞

最近有三個資安研究員 Ian Carroll、Sam Curry 與 Gal Nagli 發布了與 F1 相關系統有關的漏洞系列文,第一篇是在講跟駕照分類系統有關的漏洞(還有二三篇但還沒出來)。

要參加 F1 的比賽,需要有個 FIA super licence,而 FIA 對於車手有分不同等級,需要透過一個系統提出資料並申請更新等級的狀態。

由於這個系統是 public 的,所以任何人都可以上去註冊一個帳號(這也滿合理)。

在更新資料的時候,會用一個 PUT 的 API 如 PUT /api/users/12345,body 裡面則是放你要更新的東西,如姓名等等,看起來也很正常。

但是呢,他們注意到在 response 中多了個 roles 的欄位,於是靈機一動想說:「會不會這個 API 有 mass assignment 漏洞呢…」。

所謂的 mass assignment 呢,就是後端在更新資料時偷懶沒指定欄位,直接把請求中所有的欄位都更新進去資料庫,以 JavaScript 來講就類似於 session.user.update(req.body) 這種感覺,你給我什麼我就更新什麼。

因此,儘管前端沒有提供更新 role 的功能,只要自己在後端傳入 roles 這個欄位,就會一併更新,並且取得相關權限。這種 mass assignment 的漏洞並不少見,而且在某些程式語言上滿常發生。

但要更新的話,要先知道 roles 裡面到底要傳什麼,於是他們就在前端程式碼裡找找看線索,由於前端原本就有檢查 roles 的程式碼,因此可以推測出 roles 的結構,並且反向構造出合法的 payload。

接著就只要在 PUT 請求裡面塞入符合格式的 roles,就拿到了 admin 權限,剩下就想幹嘛就幹嘛了。

要修這種 mass assignment 漏洞也很簡單,就是後端明確寫出到底有哪些欄位可以更新就沒事了,就不會更新到不該更新的東西。

這個漏洞的根本原因就是 mass assignment 而已,不是什麼「沒有金鑰就可以更新內容」,我剛登進去看過了,需要一個 cookie 才能 update 自己的資料。也不是什麼「權限只放在前端」,前端出現檢查 role 的程式碼再正常不過,但重點是不能只有前端檢查,後端也要檢查。

前端檢查權限本來就沒什麼問題,程式碼出現 role 相關字串如 admin 也是再正常不過,不然你前端怎麼知道哪些要顯示哪些不顯示。雖然也是有一派做法是後端先做處理,傳個支援的 feature 列表啦,不會在前端直接檢查 role,但我覺得兩種都行。

前端的檢查原本就只是拿來增進使用者體驗,真正防範的地方一定得做在後端。只看前端程式碼的話,你也不會知道後端有沒有做驗證,所以光看前端也看不出什麼端倪。

站在資訊洩漏的角度來講,當然是全部在後端處理最好,使用者不該看到的,連 HTML 都不要傳給他。但問題是在現在這個前後端分離的時代,基本上不太可能,前端的 codebase 都跟後端完全分開了,你要動態決定前端的 response 成本有點高,因此後端 API 做自己的檢查,前端也做檢查決定哪些顯示哪些不顯示,是很常見的做法(有講錯歡迎打臉)。

半科學退休規劃

我對投資理財一直都沒什麼興趣,說穿了就是懶。

我以前大概 90% 資產都在現金(現在反過來了),因為不知道該買什麼股票,覺得我有固定收入存起來就好,沒有想賺大錢,幹嘛買股票讓心情跟著一起上上下下,錢放著又不會變少,不是很好嗎?後來才知道這樣的想法大錯特錯,錢不會變少,但購買力會隨著通膨持續下降。

第一次買股票好像也才五年前,中午吃飯時公司同事會聊股票,有同事推廣無腦定期定額 0050,從那時開始買了些,順便上網查了一些資料,買了一些金融股跟高股息 0056 之類的,就一直放著,也沒去深入了解(現在除了 0050 都賣了)。

一直到最近才開始稍微更認真研究各種東西,如:4% 法則、通膨、購買力、年化報酬、槓桿、指數化投資、貸款、股票質押等概念,最後寫了一共四篇的系列文:《半科學退休手冊》,大致講一下該怎麼算出要多少錢才能退休,又要怎麼累積。

底下是這四篇文章的標題:

  1. 認識通膨、風險與槓桿
  2. 退休要存多少錢?談真正的 4% 法則
  3. 該怎麼更快存到退休金?自己來算一個數字
  4. 我的資產配置與難以克服的人性

之所以叫做「半科學」是因為投資理財這塊本來水就很深,老實說我沒有真的花到很多時間研究,在細節的部分肯定是會有錯的。與其唬爛說自己的研究很嚴謹,不如承認大概只有一半是對的,另一半是未經驗證的觀念或是信仰,請讀者務必自行確認,不要全信我。

第一篇會先聊一些基礎觀念,如通膨與購買力、常見的投資方法與報酬(銀行存錢、債券、股票等)以及槓桿。第二篇談很常被誤解的 4% 法則,一堆文章都講過這東西,但我猜真正看過原始論文的人沒多少,都互相抄來抄去傳播錯誤資訊,所謂 4% 是指只有第一年領 4%,之後每年隨通膨調整,而不是「每年都固定從資產領 4%」。

而第三篇聊幾個知名 ETF(0050、VTI、VT、QQQ 等等)的年化報酬,並且搭配個簡化版的計算機,算出大概需要多少錢以及多少年可以退休。許多人只是心中有個數字而已,但有可能科學化算下來,是比自己想像中低的。賺越多當然能越安心,但就是會延後退休的時間點。

最後第四篇談我目前的資產配置,雖然指數化投資很好但有點反人性,因此還是留個 20% 讓自己隨意玩,同時滿足長期資產的累積跟自己聽網紅亂選股的樂趣。順便來聊聊退休後除了賣股票換生活費,也可以考慮透過股票質押借錢,在風險控管得當的狀況下,有可能累積更多報酬。

以上就是這四篇的內容,把這整個主題寫完之後,我自己對之後的規劃也比較有方向了,至少有個相對科學的數字能夠參考。雖然說投資有賺有賠,歷史數據也只是參考,但指數化投資已經是個相對科學的東西了,最適合我這種懶人。

我是覺得不管你想不想投資,多瞭解一些金融商品跟概念都是好事,文章附在底下留言了,有興趣的讀者們可以參考。

CodeRabbit供應鏈漏洞

來清一下存很久但還沒有寫的舊聞,在幾個月前被資安公司 Kudelski Security 公佈細節的 CodeRabbit 漏洞。

隨著 AI 越來越進步,除了幫你寫 code 以外,現在連 review 都是 AI 幫你做了。例如說 Cursor 有提供 bugbot,GitHub 有提供 copilot,各家都有自己的 Ai reviewer。有一間叫 CodeRabbit 的公司也是專門做這個的,GitHub app 裝上去之後就會有機器人幫你 review 你的 PR。

而這個 CodeRabbit 有個設定檔,可以自訂你要用什麼靜態分析的工具去跑,例如說 ESLint 啦,Pylint 啦等等。因為是靜態分析工具嘛,所以就算跑了 ESLint 通常也只是對程式碼做靜態分析,應該不會特別執行其他操作才對。

但其中一個給 ruby 用的工具 Rubocop 可以設置 extension,指定一個 ruby 檔案來執行。因此透過配置 extension,就能在跑靜態分析工具時執行程式碼(等於是在幫你跑工具的機器上執行任意程式碼),於是他們就塞了一些 code 把 env dump 出來,得到一大堆 key,AI 的,GitHub 的,DB 的,你想到的都有。

由於 GitHub App 的 key 也在裡面,等於是你直接掌控了 CodeRabbit 的 GitHub App,因此所有有安裝他們工具的 GitHub repo,你都可以讀寫,這就是為什麼揭露細節的文章標題為:「How We Exploited CodeRabbit: From a Simple PR to RCE and Write Access on 1M Repositories」,直接擁有了 100 萬個倉庫的讀寫權限。

這個漏洞在今年一月被回報,過了一週後就修掉了。

我感覺 CodeRabbit 可能打從一開始就沒想到這個攻擊面,不覺得執行靜態分析工具,可以讓人執行任意程式碼,所以不覺得有人可以打進去這個環境。但大家都看到了,一旦被打進去就直接 game over。

其中最需要改善的當然是修正一下 threat model,要先假設攻擊者可以在這個環境執行任意程式碼,就能設計出更安全的框架,跑在一個 sandbox 裡面。

另外,也可以看出為什麼我們總是需要多層防護。

當你心中想的是「這個環境他們進不來啦,沒關係」,就算你 100% 相信這個前提,萬一最差狀況還是發生了(如同這個故事一樣),就等於直接投降,資料都給你。

但若你想的是「雖然我覺得不會被打進來,但如果真的發生了該怎麼防?」,你可能就會把一些敏感資料放在其他地方,雖然不一定能完全防禦,但至少能增加攻擊的難度,並且爭取更多時間讓你發現有人打進來了。

Redis滿分漏洞解析

今天來講一個嚴重卻又沒這麼嚴重的 10 分滿分 Redis RCE 漏洞。

這兩天爆了一個名為 RedisShell 的漏洞 CVE-2025-49844,是個 CVSS 10 分滿分的 critical 漏洞。

CVSS 全名為 Common Vulnerability Scoring System,在資安界是個普遍的評估漏洞嚴重程度的標準,會將攻擊所需前提以及影響範圍列入考量,最後算出一個分數,會考量的範圍有:

  1. 從哪裡觸發漏洞,是透過網際網路,還是必須在同個網段,甚至是要實體接觸裝置等
  2. 攻擊複雜度,是否能夠穩定利用漏洞
  3. 所需權限,例如說有些漏洞要管理員身份才能觸發
  4. 是否需要使用者點擊或開啟檔案等互動來觸發
  5. 影響範圍,是侷限在該系統內還是能擴大範圍
  6. 對機密性(Confidentiality)、完整性(Integrity)以及可用性(Availability)造成的影響

這次 Redis 的漏洞由於是 RCE,遠端程式碼執行,因此 CIA 三個的影響都是 High,影響範圍也會擴大,畢竟能超過 Redis 的範圍,在該台主機上執行命令。

那為什麼我會說這個漏洞嚴重又沒這麼嚴重呢?10 分不就是最嚴重的嗎?

這個洞的成因是,Redis 在執行 Lua 時有問題,導致執行特定的 Lua 腳本可以觸發漏洞,跳脫 Lua sandbox 然後在主機上直接執行命令。

單看 Redis 的話,就是「只要能發送指令,就能 RCE」。

但若是以整體系統架構的層面來看,我們可以想的問題是:「攻擊者該怎麼對 Redis 發送指令?」,最簡單的當然是你 Redis 開在公網又沒 auth,直接被打進來。雖然這種機器確實很多,網路上可以找到一大堆,那會這樣做的群體可能也不會注意到這個最新的漏洞訊息 😆

一個稍微正常一點的系統,Redis 都放在內網裡面,那攻擊者要先打進來拿到某個主機的 RCE,才可以再往 Redis 那台打。但是對小一點的公司來說,第一個 RCE 就可以把他們打爆了,打 Redis 可能沒辦法打到更多東西。

我想說的是「對 Redis 發送指令」這個前提,在一般的環境下沒辦法輕鬆達成,但 CVSS 單看 Redis 本身,所以表現不出這點。10 分是沒問題的,但那是因為最高就是 10 分,Log4j 也是 10 分,甚至一個我覺得更嚴重的 Oracle E-Business Suite Pre-Auth RCE(CVE-2025-61882)也才 9.8 分,所以分數並不是一切。

不過我也可以想像得到,你站在另一個角度看分數這件事,就會不一樣了。

當你是個內部專門管 IT 資安的人,每天面對幾十個新的漏洞,哪有時間去看這些細節,當然是按照嚴重程度由大排到小,然後 critical 的就趕快修掉。做為風險控管的一環,這確實是個合理的做法。

同一個漏洞,在不同的前提之下會帶來不同的結果,之前才跟朋友聊到許多小公司在考慮攻擊面時,不會把橫向移動考慮進去,因為根本也不需要移動,你打下一台就整個系統淪陷了,所以「Redis 被打下來」這個風險是低的。但我也能想像到有些大公司內部分好幾個網路,這時候從 A 透過 Redis RCE 能打到 B 做橫向移動,這個就是很有價值的漏洞。

其實整體都還是風險管理的一部分,在「Redis 有個 10 分漏洞」的前提下,該考慮哪些風險、該怎麼處理等等,在不同框架底下會有不同做法。

但如果你問我該不該趕快修,我的建議是:修,都修。網路上也已經有人整理出簡單 PoC,可以看出這個洞的觸發方式。

Unity漏洞嚴重嗎

昨天看到我長期有在追蹤的資安研究員 RyotaK 發了一篇 Unity 漏洞的 writeup,想說放著晚點再看,結果剛就看到一堆新聞先寫出來了,而且看起來還挺嚴重的

至於是否真的這麼嚴重,除了看 CVSS 分數跟看新聞以外,其實也可以先了解這個漏洞以後自己思考一下。

由於原文只有寫 Android 的,因此我們只談 Android。

在 Android 上,一個 app 可以用一個叫 intent 的東西把另一個 app 叫起來,並傳一些資訊過去。例如說你在某個 app 購物,要付款時點個按鈕就打開另一個 app 跳到結帳頁面,就是類似的機制。

然而,Unity runtime 在這部分沒處理好,導致它會執行其他 app 帶過來的程式碼(更細一點,是帶一個路徑,接著載入這路徑的程式碼)。

因此呢,第一個攻擊方式就是:你先裝了一個惡意 app,這個惡意 app 就可以用這招,讓其他 Unity 打包出來的 app 執行惡意程式碼。

而第二個攻擊方式是,有些 app 支援用 URL 的方式傳送這個 intent,因此不需要裝惡意 app 了,你點個按鈕就可以了(開發者要自己配置,非預設設定)。

但是呢,剛剛有說除了 intent 以外,攻擊者還需要一個檔案,而這個檔案如果是從網路上下載的,Android 本身的安全機制會擋住,因此只能是「Unity 打包出來的遊戲自己寫的」,所以被攻擊的那個 app,必須本身就會寫檔案,而且攻擊者可以控制檔案內容,就可以寫惡意程式碼進去檔案,接著透過 URL 去執行。

原文舉的案例是 Facebook Messenger 的 cache,但其他 app 有沒有這機制,就要看每個 app 本身的功能跟做法了。

好,我們總結一下這個漏洞的觸發方式,主要有兩個:

  1. 裝一個惡意 app,透過它攻擊其他 Unity app

以及底下三種條件都滿足的:

  1. app 需要設定可以用 URL 帶 intent
  2. 攻擊者可以控制 app 寫入檔案,並控制檔案內容
  3. 你點了一個惡意連結,觸發漏洞

他之所以嚴重性為 High,分數 8.4 分(滿分 10 分)
是因為漏洞觸發後嚴重性高,但是 Attack Vector 這一項是 Local
代表這漏洞只能從本地攻擊(遠端也可以但前提較多)

有些讀者可能會好奇說,那既然都裝惡意 app 了,他自己偷資料就好,幹嘛還要利用 Unity 漏洞呢?

這個就問得好了,如果 Unity app 的權限比較多,可以達到提升權限的效果。除此之外,我記得 Android app 彼此之間是不能存取對方的資料的(除非特別設置),因此惡意 app 可以透過這點,讀到其他 Unity app 的資料。

總之呢,漏洞這種東西,比較多人都是不管觸發難度,反正嚴重的先修了再說,以防萬一,這確實是合理的。

但若是我們能理解漏洞的觸發條件,或許就不會這麼緊張(?),比起「Unity 爆重大漏洞」這個標題,在理解詳細的資訊之後,就能更客觀去看待這個漏洞。

我是覺得跟以前出現過的其他漏洞比起來(雖然 platform 不一樣好像不太能這樣比,我指的是 log4j),這個的攻擊前提確實多了些,沒有到這麼這麼嚴重(如果有人有不同看法可以在底下留言,教學相長)。

但安全起見,如果你家有 Unity 做的東西,還是盡快升版把洞修了吧。

Chrome內建AI初探

前幾天有讀者私訊我,分享一個他自己做的 Chrome 擴充套件,可以幫忙翻譯、摘要日本的新聞,幫助學習日語。由於這個套件是開源的,因此我好奇這些功能是怎麼做到的,接的是哪個 LLM API,看了一下才發現居然全部都是 Chrome 內建的 Web API!

換句話說,現在已經可以透過 JavaScript 直接翻譯跟摘要了,不需要準備任何後端,用到的是瀏覽器的 Translate API 跟 Summarizer API。

因此我花了點時間去研究,發現除了這些以外,還有一個更強大的 Prompt API,可以在瀏覽器上跑一個小模型,就可以不需要接任何付費服務,免費跑一些簡單的 prompt。

雖然性能跟沒有你去接 ChatGPT 或別的 API 來得好,能做的事也沒有比較多,但一些很基本的事情應該是夠用了。另外,AI 跟各種產品的整合原本就是勢在必行,當瀏覽器直接有 API 讓開發者使用的時候,開發者也不需要準備自己的後端,就可以用到 LLM 的各種功能。

不過目前這些 API 只有 Chromium-based 的瀏覽器如 Chrome 跟 Edge 可以用,其他瀏覽器還在觀望狀態,看起來沒有這麼快。

我有寫了一篇介紹文與一個簡單的 Prompt API demo,有興趣的讀者可以試試看在自己的電腦上跑(先提醒一下這些 API 還在測試階段,可能會有問題。例如說我剛開始跑幾次都沒問題,昨天每次跑都直接當機重開)

總之呢,感覺這些 API 是值得持續關注的。

介紹文: https://blog.huli.tw/2025/09/27/chrome-built-in-prompt-api/

用奈米裝甲蓋房子

大概每隔一陣子就會收到找我開線上課程的邀約,我全部都推掉了。但與其說我對開課沒興趣,不如說是對程式課沒興趣。我最近在思考,要不要開一個教人蓋房子的課程。

自從兩三年前日本開發出類似於漫畫《膽大黨》中的奈米裝甲以後,蓋房子早就不是以前那種需要找專家來做的事情,而是每個人都能使用的魔法。有了這個奈米裝甲之後,只要在腦中想像一下房子的長相,結果就會立刻呈現在眼前。細節想得越詳細,最後的結果也會越詳細,細節越逼真。

以前那些要花一兩年蓋的房子,有了奈米裝甲之後一兩天就能蓋好,它正在重塑整個產業,改變了整個遊戲規則。有了奈米裝甲之後,我覺得我不太需要找那些所謂的專家去蓋了,我自己就可以搞定的東西,找他們幹嘛?最近幾個月我已經用超快的速度蓋好十幾間房子了,每一間看起來都跟真人蓋的差不多。這樣真的省了很多時間,讓以往必須由特定人士才能做的工作,變成誰來都行。

但我發現有些人不太會用奈米裝甲,不知道該挑哪個牌子,也不知道該怎麼想像,不知道怎麼在腦中描繪那些細節,因此我才想開個課程來教大家怎麼用奈米裝甲蓋房子。之前跟朋友講了這個想法,他第一個念頭是質疑我:「你又沒有專業背景,要怎麼教?」,我說我為什麼需要專業背景,你不是有看到我蓋出來的房子嗎,那不是跟專業的長差不多嗎?現在的時代早就變了,你那是迂腐陳舊的觀念,會跟不上潮流的。

話說,講到要怎麼挑奈米裝甲,最近我發現有一間廠商太奸詐了,我用它蓋了一間樣品屋讓大家參觀,最近天氣熱嘛,我就想像了一個大學宿舍的冷氣卡機制,讓想參觀的人自己買冷氣卡付錢,結果我今天收到一筆帳單,發現那些冷氣錢還是扣我的!

這個設計實在是太奸詐了,我不是說都說我要冷氣卡機制了嗎,感應機確實在那裡,可以感應也可以刷卡,但最後居然是扣我的錢,這麼大的公司到底在搞什麼?

奉勸所有最近有在玩奈米裝甲的人,不要用這間公司的產品,否則你可能會成為下一個倒霉鬼。

Bun安裝為何很快

JavaScript 的 runtime Bun 憑藉著又快功能又多的特色,早已在圈內打響了名號。

前幾週 Bun 的技術部落格有一篇文章《Behind The Scenes of Bun Install》,深度解析了為什用 Bun 來安裝套件可以比其它程式快這麼多,足足有 pnpm 的 4 倍,npm 的 7 倍。

文章有提到 Bun 在做這個功能時的核心理念是:「把這當成是一個 systems programming 的問題」,因此用了很多相對較底層的解法,包括:

  1. 減少 system calls
  2. 運用 Apple 非公開的 API 做非同步 DNS 解析
  3. 用 binary 格式取代 JSON pasring
  4. 設計對 CPU 快取友好的資料結構
  5. 善用不同的 system call 快速複製檔案

這裡面細節很多,Bun 的原始文章圖文並茂,寫得很好,因此我就只列出幾點而已。

看完之後很能理解為什麼 Bun 比別人快了這麼多,背後真的是做了很多細節上的改善。另外,Bun 是用 Zig 寫的,直接編譯成 native code 並呼叫 system call,也比用 Node.js 寫的其他套件管理程式少了許多 JavaScript overhead。

這篇 Bun 的原文很值得一看。

上面講完了 Bun 的優點跟背後的努力,接著講一下 Bun 的缺點跟我不喜歡的地方,就是 Bun 雖然宣稱自己可以直接替代 Node.js 來使用,但若是某些 spec 他們覺得不合理,就會直接不實作。

舉例來說,6 月份有個 issue 是說 Bun 在執行 fetch(‘localhost:6000’) 時沒有報錯,可是 spec 上有所謂的「Port blocking」,發送到特定 port 的請求會直接報錯,不會建立連線。這是一種資安上的考量,避免有人用 HTTP protocol 偽造別的協定來攻擊(叫做 Cross Protocol Scripting),Redis 早期就有這問題,你可以發一個 HTTP 請求當成 Redis 指令來執行。

總之,後來有人對 Bun 提了個 PR 加上這個符合 spec 的功能,而 Bun 的 creator 把 PR 關了,說他覺得這功能對使用者沒價值,如果他們就是想用這些 port 怎麼辦。

這只是其中一個案例,再查查也會發現其他 Bun 沒遵守 spec,或者是因為某些原因加進去的預設設定。久了之後說不定會成為另一種 IE?反正 spec 寫他的,我做我想做的。

不過 Bun 的出現,也確實為其他 runtime 帶來一些壓力跟競爭,其實也是件好事。在特定狀況下我可能會用 Bun(如需要 Single-file executable),但一般情形下,還是再觀望一陣子好了,繼續用我的 npm + Node.js。

補充文章:

像學外語學程式

我從來不覺得學習程式語言開心過。

小時候帶我入行的師父,在教程式這件事情上跟其他人有這麼一丁點不同。「程式語言」這四個字,一般人在意前兩個字,但外文系出身的他則相反——「程式語言不也是一種語言嗎」,他是這麼說的。

因此,一直到開始學程式語言的三個月後,我才知道把一個程式跑起來是長什麼樣子。

在這之前,我是從背單字開始的。師父跟我說程式語言比英文好學多了,用到的單字量比較少,每天只要背三個就好,大概背個三個月左右就能把常用單字都記完了。於是我每天背三個,我還記得第一天背的是 public、private 與 protected 這三個單字(我是在過了幾年以後,才知道這些詞在英文裡是什麼意思)。

除了背單字以外,文法的學習也很重要。

師父跟我說,就像英文基本句型 I like you 是主詞 S + 動詞 V + 受詞 O 一樣,程式語言也類似,如 int a = 42,主詞是 a,動詞是 =,受詞是 42,就跟 I like you 是相同的句式,而那個 int 則是修飾語,用來修飾 a,類似於 I like you very much 的 very much。

而條件控制如 if (score >= 60),文法就跟英文更像了,if 是條件連接詞,score >= 60 是條件子句,而後面 {} 接的內容則是主句,只是把英文多加一些符號而已。

還有,在學習 JavaScript 的 Promise 時,我卡關了很久都搞不懂它的語法,而師父給的指導簡潔有力:「Promise 是對未來的承諾,就是一種未來式。現在式要用 return 跟 throw,未來式動詞要變化,變成 resolve 跟 reject,就這樣而已」,聽完以後茅塞頓開,瞬間搞懂怎麼使用。

這樣的訓練苦歸苦,畢竟身為一個小孩連英文都學不好了,何況是程式語言?但長大後才發現幫助很大。

例如說有些公司面試時會手寫程式碼,不給用電腦也沒有 IDE,直接筆試用手寫。不只公司面試,甚至我大學修程式語言時,有些課程考試時也是這樣的。儘管一堆同學叫苦連天,沒有 IDE 的幫助根本寫不出來,但對我來說則是得心應手,因為我從小就是這樣練的。

開頭我有提到,我學三個月以後才真正在電腦上寫 code,在這之前都是像學英文那樣學程式的,因此本來就是用手寫程式碼的。

那時師父每週都會出一份作業,內容大概有幾種類型:

  1. 選擇題
  2. 照樣造句
  3. 句子重組

選擇題比較簡單就不多講了,照樣造句大概就是給 int a = 42,然後我要照這個寫出 char c = ‘a’ 或是 float d = 3.14 之類的,照著同樣的句型去寫。

句子重組的話也滿有意思的,比方說會是 if print score “pass” >= 60,要重新排列成 if score >= 60 print “pass”,才是正確的語法。不過師父有提醒我,在某些程式語言中會用倒裝句,變成 print “pass” if score >= 60,果然跟英文文法很像。

在學習時,每週大概就教一兩個文法,到了第三個月的時候,該學的文法都學完了,單字也背完了,才真的開始用電腦打字,並且把程式碼編譯後跑起來。由於小時候這些紮實的文法練習,導致後來在寫前端時,我不太需要用到 formatter 或是 linter,例如說 prettier 跟 ESLint 我從來沒用過,因為我不需要。

之前有同事不相信,我就當場寫給他看,寫完 commit 以後他打開 auto format 的功能按下存檔,再用 git diff 看了一下發現是空的,才終於相信我根本不需要這些。就像很多人寫中文也不需要自動排版或是文法檢查一樣,順順地寫完後就已經是最完美的結果,程式語言已經是我的母語了。

隨著接觸的人更多,我才知道像我這樣學程式的人少之又少,再加上我是師父唯一的嫡傳弟子,門派就我一個人,不確定有沒有其他類似的宗派。

在我正式開始工作以後,師父就被大公司找去做程式語言規格編撰的工作,在那裡盡情發揮他的長才。幾年前我跟師父吃飯時,就有問了他這個問題,還有哪些人是用同樣的方法學程式的。

他說在 200 年前我們宗派才是顯學,是武林第一大門派,但後來天魔帶領魔教大舉入侵,正魔大戰後門派迅速衰弱,新武學趁機崛起,秉持著實用的口號,成為了新的流行。

而我們門派只能歸隱深山,靜靜等待預言中的救世主前來復興門派。他說他第一眼看到我,就知道是我了,因此對我的教導特別嚴格,希望我能重新復興門派。

因此我開始寫部落格,開始分享文章,開設臉書粉絲專頁,就是為了等待這一天的到來。當追蹤的人數越來越多,我必定復興門派,讓其重返榮耀。

不用括號執行函式

有種討人厭的東西叫 WAF,全名為 Web Application Firewall,給網站用的防火牆。儘管你找到了可以插入 HTML 的地方,但只要符合 WAF 的判定規則就會直接把你擋掉,讓你沒辦法攻擊。

因此呢,想攻擊的話就要試著繞過 WAF,在各種限制下組出不會被偵測到的 payload。

這次介紹的是「不用 也能執行函式的 JavaScript」

在一般開發者的眼中,執行函式一定會用到 ,不用 怎麼執行?但是有了 template string 以後,可以用一種叫做 tagged template string 的方法去執行,像這樣:alert1

這個實際的應用其實滿廣的,例如說現在有些 library 的用法會是:sqlselect * from users where username=${name} ,看起來是個漏洞,但其實不是, 因為這不只是單純的字串取代,而是會去執行 sql 這個函式,裡面可以做 escape。

除此之外,還有另一種奇技淫巧,那就是把錯誤訊息當成程式碼來執行。

在網頁上,所有沒被捕捉的同步錯誤都會被 window.onerror 接收到,如 Sentry 背後就有用這個。那只要用 onerror=eval,再搭配把錯誤訊息構造成合法的 JavaScript,一樣可以執行任意程式碼。

例如說這樣:onerror=alert;throw ‘hello’; 最後會跳出 Uncaugh hello,那只要改一下把 hello 變成 =alert(1),錯誤訊息就會是「Uncaugh=alert(1)」,把前面的 Uncaugh 當成 global variable 來用。

接著,因為 ‘=alert(1)’ 是個 JavaScript 的字串了,可以改成 ‘=alert\u00281\u0029’,把括號換成 unicode,這樣就能在 payload 中把括號藏起來了,達成我們的目的。

以上是簡單的基本概念,更詳細的解說與更進階的 payload 都在這篇文章裡了,或許可以稱它為花式 JavaScript 吧(還有很多更花的就是了)。

useEffect造成事故

Cloudflare 前幾天出了個事故, dashboard 跟部分 API 都掛了,事故報告出來之後,兇手之一是寫 React 時一定都碰過的 useEffect 😅

在 React 中你可以監聽一些 state 的變化並執行相對應的動作,但有個常見的錯誤是,如果你在裡面又改了監聽的 state ,就會有類似無窮迴圈的效果,一直不斷重複執行

而這次的兇手之一就是這個,dashboard 的前端沒寫好導致 useEffect 一直狂發請求,自己對自己 DDoS,造成後端負荷過大進而影響服務

剛好掛掉的這個 API 又是負責 auth,於是連帶影響其他原本正常的 API

文章裡面其實沒有寫的太詳細,根據 reddit 的討論,看起來像是有問題的前端先發版,而這個 bug 只會出現在 API 有錯誤並且重試的時候,接著再過幾分鐘有問題的後端也發版了,兩個加在一起就形成這個結果了,過多請求導致服務不可用

而 cloudflare 加資源以後暫時恢復,但修復問題時沒修好,上了一版 patch 後又掛了第二次,只好趕緊 rollback 😅

多看幾次故障報告跟討論之後,看起來是現在這樣。稍早之前其實也有 po 但事故原因寫得不太對,有錯的話再來修一下🙇

Chrome VPN洩漏IP

話說在看 YouTube 的時候,時常看到 VPN 的廣告(雖然現在很多都變 eSIM 了…),標榜的功能之一就是能隱藏自己的身份,保護隱私。

開了 VPN,本質上就是讓自己的流量透過 VPN server 再出去,所以對網站來講,只看得到封包是 VPN server 來的,拿到的 IP 也是 VPN server 的,就多少達成了所謂保護隱私的效果(還有一說是,你只是把隱私從暴露給網站,轉成暴露給了 VPN)。

也因為如此,有一類關於 VPN 的漏洞叫做:洩漏使用者 IP,意思就是利用某些漏洞,讓使用者雖然開著 VPN,但網站還是能知道使用者的真實 IP。

七月份的時候看了一篇 0x999 寫的《Leaking IPs in Brave Tor Window & Chrome VPNs + Popunders + CSP Bypass》,紀錄了他發現的兩個這類型的漏洞,而且其實是 Chrome 的問題,回報了各家 VPN 廠商之後總賞金是 7000 美金。

先講一下,大家最常開的 VPN 可能是應用程式,但還有另一種是瀏覽器的擴充套件,如 Chrome extension,裝這個不裝 app 也可以有 VPN 的功能。各家 VPN 廠商的實作都大同小異,就只是使用 Chrome 提供出來的 API 而已(如 chrome.proxy),而 0x999 發現了兩個在 Chrome 上不會走 proxy 的功能,就繞過了幾乎所有 VPN 的防護。

第一個是 service worker 中的 backgroundFetch,第二個是 Web Authentication API 中去拿 /.well-known/webauthn 的時候,這兩個功能都可以指定一個 URL,但是發送請求時不會依照 chrome.proxy 的設定,因此伺服器就可以看到使用者的真實 IP。

不過大多數這類 VPN 的使用者應該都不太在意就是了,畢竟買來可能都只是想跨區追劇用的 😆

NPM釣魚供應鏈攻擊

NPM 又有套件被攻擊啦,這次是直接鎖定特定開發者進行攻擊,利用釣魚的方式駭入他們的 NPM 帳號然後發版。

這次被駭的對象 Josh Junon 底下的套件加起來,一週有 20 億以上的下載次數,會有這麼多下載次數主要還是套件一層一層依賴的關係,例如說幫 terminal 輸出上色的 chalk 以及 ansi-styles,這兩個加起來一週就 6 億下載次數了,有許多套件都有用它們。

那這個釣魚是怎麼釣的呢?

攻擊者註冊了一個 npmjs[dot]help 的 domain,寄了一封「請更新 2FA」的信件給某些開發者,信中說系統偵測你已經 12 個月沒有更新 2FA,由於安全性的考量,若是 9/10 還沒更新的話,帳號將暫時被鎖住以確保安全,請儘速更新你的 2FA。

老實說看起來還真的滿有這麼一回事的,信件本身也做得十分逼真。總之呢,點進去連結以後大概就是要你登入然後更換 2FA,輸入完帳號密碼跟當前 2FA 的時候,駭客就把帳號盜走拿去發布新版惡意套件了。

而這個惡意套件與前幾天提過的 Nx 不同,Nx 的攻擊方式是在開發者主動安裝套件時去攻擊,而這次的攻擊是在 source code 裡面藏一些後門,在以網頁的形式被打開時作用。具體內容是針對加密貨幣,去 hook 各種函式,然後在 sign transaction 以前將地址改掉,錢就轉到駭客那邊去了。

由於這幾個套件很多人用,所以當你的網站安裝到新版套件時,就會自動被植入這個後門,這就是供應鏈攻擊的威力。

可能有些讀者會好奇,怎麼又是 NPM?

其中一個原因大概是這種套件疊床架屋的現象在 NPM 圈特別普遍,2016 年的 left-pad 事件應該不少人經歷過,一個功能超簡單,只是幫字串填充空格的套件,被一堆 library 使用,然後上層又有更多 library,因此這個套件被刪掉時,Babel 壞了,Webpack 也壞了,React 也跟著一起壞,一個接著一個通通壞掉。

其他語言內建的功能以及函式庫相較完整,許多功能不需要額外裝套件就可以用了,但是許多 JavaScript 的 library 靠一堆小套件層層疊起來,導致的結果就是只要攻陷底層那些小專案,就能影響許多上層的東西。

至於身為開發者的我們,要防禦這種攻擊的話,最有效的方式之一大概就是鎖版號了,在 package.json 裡面把版號鎖死,要更新的話手動更新,關掉自動更新功能。

不過就算你沒有自己鎖,只要 lock file 存在,安裝的時候就會照 lock file 裡的安裝,因此影響也不大。想要更嚴謹的話,可以用 npm ci 取代 npm install,當它檢查到你的 package-lock.json 跟 package.json 裡的版本不一致的時候會報錯,要你手動更新 lock file 才會生效,避免意外的升級。原理是類似的,就是不要自動更新就沒事。

還有些更大的公司可能會在內部自己架一個 registry,套件都只能從這裡裝,而內部會定期從外部同步套件回來,在同步前先檢查掃描、審核以及檢查等等,藉此來確保內部使用到的東西都是安全的。

最後呢,這次攻擊跟上次提的 Nx 攻擊,瞄準的目標之一都是加密貨幣,無論是竄改交易也好,偷取私鑰也好,有在用的人記得愛用冷錢包,並且在交易前確保內容是正確的(冷錢包上顯示的目的地要是正確的)。GossiTheDog 也有一篇相關整理可以參考。