<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Huli 隨意聊</title>
  <id>https://blog.huli.tw/notes/</id>
  <link href="https://blog.huli.tw/notes/"/>
  <link rel="self" href="https://blog.huli.tw/notes/atom.xml"/>
  <updated>2026-05-06T12:13:35.657Z</updated>
  <entry>
    <title>神奇的隱形水印</title>
    <id>https://blog.huli.tw/notes/invisible-watermark/</id>
    <link href="https://blog.huli.tw/notes/invisible-watermark/"/>
    <updated>2026-05-06T12:13:35.657Z</updated>
    <published>2026-05-06T12:13:52.000Z</published>
    <content type="html"><![CDATA[<p>今天來聊聊隱形水印這個神奇的東西。</p>
<p>浮水印 watermark 大家應該都聽過，為了防盜圖什麼的很常看到這個，而隱形水印就是「看不見的浮水印」，invisible watermark，明明加了浮水印在圖片上但肉眼看不到。</p>
<p>大家要知道肉眼能辨識出來的東西是有限的，例如說許多圖片的壓縮可以從 2MB 壓到 200KB，大小變成 10% 但是肉眼看到的幾乎一樣。而隱形水印也是在肉眼看起來幾乎相同的前提下，把一些資訊塞到圖片中，你人看是絕對看不出來有這東西的。</p>
<p>隱形水印的應用最常見的有幾個，第一個是追蹤外洩資料的來源，例如說漫畫 APP 想知道盜版網站的圖片是從誰流出去的，就能根據隱形水印找到 user id，第二個是 AI 標記，例如說從 Google 那邊產生的 AI 圖片都會用一個叫做 SynthID 的技術加上隱形水印，你把圖片丟給 Gemini 問他是不是 AI 產生的，他就會檢查。</p>
<p>厲害的隱形水印必須要對抗許多東西，例如說防壓縮，你壓縮完之後隱形水印還在。也要防 resize，你圖片換了個尺寸或是裁切過後也還在。當然，並不是說水印永遠不會消失，還是有可能不見的，但至少保證正常使用下，水印都會在。</p>
<p>除了圖片，影片也可以加隱形水印。</p>
<p>Meta 去年就發了一篇文<a href="https://engineering.fb.com/2025/11/04/video-engineering/video-invisible-watermarking-at-scale/">《Video Invisible Watermarking at Scale》</a>，講他們是怎麼做的，而主要的應用情境是在「誰第一個發這個影片」，這個應用滿不錯的，可以防止那種二次轉發想賺流量的，你把別人影片偷過來重發，就算剪輯了，還是能辨識出原始的上傳者是誰。</p>
<p>雖然圖片跟影片都行，但文字呢？文字要怎麼藏東西在裡面？</p>
<p>有種做法是用零寬字元，藏幾個看不見的字元在裡面，但問題是如果文字流出的方式是截圖就看不出來。也可以些微更改標點、排版或是同義字等等，來對抗這種截圖流出的方式，但這個就是肉眼可見了，你拿發給不同人的內容來看就會看到差異，不過這也沒辦法。</p>
<p>而針對 LLM 所產生的文字，Google 的 <a href="https://www.nature.com/articles/s41586-024-08025-4">SynthID</a> 技術也有 cover 到（真的好強，趕快多買一點 GGLL，我都直接兩倍槓桿），LLM 的原理就是不斷去預測下一個 token 是什麼嘛，然後每一次都會有多個候選，例如說「我喜歡吃」後面可能接「鳳梨」、「牛肉麵」、「章魚燒」等等，而 SynthID 就是在這個階段介入，用你想藏的文字算出一個 random seed，再搭配這個隨機亂數，讓每次的選擇都偏移一點，在文字越長的狀況下，統計來看就會越明顯。</p>
<p>簡單來講，就是讓 LLM 在選擇文字時會有特定偏好，但這個偏好小到你人類幾乎看不出來。跟「不是…而是…」這種被講到爛的 pattern 不一樣。</p>
<p>這個做法真的滿有趣的，可以做到人看不出來但是又根據 LLM 的特性塞了額外資訊在裡面。</p>
]]></content>
  </entry>
  <entry>
    <title>Linux 提權漏洞解析</title>
    <id>https://blog.huli.tw/notes/linux-copy-fail/</id>
    <link href="https://blog.huli.tw/notes/linux-copy-fail/"/>
    <updated>2026-05-06T04:48:47.552Z</updated>
    <published>2026-04-30T12:21:26.000Z</published>
    <content type="html"><![CDATA[<p>今天剛看到 Linux 最新被爆出來的提權漏洞 CVE-2026-31431，又稱作 <a href="https://xint.io/blog/copy-fail-linux-distributions">Copy Fail</a>，利用方式簡單容易。</p>
<p>用白話文講的話，你原本把重要文件放左邊，白紙放右邊，讀完左邊文件之後，在右邊白紙寫下筆記。</p>
<p>但你有天突然覺得這樣很不方便，比起左右放，還是上下放更好，於是上面放白紙，下面放文件，結果白紙寫著寫著寫滿了，不小心多寫了一些字在重要文件上面，文件的內容就被修改了。就因為這個不小心，重要文件的內容被改動，就成了一個漏洞。</p>
<p>修法很簡單，不要把兩張紙上下放在一起就好，讀就是讀，寫就是寫，要寫就寫白紙上，不讓你寫到重要文件去。</p>
<p>技術細節的話，這個 bug 出在 Linux kernel 的 authencesn 功能，是拿來做加解密的。正常狀況下，你丟給他一段密文跟 key，他就會把解密的結果寫到 buffer 後還給你。</p>
<p>正常來講讀寫是分開的兩塊 buffer，但由於 2017 年的一個改動，讀跟寫的 buffer 指到了同一塊記憶體，然後 authencesn 的實作又被發現了一個 4 bytes 的 overwrite。</p>
<p>所以你先用 splice 拿到 &#x2F;usr&#x2F;bin&#x2F;su 的 page cache reference，當成 input 丟給 authencesn，接著再利用那個 overwrite，就可以蓋掉 su 在 page cache 中的內容，等於是修改 su 的程式碼。</p>
<p>蓋完之後再執行 &#x2F;usr&#x2F;bin&#x2F;su，就順利 root 了。</p>
<p>整個 exploit 的重點在於可以寫到任意的 page cache，所以把你想改的 program 用 splice 拿到 page cache reference 後，就可以丟給 authencesn 用 bug 去覆蓋 page cache。</p>
<p>最後修法是把那個 in-place 的改動拿掉，不讓你寫 page cache。</p>
<p>（我完全不懂 Linux kernel，技術細節是反覆看 writeup 以及與 AI 討論得出來的，細節必有不精確之處，有錯的地方歡迎留言指正，讓我多學習一些 Linux 知識）</p>
]]></content>
  </entry>
  <entry>
    <title>身分證字號不是鍵</title>
    <id>https://blog.huli.tw/notes/id-number-not-key/</id>
    <link href="https://blog.huli.tw/notes/id-number-not-key/"/>
    <updated>2026-05-06T04:48:47.550Z</updated>
    <published>2026-04-30T11:07:37.000Z</published>
    <content type="html"><![CDATA[<p>這兩天看到一個在講身分證字號的新聞，三年前台灣個資外洩的新聞爆發之後，有人因為這個去申請改身分證字號，被行政機關駁回後提起訴願，然後打行政訴訟，最後打贏了，可以更換身分證字號。</p>
<p>讓我想起以前看過的法律白話文運動的貼文，尾數是 4 或是含有三個以上的 4，也能修改身分證字號。</p>
<p>由此可見，身分證字號是會變的，所以存在系統的時候不要用這個當 key，否則會出問題。</p>
<p>還有另外一個理由是，身分證字號是有可能會重複的。</p>
<p>以前人工作業時抄寫錯誤等問題，導致同一個身分證字號可能出現在兩個人身上（隨手搜一下就很多資料了），就需要有一個人去改。</p>
<p>總之呢，身分證字號既不 primary 也不 unique。</p>
<p>參考資料：<a href="https://www.cw.com.tw/article/5140846">https://www.cw.com.tw/article/5140846</a></p>
]]></content>
  </entry>
  <entry>
    <title>用 Agent 清理硬碟</title>
    <id>https://blog.huli.tw/notes/agent-disk-cleanup/</id>
    <link href="https://blog.huli.tw/notes/agent-disk-cleanup/"/>
    <updated>2026-05-06T04:48:47.540Z</updated>
    <published>2026-04-09T12:22:52.000Z</published>
    <content type="html"><![CDATA[<p>話說 agent 是真的很方便<br>以前我電腦容量快滿的時候，不想去下載一堆感覺就不太安全的 cleaner，也懶得裝一些開源的軟體去掃</p>
<p>但有了 agent 之後，我現在都直接讓 agent 做了<br>就打開 cursor CLI 跟他說我空間快滿了，幫我找找哪些地方佔空間<br>他就會開始跑跑跑透過各種指令去看空間分佈</p>
<p>掃了大概 10 分鐘就給了份報告，跟我說 npm 的快取就 10GB 了，pnpm 5GB，Go 的也有個 2GB，Playwright 也有 10GB，超多版本的 Chromium 都在裡面，大概裝了二十個。</p>
<p>總之就是各種應用程式的快取佔了一堆空間，最後幫我分析哪些可以清掉，但最後清掉的指令跟刪除還是我自己來執行，他只幫我分析而已。</p>
<p>刪完再跑一次就跟我說少了多少空間，哪裡還可以在刪等等，真滴方便。</p>
]]></content>
  </entry>
  <entry>
    <title>Claude 訂閱與工具限制</title>
    <id>https://blog.huli.tw/notes/claude-subscription-tools/</id>
    <link href="https://blog.huli.tw/notes/claude-subscription-tools/"/>
    <updated>2026-05-06T04:48:47.547Z</updated>
    <published>2026-04-04T11:02:03.000Z</published>
    <content type="html"><![CDATA[<p>4&#x2F;6 07:00 更新：</p>
<p>一早起來看到 Peter Steinberger 的<a href="https://x.com/EricBuess/status/2040207443636973927">推文</a>，就算用 claude -p 只要你帶上 OpenClaw 的 system prompt 還是會被 ban，所以之前我的理解可能有些偏差，就算你自己 claude -p 給龍蝦用也還是不行（Peter Steinberger 原本也以為可以  😂）</p>
<p>雖然說只要把那段字串稍微改一下就會過，但官方的態度就擺在那裡。之後等等看有沒有個官方聲明好了，再繼續更新這篇貼文。</p>
<p>&#x3D;&#x3D;&#x3D;</p>
<p>小聊一下 Claude 訂閱制把第三方工具 ban 掉這件事</p>
<p>如果我的理解沒錯，無論是 Claude 的訂閱方案也好，還是 Google Antigravity 的訂閱方案，使用規則都是一樣的，那就是禁止你把訂閱方案的 token 拿去其他非官方工具用。</p>
<p>其實最大的那幾間，所謂固定費用的「訂閱制」，本來就不是針對模型本身，而是針對產品，是讓你使用他們產品的時候可以用得更多，卻只需要付出固定費用。若是你有其他客製化需求，就是去接 API，一律使用 API key 的方案按量收費，否則就是違反使用條款。</p>
<p>Claude 的立場從以前就這樣了，上次對 OpenCode 也是一樣，不是不能用 Claude 模型，而是你不能用訂閱制拿到的 token 去使用，要用的話就要用 API key。</p>
<p>有用過的都知道，認真在用的話訂閱制一定是比 API key 便宜的，一些 AI 中轉站的原理就是這樣，背後有一堆訂閱制的帳號，然後把 auth token 拿出來轉成呼叫 API 的形式，用這些固定費用的帳號創造出更大的利益來賺價差（顯然不符合官方使用條款）。</p>
<p>雖然可以理解訂閱制與 API 的差異以及官方的考量，但身為使用者的我們當然還是想省錢，除了換個模型以外還有其他做法嗎？</p>
<p>有的，第一個是用 OpenAI 的 codex 訂閱方案，OpenAI 目前並沒有禁止把訂閱方案用在 OpenClaw 上面，所以我之前架小龍蝦來玩，第一件事情就是訂閱 codex 方案。</p>
<p>如果你是開發者想要寫一點自己的服務，那正解就是參考 Paperclip 的做法，與其接入 AI 模型，不如接入 AI agent。在 Paperclip 的模式中，他直接接入 codex 或是 Claude Code 等工具，幫每一種工具做一個 adapter，然後用 headless mode 跑起來。</p>
<p>換句話說，當你建立一個任務時，背後是直接去跑 claude -p “analyze this repo for security issues” 並把結果回傳。因此最後跟 Claude 模型的互動還是透過 Claude Code，這是完全符合規則的。</p>
<p>面一些論述的出處做為佐證。</p>
<p>參考資料：<a href="https://x.com/steipete/status/2024182608746217953">https://x.com/steipete/status/2024182608746217953</a></p>
]]></content>
  </entry>
  <entry>
    <title>Blockly 翻譯鬧笑話</title>
    <id>https://blog.huli.tw/notes/blockly-translation-fail/</id>
    <link href="https://blog.huli.tw/notes/blockly-translation-fail/"/>
    <updated>2026-05-06T04:48:47.545Z</updated>
    <published>2026-04-01T12:57:19.000Z</published>
    <content type="html"><![CDATA[<p>今天突然想查 Scratch 用的那套可以用類似拼圖的方式寫程式的東西叫什麼，我記得有人有開源出來，查一查發現 Google 開源了一個叫做 Blockly。</p>
<p>於是我就去官網看了看介紹，看到底下這段超級突兀：</p>
<p>「禁止使用網頁版」</p>
<p>我就想了想為什麼要禁止使用，還要當成一個功能來宣傳，把語言切成英文後恍然大悟：「Blockly for web」…</p>
<p>底下那個「為什麼要封鎖」，也理所當然的是「Why Blockly」。</p>
<p>真有你的，Google。</p>
]]></content>
  </entry>
  <entry>
    <title>Claude Code 原始碼外洩</title>
    <id>https://blog.huli.tw/notes/claude-code-sourcemaps/</id>
    <link href="https://blog.huli.tw/notes/claude-code-sourcemaps/"/>
    <updated>2026-05-06T04:48:47.547Z</updated>
    <published>2026-04-01T12:25:28.000Z</published>
    <content type="html"><![CDATA[<p>今天早上看到 Claude Code 原始碼因為 source maps 外洩的消息，我第一個反應是：「咦？難道以前沒有人試著還原過？」</p>
<p>Claude Code 的程式碼雖然沒有開源，但其實就是個 13MB 的 cli.js 檔案，俗話說的好，client 端的東西沒有秘密，而且還是最容易還原的 JavaScript，那以 Claude Code 這麼有名的東西來說，不可能沒人研究過吧，怎麼就變驚天的重磅消息了，好像知道了許多以前不可能看見的東西。</p>
<p>經過了一整天的思考，這想法其實半對半錯，聽我娓娓道來。</p>
<p>先來講講 source maps 是什麼，前端的程式碼需要用 bundler 打包在一起，打包完之後會做 minify 跟 uglify 等操作，去掉所有多的空白、換行，然後把變數名稱都變成 a,b,c 那種可讀性低的格式，最後的產物才會傳上去。</p>
<p>但既然程式碼可讀性都變這麼差了，要 debug 的時候怎麼辦呢？這時候就需要把這些 minify 過的程式碼還原成原本的樣子，靠的就是這個 source maps 的檔案，裡面記錄著原始的程式碼以及對應關係，靠這個檔案就能對應出原本的 a2 其實是 API_URL 這個變數。</p>
<p>所以若是 source maps 裡面記錄著檔案路徑以及內容，這個檔案洩漏就等於是原始碼洩漏了，這就是此次 Claude Code 發生的事故。一般常見的做法是 build 完一樣產生 source maps，但是不上傳到外面，只上傳到 Sentry, Datadog 等專門做錯誤處理的地方，在那邊還原，就能確保原始碼不外洩，又能方便 debug。</p>
<p>這邊再提一個概念，有些人會把 minify 跟「混淆（Obfuscate）」混在一起，這兩個概念不一樣。混淆指的是特地把程式碼再轉換一層，你光看是絕對看不懂的，惡意軟體就常幹這種事。而 minify 更像是把程式碼的體積縮小，你認真看還是能大概看出它在幹嘛，我看過很多遍了。</p>
<p>所以，Claude Code 大部分的功能，你根本不需要 source maps，你直接拿 AI 丟給他 cli.js（或先稍微處理過），他就可以回答你了，該有的邏輯都在那邊。</p>
<p>那到底有哪些東西會在打包的時候被去掉，讓這些資訊徹底消失呢？最顯而易見的就是變數名稱、函式名稱、檔案路徑等等，以及最重要的：註解。</p>
<p>程式碼裡面的註解在打包後會完全被去掉，而 source maps 裡面則被保留。以及另一個我朋友提醒我才想到的：dead code。</p>
<p>Dead code 指的是永遠不會被執行的程式碼，例如說 if(false) { … }，這段永遠不成立。那為什麼有人會寫出這種程式碼呢？通常原始形式其實是這樣：if (Flag.Internal) { … }，然後在 build 的時候把 Flag.Internal 換成 true 或 false，藉由 feature flags 的方式在 build time 開關，藉此 build 出不同的版本。</p>
<p>如果 Flag.Internal 是 false，那最後的產物就會直接把程式碼去掉。但是呢，由於 source maps 保存的是原始檔案的整個內容，因此這些 dead code 還會在。</p>
<p>總而言之，這次外洩的 source maps 跟原先打包後的版本比起來，多了以前絕不可能看到的註解與打包時被移除的 dead code，也還原了變數名稱與檔案路徑。</p>
<p>換句話說，很多人寫的什麼「Claude Code 的隱藏功能」也不是真的隱藏，只是大家懶得去看打包後的版本而已。</p>
<p>之所以我敢寫得這麼肯定，是因為我去試過了。外洩的版本是 2.1.88，我抓的是 2.1.87，我先讓 AI 幫我研究 Bun 的 bundler 邏輯，然後寫一個 reverse 版本，先把 cli.js 還原成 50 個小檔案，然後讓 AI 再根據這些檔案幫我還原成合理的形式。</p>
<p>接著我讓 AI 整理幾篇網路文章提到的隱藏功能，讓他去找找在不在程式碼裡面。</p>
<p>關於那些註解、內部代號或是特殊 flag 才能開啟的功能，確實不存在。例如說什麼內部代號 Capybara、Fennec、Numbat 等等，還有 Undercover Mode 跟反蒸餾防禦，這些都找不到。</p>
<p>但是今天上線的 BUDDY 電子寵物系統、KAIROS、ULTRAPLAN 或是記憶管理、壓縮邏輯等等，這些都是有的，本來就存在了。</p>
<p>所以呢，如果有人有心想研究的話，Claude Code 的這些運作邏輯一直在那，事實上也有人逆向過了，這些都不是新鮮事，只是大家懶得去做而已。那些 prompt 啦，記憶系統啦，agent 協作啦，bash 的檢查啦，憤怒語言偵測器啦，不需要 source maps 外流你就看得到。</p>
<p>真正全新的東西是那些註解裡面寫的經驗、內部代號以及 build time 被砍掉的隱藏功能，這些確實是只有透過 source maps 能看到的。</p>
<p>寫了這麼多，我只是好奇心使然，想去探索到底有哪些東西是新的、真的外洩的，哪些東西又只是「你想研究一直都在，只是現在不用自己還原」，也順便測一下 AI 的能力（還原 bundle 過的程式碼）。無論如何，原始碼外洩對於想研究的人絕對是利多，不用自己去試著還原或是猜測，有原始碼什麼都好辦。</p>
<p>或許在某個平行時空，有個好奇的人辛辛苦苦逆向了 Claude Code 把架構還原，準備跟大家分享成果，結果一覺醒來發現原始碼外流了，每個人用 AI 產的文都跟自己苦心研究的成果類似，只能躲回被子裡哭。</p>
]]></content>
  </entry>
  <entry>
    <title>Trivy 供應鏈攻擊</title>
    <id>https://blog.huli.tw/notes/trivy-supply-chain/</id>
    <link href="https://blog.huli.tw/notes/trivy-supply-chain/"/>
    <updated>2026-05-06T04:48:47.558Z</updated>
    <published>2026-03-25T12:04:07.000Z</published>
    <content type="html"><![CDATA[<p>剛好整起事件都有跟到，來聊一下 Trivy 跟最近的大規模供應鏈攻擊事件。</p>
<p>Trivy 是個資安公司 Aqua Security 出的開源掃描工具，最常用的是拿來掃 IaC 的程式碼或是 image 之類的，我自己就用過不少次。</p>
<p>在 2 月底的時候 Trivy 的 GitHub 被攻擊，因為 CI 流程有漏洞，所以發個 PR 就可以偷到 token，這類攻擊通常被叫做 Pwn Request，以前也出現過不少次，而這次的攻擊其實不只有 Trivy 受害，一堆 repo 也被攻擊了。</p>
<p>攻擊的帳號叫做 hackerbot-claw，跟上了前陣子正熱的小龍蝦熱潮，我那時看到消息還想說是不是哪個資安研究員在做研究 😆</p>
<p>過了幾週，到了 3&#x2F;19 左右，駭客正式發起攻擊，透過 2 月底偷到的 token 直接幫 Trivy 發個含有惡意程式碼的新版本，甚至更狠地還把舊的 tag 全部都 push 一遍。</p>
<p>有些人已經有意識到這類型的供應鏈攻擊風險，在使用一些套件時會寫死版本號如 <a href="mailto:&#116;&#x72;&#x69;&#x76;&#121;&#x40;&#x31;&#x2e;&#50;&#46;&#51;">&#116;&#x72;&#x69;&#x76;&#121;&#x40;&#x31;&#x2e;&#50;&#46;&#51;</a>，這個通常是沒問題的，因為許多 package manager 會保證版本不可篡改，例如說 NPM。</p>
<p>但是 GitHub <a href="https://docs.github.com/en/actions/reference/security/secure-use">Actions</a> 沒這功能，他的版本只是一個 tag，背後東西是可以換的。所以你在使用 action 時寫死 tag 也沒用，要寫死 commit hash，這我也是今天才知道的，之前沒注意到這個差異。</p>
<p>看到這邊我相信大家都有個疑惑的點，那就是為什麼二月底被駭，理論上已經清理過一輪了，怎麼 3 月底又來一次，而且還是用二月就被偷的 token。</p>
<p>官方聲明是這樣寫的：We rotated secrets and tokens, but the process wasn’t atomic and attackers may have been privy to refreshed tokens</p>
<p>具體是什麼狀況沒講，但總之應該就是換的時候沒換好，導致攻擊者也能拿到新的 token。雖然說大家都會犯錯，但是一個資安公司連錯兩次，客戶對他們的信任度可能掉了不少…</p>
<p>總之呢，開頭提過 Trivy 是掃描工具，所以一堆專案都有裝這個，那自然也一堆專案直接被入侵。為了安全裝了資安掃描工具，卻因為裝了這個被入侵，有點諷刺。</p>
<p>而目前最新的受害者是今早才爆出來的 Python 套件 LiteLLM，被入侵的管道就是之前 Trivy 被駭的時候偷到了maintainer 的 token，就利用了這個 token 發布惡意版本。</p>
<p>就是巢狀供應鏈攻擊啦，先打下一個套件，再打下用這個套件的套件，以此類推，越打越多，影響也越來越大。雖然說 LiteLLM 有問題的版本已經被快速下架，但是大多數人（包含我）都猜測攻擊還沒停止，一定會有下一波的到來，請大家多多注意。</p>
<p>防範的方式還是老樣子：</p>
<ol>
<li>安裝套件的時候永遠固定版本</li>
<li>承上，在某些版本不是 immutable 的情境下要固定 hash（如 GitHub Actions）</li>
</ol>
<p>如果要安裝的專案是別人的，別人沒有寫死的話，也建議加減裝個 socket 之類的，在下載後似乎會先做一些基本掃描，也算是多少有防到。想更安全的話就是在 VM 或是 docker container 裡面裝，至少能保證影響範圍有限。</p>
<p>話說單個套件被打就已經這麼恐怖了，何況是整個 package manager 都被打下來。之前在 DEVCORE CONFERENCE 2026 聽到 splitline 的議程，就是在講直接去把整個 package manager 打下來，而且成功了不少，涵蓋一堆程式語言。簡報要四月底左右才會公開，到時公開了再來分享一波。</p>
<p>參考資料：<a href="https://snyk.io/articles/poisoned-security-scanner-backdooring-litellm/">https://snyk.io/articles/poisoned-security-scanner-backdooring-litellm/</a></p>
]]></content>
  </entry>
  <entry>
    <title>把 DOOM 藏進 DNS</title>
    <id>https://blog.huli.tw/notes/doom-over-dns/</id>
    <link href="https://blog.huli.tw/notes/doom-over-dns/"/>
    <updated>2026-05-06T04:48:47.549Z</updated>
    <published>2026-03-24T12:04:30.000Z</published>
    <content type="html"><![CDATA[<p>剛看到一個國外的資安工程師 Adam Rice 因為太喜歡 DNS 了，所以乾脆把 <a href="https://blog.rice.is/post/doom-over-dns/">DOOM</a> 毀滅戰士放在上面，只要依序解析 DNS TXT 紀錄就可以抓下來跑 😆</p>
<p>先來講講 DOOM 毀滅戰士這個遊戲，如同原文所提到的，一堆神人會在各種地方試著把 DOOM 跑起來，例如說有數位螢幕的驗孕棒或者是電動飛機杯之類的。</p>
<p>而 DNS TXT 紀錄本質上就是個字串，每條紀錄可以放 2000 個字元左右，所以把 DOOM 的主程式壓縮一下再轉成 base64 約 3MB ，作者用了將近 2000 條 DNS 紀錄把它給放進去。</p>
<p>最後，只要寫個 PowerShell script 去解析 DNS 拼接成一個大字串，在記憶體裡面解碼然後解壓縮，就能直接把 DOOM 跑起來，做到檔案不落地，直接在記憶體裡面跑。</p>
<p>更多技術細節在原文，然後原始碼也有開源到 GitHub 上。</p>
]]></content>
  </entry>
  <entry>
    <title>Coupang 外洩與金鑰</title>
    <id>https://blog.huli.tw/notes/coupang-key-leak/</id>
    <link href="https://blog.huli.tw/notes/coupang-key-leak/"/>
    <updated>2026-05-06T04:48:47.548Z</updated>
    <published>2026-03-19T11:20:19.000Z</published>
    <content type="html"><![CDATA[<p>今天從技術的觀點來聊前陣子沸沸揚揚的 <a href="https://blog.huli.tw/2026/03/19/coupang-insider-kms-and-jwt/">Coupang</a> 個資外洩事件。</p>
<p>其實已經寫一篇完整的部落格文章了，懶得看全文的話，就看我這篇精簡版吧。</p>
<p>Coupang 是個韓國電商，在台灣也有設點，去年發生個資外洩事件，韓國那邊的調查已經告一個段落，而近期因為台灣也有受影響，所以數發部介入，目前劇情大概到這裡。</p>
<p>相關的技術細節韓國的報告寫得很清楚，這整起事件的攻擊者並非外部駭客，而是一個離職的前員工，而且還是開發備援 auth 系統的 Staff Back-end Engineer（但他做這件事的動機新聞跟調查都沒寫）。</p>
<p>Coupang 的驗證系統在登入過後會發一個類似 JWT token 的東西，直接在裡面帶上會員 id 之類的，下次就只驗這個 token 是否合法。因此，只要能拿到簽這個 token 的 key，就能偽造任何人的身份，不用登入就獲得相關權限。</p>
<p>而這個離職員工就是利用這種方式，還在職時拿到了這把 key，偷偷帶走，離職後拿來偽造出 token，就能進入 my information 之類的頁面看到個資。</p>
<p>所以呢，這整起事件就是負責開發 auth 系統的主任後端工程師，在離職後用在職時取得的 auth 系統 signing key 搞出來的。</p>
<p>接著可以從兩個角度聊，一是 key 該怎麼管才安全，二是這種驗證方式本身是不是有點問題。</p>
<p>管 key 的話，有很多公司都會用 vault 或 secret manager 之類的東西管，然後讓 SRE 或開發者自己產一把 key 放進去。雖然說放到 vault 後取用是安全的，但產 key 的時候已經有幾個人知道了。雖然說 insider 的風險跟其他比沒這麼高，比較容易被查出來，但若是發生了，外部也不會管你到底為什麼出事。</p>
<p>所以不只是儲存跟使用，在產生 key 的時候也要注意，最安全的是用 HSM 儲存 key 外加 KMS 管理，key 本身從不離開這個系統，但相對的成本也會高一點。</p>
<p>也可以先從 key rotation 做起，當這些能碰到的人離職時，把能碰到的 key 都先換過一輪，雖然在職時還是能碰到 key，但至少讓他們離職後自動喪失所有權限。</p>
<p>再來，key 被偷就整個 auth 系統 gg，聽起來似乎不太合理。</p>
<p>以傳統 session 做法來說，你保存一個 session id，每次後端查表，session id 若是不可預測，你拿到 signed cookie 的 key 也沒用。JWT 其實也是，你如果在 token 裡存的是 session id 也一樣。</p>
<p>但現在許多系統 JWT 是存 session data 的，裡面直接放 email 或 user id 這些可預測的東西。在這個前提下，保護 key 就變成非常重要的一件事情，而且 private key 跟 public key 都要保護。前者保證不被洩漏，後者保證不被置換。</p>
<p>我相信有許多公司在產 key 這段多少都有點問題，許多都是我前面說的，由人產完再放進去 secret manager。況且也沒這麼多公司有資源專門去弄個 KMS（或甚至沒想到可以這樣或需要這樣做）。</p>
<p>這些都是風險，都會回到風險管理的框架去討論，不少公司目前選擇的是接受風險，亦即承認風險的存在，但因發生機率小所以先不處理。若是真的有哪個能碰到這些的離職員工偷偷帶了一份資料走，那類似的事情很可能又會重演。</p>
<p>總結就是：</p>
<ol>
<li>key 的完整生命流程要注意，尤其是產生的時候</li>
<li>使用 stateless JWT 有個風險是 key 被偷走就 gg，要記得</li>
<li>考慮風險時，除了外部攻擊者，也要考慮 insider threat</li>
</ol>
<p>看完想知道更多細節的話，可以再回去快速看過部落格完整版</p>
<p>補充文章：<a href="https://www.msit.go.kr/eng/bbs/view.do;jsessionid=iMyzX8C42zedbf27PtWxq844qjcyYy0VOCt74FEO.AP_msit_2?sCode=eng&amp;mPid=2&amp;mId=4&amp;bbsSeqNo=42&amp;nttSeqNo=1221&amp;utm_source=perplexity">https://www.msit.go.kr/eng/bbs/view.do;jsessionid=iMyzX8C42zedbf27PtWxq844qjcyYy0VOCt74FEO.AP_msit_2?sCode=eng&amp;mPid=2&amp;mId=4&amp;bbsSeqNo=42&amp;nttSeqNo=1221&amp;utm_source=perplexity</a></p>
]]></content>
  </entry>
  <entry>
    <title>這裡不是 AI 洗稿場</title>
    <id>https://blog.huli.tw/notes/not-ai-content-farm/</id>
    <link href="https://blog.huli.tw/notes/not-ai-content-farm/"/>
    <updated>2026-05-06T04:48:47.554Z</updated>
    <published>2026-03-18T11:23:33.000Z</published>
    <content type="html"><![CDATA[<p>不好意思，你找錯地方了</p>
<p>這裡不是接入 AI，自動搜集新聞，自動改寫文章洗稿抄襲的地方</p>
<p>你找錯地方了</p>
<p>這裡不是視著作權於無物，直接翻譯國外文章或影片然後全文轉貼，又不附出處的地方</p>
<p>你還是找錯地方了</p>
<p>這裡不是用 AI 寫一堆故事，下聳動標題，不查證真實性，只管故事本身能否吸引流量的地方</p>
<p>你真的找錯地方了</p>
<p>這裡不是一直說自己 AI 用得有多厲害多跟別人不一樣，然後賣你課程的地方</p>
<p>就跟你說你找錯地方了</p>
<p>這裡不是每天發一堆 AI 新聞，每天都分享人類文明的重大突破，販賣焦慮的地方</p>
<p>喔喔喔，這次你總算找對了</p>
<p>這裡是想不出聳動的吸引人的標題、跟不上時代，就算寫得比 AI 差還是遵循古法手工製造的，我一個人發廢文的地方</p>
]]></content>
  </entry>
  <entry>
    <title>GlassWorm 木馬攻擊</title>
    <id>https://blog.huli.tw/notes/glassworm-developer-malware/</id>
    <link href="https://blog.huli.tw/notes/glassworm-developer-malware/"/>
    <updated>2026-05-06T04:48:47.550Z</updated>
    <published>2026-03-16T10:53:51.000Z</published>
    <content type="html"><![CDATA[<p>最近有認識的朋友中了木馬，本機 token 被偷光以後，直接往 GitHub 上的 repo 推了惡意程式碼，因為好奇就跑去稍微看了一下。</p>
<p>推的 code 是一段 JavaScript，會在 postinstall 的時候執行，惡意程式碼本身是用 unicode 的不可見字元，再寫一段 JS 還原然後丟給 eval，所以把 eval 改成 console.log 就能看到跑了什麼。</p>
<p>而這段程式碼解出來之後，是一段用 AES fixed key 解密另一個 payload 再丟一次 eval 的程式碼，所以要再改成 console.log 跑一次。</p>
<p>跑完之後還沒結束，會看到一段去呼叫 blockchain 的 API，從 Solana 的某個固定地址拿 memo，拿到的內容是一個 IP，接著連線到 IP 之後又拿一段 payload 回來，再丟到 eval。我連過去的時候被擋掉了，所以也沒看到具體 payload。</p>
<p>上網查了一下發現這是個叫 <a href="https://socket.dev/blog/open-vsx-transitive-glassworm-campaign">GlassWorm</a> 的已知木馬，專門打開發者的，透過 VSCode 的擴充套件打進來。而我朋友中的這波是上週才發生的最新一波攻擊。</p>
<p>這次的攻擊是先發佈一些看似無害的套件，接著在升級時偷偷在 manifest 裡面加上惡意的 dependency，升級後 VSCode 就會自動下載，然後就中招了。</p>
<p>中了之後就會把你電腦裡的東西都偷過一輪，然後再去感染其他人。就像我開頭講的那樣，直接把你有權限的 GitHub repo 都 push 一遍，若是有哪個觸發 CI 甚至自動發版了，那就又擴散出去了，因此才會稱為是 worm。</p>
<p>這類攻擊感覺一直不斷發生，無論是 NPM 的 supply chain attack，或是針對 VSCode 套件本身的攻擊，都是專門打開發者，一不小心的話很容易中招。</p>
<p>也因為如此，我自己的 VSCode 幾乎都不安裝套件了，只裝官方而且夠大的，其他就算了。也把自動更新都關掉，避免新版帶奇怪的東西進來。</p>
<p>話說，現在好像越來越多人直接 CLI 寫 code，甚至連 editor 都不用了，因為寫完不用看直接上，其實也算是某種程度防範了這個風險 😆</p>
<p>不過取而代之的就會是一些惡意的 MCP 或 skill 等等，不小心跑了也一樣會有事。相關報導跟這次中招的套件，大家可以自己檢查一波。</p>
]]></content>
  </entry>
  <entry>
    <title>Snaps 簽交易漏洞</title>
    <id>https://blog.huli.tw/notes/metamask-snaps-bug/</id>
    <link href="https://blog.huli.tw/notes/metamask-snaps-bug/"/>
    <updated>2026-05-06T04:48:47.553Z</updated>
    <published>2026-03-13T09:52:25.000Z</published>
    <content type="html"><![CDATA[<p>在加密貨幣的世界中，MetaMask 大概是最知名的軟體錢包了。而 MetaMask 除了本身提供的那些功能以外，還提供了叫做 Snaps 的 plugin 系統，可以讓開發者在 MetaMask 上面新增功能。</p>
<p>MetaMask 是瀏覽器的 plugin，然後本身又提供了 plugin，一層疊一層，厲害吧。</p>
<p>那有什麼功能會需要往 MetaMask 上面加呢？</p>
<p>舉例來說，有些 blockchain 用的技術沒有被 MetaMask 原生支援，因此這些鏈如果想做錢包的話，要嘛自己再做一個新的擴充套件，要嘛用 Snaps 加到 MetaMask 上。</p>
<p>由於 MetaMask 實在是太多人用了，因此大多數人都選擇後者，做一個 plugin 來幫它加功能，讓它支援更多種不同的 chain，例如說 MetaMask 背後的公司 Consensys，就做了個給 Starknet 用的 Snaps 錢包，讓大家可以在這上面使用 Starknet。</p>
<p>今天有份漏洞<a href="https://hackerone.com/reports/3507241">報告</a>被揭露，有人發現這個 Starknet Snaps 在發起交易時，支援一個叫做 enableAuthorize 的參數，正常狀況下是 true，MetaMask UI 就會顯示確認視窗。</p>
<p>但如果這個參數傳 false，就不會顯示確認視窗而是直接 sign transaction。換句話說，如果有人不小心在某個網站上連接了 Starknet Snaps，在連接之後攻擊者就可以直接用這個參數繞過確認，在使用者不知道的狀況下發起交易，進而把裡面的錢偷走。</p>
<p>而這個「連接」就像是你在網站上要使用 MetaMask 錢包會跳出的視窗一樣，不是個太敏感的操作（我認為啦），網站要拿錢包地址也需要先連接，否則什麼都拿不到。這個連接跟授權交易完全是兩回事，前者雖然要使用者點擊，但門檻低。</p>
<p>總之呢，假設我做了一個 Dapp 跟大家說來連接 Starknet Snaps 就送獎金，只要連接拿地址登記就好，散佈出去，若是有人裝了這個 Snaps，在點擊連接後就能自動幫他簽交易把錢偷走。</p>
<p>問題來了，這樣的漏洞嚴重程度是多少，賞金又是多少呢？</p>
<p>答案是 medium 以及 350 塊美金 😆</p>
<p>原本 Hackerone 的人員還評估成 low，之後是 Consensys 的人改成 medium，但我怎麼看至少都應該是 high 才對。</p>
<p>官方給的理由是：</p>
<ol>
<li>使用者必須有裝Starknet Snap</li>
<li>使用者要 connect</li>
<li>downstream dApp behavior for financial impact</li>
</ol>
<p>第一點簡直是聽君一席話如聽一席話的典範，我不就是回報這個程式的漏洞嗎。</p>
<p>第二點我上面講過了，我覺得門檻沒這麼高。</p>
<p>第三點我就沒有看懂了，不知道是不是我對 Starknet 了解有誤？在我的認知中，只要能簽交易就能偷錢了，我自己做個惡意 dApp 不就好了嗎？難道不是？</p>
<p>總之，在我反駁之後官方沒有繼續給回覆，我就請求公開漏洞了，官方還是沒回覆，因此現在一個月後自動公開。他們很多漏洞都沒公開的，我猜他們可能連看都不看根本不 follow 了，也沒有管後續 😂</p>
<p>喔，對啦，那個回報的人就是我，碰巧看到的洞而已。，歡迎一起來看看報告。</p>
<p>然後另一個我覺得滿值得聊的是 CVSS 對於 Web3 的適用程度，我都可以偷錢了，結果拿 CVSS 給我評個不影響 confidentiality 跟 availability，然後 integrity low。</p>
<p>你要這樣講不是不行啦，我只能簽交易確實可能不影響那些，但這個洞怎麼看都不會是 low。這代表在 Web3 相關的情境下，針對傳統漏洞的 CVSS 沒辦法很好的判斷嚴重程度，沒有把資產損失這點考慮進去。</p>
<p>而大多數時候我也不會看到有人硬要把 CVSS 拿去套那些加密貨幣的漏洞，至於 hackerone 為什麼堅持這樣，我也不知道 😑</p>
]]></content>
  </entry>
  <entry>
    <title>AI 軟體開發第三時代</title>
    <id>https://blog.huli.tw/notes/ai-dev-third-era/</id>
    <link href="https://blog.huli.tw/notes/ai-dev-third-era/"/>
    <updated>2026-05-06T04:48:47.543Z</updated>
    <published>2026-03-02T11:32:59.000Z</published>
    <content type="html"><![CDATA[<p>早上看到 <a href="https://cursor.com/zh-Hant/blog/third-era">Cursor</a> 的部落格發了一篇文章《The third era of AI software development》，裡面把 AI 軟體開發分成三個時代，覺得滿贊同的來聊一下，順便寫一下上次提的用 AI 做逆向工程的心得。</p>
<p>第一個時代是 Tab 自動補完，也就是最早期的 GitHub Copilot 在幹的事情，當初 Cursor 剛出來的時候也是這功能。</p>
<p>第二個時代是 AI agent，也就是現在大部分軟體工程師都在幹的事情，讓 AI agent 幫你寫 code。在一年前的時候，使用 Cursor tab 的人是 agent 的 2 倍，而現在已經顛倒過來了，我自己也很少用 tab 了。</p>
<p>而第三個時代就是我上週提過的 Cloud agents，本地用 agent 有其限制，例如說某些資源還是共用，同時也沒辦法真的開到太多太多 agent，還是一個我認為滿重要的限制是「你要有台電腦」。</p>
<p>而 Cloud agent 就是最理想中的形式，你只要在 web 介面上說一句話，背後就有 agent 去幫你開發，跟在本機電腦一樣。幫你開發完測完之後，你去 review 就好。</p>
<p>這個第三個時代的轉變，讓我們脫離了「一定要有電腦」這個限制，你在下班回家的捷運上突然有個 production issue，打開 cloud agent 叫他分析 log 然後把 bug 修掉，發 PR、merged、deploy，可能你還沒到家事情就解決了。</p>
<p>其實已經有不少人現在就是走這個開發模式了，大多數我看到的是一些熱情投入 AI 的個人開發者，至於公司的話，之前提過的 Stripe 就是，一定還有別的公司也是只是我懶得找。</p>
<p>不過第三個時代的門檻較高一點，你要先把開發環境準備好，而且還要同時有多個，不像第二個時代你都跑在自己電腦上，自己建好就行。或許再過個兩年，大多數人都會進入第三個時代，把大部分開發都丟到雲端去，隨時隨地都可以 coding。</p>
<p>想先體驗這個時代會長怎樣的，現在就可以找一些工具來用了（如上次介紹的 Cursor cloud agent），這是現在就做得到的事情。某個層面有點類似 OpenClaw 小龍蝦那樣，你給他環境跟機器，下指令他就會做事。</p>
<p>最後來寫一下用 AI 逆向工程的心得，我對逆向工程幾乎沒研究，除了學生時期修組合語言的時候，期末 project 做的是逆向某個小軟體，把 jmp 改成 nop 以外，就沒碰過逆向了。</p>
<p>這次因緣際會拿到一個 Golang HTTP server 的 binary，想說來試試看現在結合 AI 可以做到什麼地步。一開始我直接先召喚 agent 出來，它就先用 strings 去猜各種字串，最後撈到一些參數跟 URL，其實也滿有用的。</p>
<p>但這樣還不夠，於是我裝了個 <a href="https://blog.huli.tw/2026/03/01/reverse-engineering-with-ai-ghidra-mcp/">Ghidra</a> MCP 再裝了個專門分析 Golang 的 plugin，再搭配我平常在用的 Cursor，直接在上面跟他說「幫我逆向這個程式並給我一份報告」，他就產出了一份報告說明這是什麼東西，然後把 API endpoints 都列出來。</p>
<p>那時我可以感受到跟外行 vibe coder 相同的喜悅，也就是「我以前認為這麼困難的領域，沒想到靠 AI 就能讓我產出成果，AI 太神啦」，不過我對逆向工程還是抱持著一顆敬畏的心，依舊佩服那些會這個技能的人。同時，我也不覺得 AI 在這件事情上可以完全取代人類，AI 逆向出來的結果有些是錯的，有些也有幻覺，還有進步空間，我給的也只是隻小程式，沒試過更複雜的。</p>
<p>詳細的心得跟步驟昨天寫在部落格了，有興趣的可以看一下。總之呢，心得就是 agent + MCP 組合技真的好用，大力推薦。</p>
]]></content>
  </entry>
  <entry>
    <title>雲端 Agent 開發時代</title>
    <id>https://blog.huli.tw/notes/cloud-agent-development/</id>
    <link href="https://blog.huli.tw/notes/cloud-agent-development/"/>
    <updated>2026-05-06T04:48:47.547Z</updated>
    <published>2026-02-26T12:45:13.000Z</published>
    <content type="html"><![CDATA[<p>現在業界對於 AI coding 的使用，到底是怎麼個用法呢？剛好最近看到一些可以連起來的東西，簡單寫一下。</p>
<p>金流服務 Stripe 最近發了一篇文章，介紹他們自己打造的內部工具 <a href="https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents">Minions</a>，你可以直接從 Slack 上面 tag 他，跟他說要做什麼，他就會自己起一個環境（內部叫 devbox，一個 EC2 instance 上面已經把環境弄好 ），把任務完成之後發 PR 讓你 review。</p>
<p>然後他們用的 coding agent 是從開源專案 goose fork 出來改的，看來大公司還是有挺多東西需要客製化的。</p>
<p>在兩三年前雖然也有這種概念（AI 軟體工程師如 Devin），但在當時看來我還覺得有點遠，模型還沒這麼厲害，但是在 2026 的現在，是 100% 可以做到的東西，更是有些公司內部已經在使用的服務。</p>
<p>但不要看 Stripe 做得到，就以為每間公司都行，要這樣做至少要有兩個前提：<br>(1) 你的測試要足夠<br>(2) 你要能把環境建起來</p>
<p>Stripe 是因為本來就有很多測試，所以 AI 改壞可以自己修，直到測試通過為止，人 review 的時候可以減少很多心智負擔，因為 test coverage 夠齊全，至少不會歪到哪去。</p>
<p>但很多公司連測試都沒有，想這樣做要嘛工程師花些心力 review，要嘛相信 AI 足夠強，直接勇敢按下 merge。</p>
<p>剛好這兩天 <a href="https://blog.cloudflare.com/vinext/">Cloudflare</a> 宣布他們用 AI 花了一週把 Next.js 遷移到 Vite 上面，然後只有一個工程師在負責指揮，就搞定了。</p>
<p>在他們的文章中也有清楚提到，這次遷移能順利的理由是完整的 AI 文件以及全面的測試案例，否則不可能這麼順利。這個再次強調了測試的重要性，當你的測試夠強，就能讓 AI 自主工作變得更有效率。</p>
<p>現在已經很多人直接 claude code 或其他 AI agent，跑一次就把任務完成了，而 Stripe 那種模式可以想成把你的本地環境搬一份到雲端，就可以享受隨時隨地叫 AI 工作的快感。</p>
<p>那如果你也想體驗這種快感該怎麼做呢？</p>
<p>剛好這兩天 <a href="https://cursor.com/blog/agent-computer-use">Cursor</a> 的 Cloud Agent 改版，它就是一套雲端的 agent，我已經體驗過了，感覺很不錯。</p>
<p>把 GitHub repo 權限開給他以後，agent 會自己從 repo 中去探索怎麼把服務跑起來，然後還會錄影片給你證明它完成了。若是 agent 卡住，你可以中斷它然後幫他操作，這邊是直接有一個雲端桌面可以操控，一個 Xfce 的 Linux 環境。</p>
<p>比如說像我的專案需要登入，在 setup 過程中 agent 發現後就自動在 setup 區塊說他需要帳號密碼，直接多了兩個輸入框出來讓我填。</p>
<p>在環境配置好以後，就會存 snapshot，之後每個任務都只要出一張嘴，agent 就會自己把環境跑起來，然後完成你交代的任務，之後發 PR 等你 review，就像是 Stripe 的文章中所描述的那樣。</p>
<p>整體的體驗滿不錯的，專案建置上沒什麼問題，Electron 它也跑得起來。只是在操控上面因為是用 computer use 所以滿燒 token，我今天讓它試著在 desktop app 上做一個新功能，大概花了 30 分鐘，燒了 2000 萬個 token，似乎是 10 美金左右。</p>
<p>未來 cloud agent 我猜也會越來越普及，只是在資安以及環境建置這塊要怎麼處理會比較麻煩（例如說有些服務在公司內網），但用起來感覺不錯就是了。</p>
<p>總之呢，從我自己的日常開發以及這些大公司的部落格中，很明顯可以看到軟體工程師把任務交給 AI 跑已經是常態了，不要再用什麼網頁版，你用 claude code 也好 open code 也好 Codex 也好 Cursor 也好，反正有個 agent 可以幫你跑任務就對了。</p>
<p>我自己日常開發還是用 Cursor，下次再寫一篇我最近怎麼用 Cursor 搭配其他工具，幫助我這個外行人逆向一個 golang binary 吧。</p>
]]></content>
  </entry>
  <entry>
    <title>用 CSS 寫出 CPU</title>
    <id>https://blog.huli.tw/notes/css-x86-emulator/</id>
    <link href="https://blog.huli.tw/notes/css-x86-emulator/"/>
    <updated>2026-05-06T04:48:47.548Z</updated>
    <published>2026-02-24T11:36:33.000Z</published>
    <content type="html"><![CDATA[<p>有寫過網頁的人可能知道 <a href="https://lyra.horse/x86css/">CSS</a> 很厲害，可以用純 CSS 來寫遊戲，無論是 2D 或 3D 的都行。</p>
<p>但我今天看到了個更厲害的，用 CSS 寫了個 x86 CPU 模擬器！把 C compiled 變成 machine code 之後，可以把它交給 CSS 去跑。</p>
<p>有點類似於有些人在 Minecraft 裡面也會搞出一台電腦或是 CPU，不過弄在 CSS 上從我的角度看來是更厲害的，因為它能用的東西更少一點。</p>
<p>至於原理的話，作者之後會寫個部落格談談自己用到哪些技巧，目前看起來是受兩年前另一篇文章《Expert CSS: The CPU Hack》的啟發，透過 animation + keyframe 為基礎去弄出一個 loop，剩餘的就是一堆計算跟儲存了。</p>
<p>補充文章：<a href="https://garethheyes.co.uk/">https://garethheyes.co.uk/</a></p>
]]></content>
  </entry>
  <entry>
    <title>手機定位與 AI 洗稿</title>
    <id>https://blog.huli.tw/notes/carrier-gps-ai-rewrite/</id>
    <link href="https://blog.huli.tw/notes/carrier-gps-ai-rewrite/"/>
    <updated>2026-05-06T04:48:47.546Z</updated>
    <published>2026-02-20T03:09:42.000Z</published>
    <content type="html"><![CDATA[<p>剛剛在讀一篇之前存起來的文章《Your Phone Silently Sends GPS to Your Carrier — Here’s How》，內容大意是手機的組成分成兩塊，一塊是應用晶片(Application Processor, AP)，大家常用的 iOS&#x2F;Android 都在這上面，另一塊是基頻晶片(Baseband Processor, BP)，負責處理 2345G 那些手機原有的通訊功能。</p>
<p>而 BP 上有個 protocol（RRLP&#x2F;LPP）可以讓電信商拿到你的 GPS。由於是在 BP 上，所以不是 Android 跟 iOS 這些應用層可以干涉到的，就算你把什麼權限都關了也沒用，它是直接從更底層去拿的。這功能的本意是在緊急狀況時能夠有方法定位到手機，因此有了這個協定，但既然這功能是存在的，就代表會有被濫用的可能性。</p>
<p>文中有舉了一些例子，例如說在美國經過法院許可之後就可以跟電信業者去申請（不過標準不太統一）以及美國電信業者之前出售 GPS 資料的新聞等等，還有以色列在疫情時也運用手機定位去做隔離。</p>
<p>文章最後則是提到 Apple 從 iPhone 16e 開始自己做了 BP 的晶片（C1 Modem），所以可以突破 AP 跟 BP 間的隔離，提供了針對位置隱私的防護措施，能夠限制可以取得的數據。</p>
<p>看完之後，我第一個想到的是中華電信在疫情時也有過類似的新聞，查了一下說是透過基地台定位，沒有提到更具體的技術：</p>
<blockquote>
<p>利用手機和基地臺之間的相對位置概略定位，電信業者定時監測手機所連接的基地臺</p>
</blockquote>
<p>以色列當時所做的類似措施，也沒有提到具體技術，所以也不知道是透過基地台去定位，還是真的用了前面提過的 LPP 協定去定位。</p>
<p>接著我想找更多相關討論，於是拿標題去 google，反而找到了另外一篇《Mobile carriers can get your GPS location》，內容提到的東西與開頭看的那篇極為雷同，但是順序不一樣，這篇是先提 Apple 的那個新措施，然後才講到那兩個通訊協定，以及實際追蹤過的範例。</p>
<p>這篇發文的時間是 1&#x2F;31，開頭那篇發文時間是 2&#x2F;1，讓我開始思考，會不會我原先看的那篇，其實是這篇經由 AI 改寫並且補充的版本？</p>
<p>我目前唯一能找到的間接證據是文中有一個「HAR2009」的連結引用，點下去是 404 Not Found，這個連結會在短短一個月內突然失聯的機率偏低（用 Wayback Machine 查過了，上次存檔就在 2009），有沒有可能是 AI 寫完之後作者沒確認就放進來了？如果是真人寫的，應該不會放個 404 才對。</p>
<p>不過除了這兩篇提到的東西真的很雷同以外，目前也沒有其他一刀斃命的證據可以證明什麼，只是我的懷疑而已。</p>
<p>沒想到只是看個 GPS 追蹤的文章，還可以弄出個案外案（？）</p>
<p>總之呢，我的感想是：</p>
<ol>
<li>不管實際是用什麼技術（三角定位也好，古老協議也好），電信公司都有能力可以追蹤你的位置（但我還是滿想知道具體到底是不是用到這個 protocol）</li>
<li>有沒有可能以前看過的好文章，是 AI 洗稿而來的？或更進一步思考，AI 改寫的比原文好的話，身為讀者我該用什麼心情去面對？</li>
</ol>
]]></content>
  </entry>
  <entry>
    <title>Typeless 隱私檢查</title>
    <id>https://blog.huli.tw/notes/typeless-privacy-check/</id>
    <link href="https://blog.huli.tw/notes/typeless-privacy-check/"/>
    <updated>2026-05-06T04:48:47.558Z</updated>
    <published>2026-02-13T12:11:55.000Z</published>
    <content type="html"><![CDATA[<p>有個叫做 Typeless 的 app，就如同其名一樣，希望讓大家從打字中解放，用語音輸入就可以把許多事情搞定。據說很好用，用的人不少，但近期有人指出可能有些資安上的疑慮，因此我好奇把它拆開來看了一下。</p>
<p>話說在這個人手一個 AI agent 的時代，其實把它拆開來很容易，你就跟你的 AI agent 說它是個 Electron App，它就會找到 asar，解開，然後分析裡面的 JavaScript。就算不講它是 Electron，我相信 AI 應該也能判斷得出來。</p>
<p>首先是語音辨識的部分，是 100% 雲端沒錯，你的語音輸入外加 context 都會被送到他們的 server。不過這點其實他們官網就有寫，我預期使用者在用之前應該也會知道？</p>
<blockquote>
<p>Cloud Processing: Transcription is performed on the cloud to ensure the highest accuracy and low-latency performance.</p>
</blockquote>
<p>但在安裝使用的時候，確實有一行標題寫說：「所有數據保持本地」，敘述是「所有歷史紀錄都保留在你的設備上」，這倒是有一點誤導，敘述是對的，但標題的「所有數據」並不包含你的語音。</p>
<p>然後順帶一提，還有一個標題寫「零數據保留」，根據我的淺薄理解，零數據保留其實跟雲端是不衝突的。你可以把資料傳到雲端，但 service provider 又宣稱沒存你的數據。</p>
<p>至於是不是真的呢，第一看你信不信任這間公司，第二看有沒有拿什麼第三方合規認證，這就見仁見智了。很多大公司的雲端產品也都有零數據保留相關的 policy。</p>
<p>把話題拉回來，那 Typeless 除了語音辨識以外還會幹嘛呢？看了一下，主要就是收集語音辨識時需要的 context，這 context 包含現在 focus 的應用程式、標題、URL（如果是瀏覽器）、input 內的文字以及當前畫面能看到的文字等等，具體請求內容我放截圖了，這是我在 Github Issue 上面留言，所回傳 server 的資料。</p>
<p>我自己是覺得這些 context 還算合理啦（儘管完整 URL 跟 visible screen content 應該有些人會覺得有點可怕），就真的是語音辨識的時候需要用到，藉由這個 context 能讓結果更強。</p>
<p>至於按鍵監聽的部分，是拿來做熱鍵偵測沒錯，但我也不確定常見做法是什麼（Electron 也有內建，不過我沒用過），至少沒看到把按鍵資訊直接回傳。</p>
<p>總而言之呢，作為一個立志要讓語音辨識變得超好用的 app，目前的 context 看起來還算合理，至少從原始碼中沒看到它偷傳什麼奇怪的資料，不過有幾點是肯定的：</p>
<ol>
<li>語音會被傳到 server</li>
<li>context（內容見附圖）會被收集並傳到 server</li>
</ol>
<p>知道這些以後要不要使用，就看每個使用者自己了。</p>
<p>有些人覺得這些資料是合理的，是必要的，就繼續用。有些人可能覺得它拿的東西太多，或甚至有些人希望語音永遠留在本地不要上雲，這都是每個人的選擇。</p>
<p>然後我也只是隨便看了幾眼，程式碼靠 AI 幫我先看過一輪我再稍微對照，只確認了一下請求格式，然後弄個 proxy 實際看一下傳了什麼，不是很認真的研究。</p>
<p>話說我弄 proxy 的時候搞半天沒攔到東西，讓 cursor 一出手就搞定了，直接幫我把 asar 弄出來、patch 完然後塞回去，順便重新 sign 了一下 app，真的厲害，佩服佩服。雖然我自己弄也搞得定，但是出一張嘴就有人幫我辦事再好不過了。</p>
]]></content>
  </entry>
  <entry>
    <title>AI 搶先找出漏洞</title>
    <id>https://blog.huli.tw/notes/vulnerability-spoiler-alert/</id>
    <link href="https://blog.huli.tw/notes/vulnerability-spoiler-alert/"/>
    <updated>2026-05-06T04:48:47.559Z</updated>
    <published>2026-02-12T13:19:42.000Z</published>
    <content type="html"><![CDATA[<p>快速分享個昨天在推特上看到的有趣小專案</p>
<p>有個資安研究員 Eugene Lim 做了「Vulnerability-spoiler-alert」，原理是去掃幾個固定的開源專案，用 AI 去看最新的 commit 是不是在修漏洞，是的話反推回漏洞以及寫個 PoC。</p>
<p>由於一定是先發 commit 修完漏洞，然後才發版，所以如果有掃到的話，可以在發版前或是 CVE 公布前就先知道漏洞，因此作者把它稱為「<a href="https://spaceraccoon.dev/discovering-negative-days-llm-workflows/">Negative</a>-Days」（但其實就算是一種 0 day 啦，不過稱為 negative day 確實也滿有趣的）</p>
<p>原始碼、相關文章以及網站本身都是公開的，最新的戰績是在 Grafana 提前找到了兩個那時尚未公開的漏洞：CVE-2025-41117 (XSS) and CVE-2026-21722 (Privesc)</p>
<p>雖然一定會有一些 false positive，但看起來成本應該沒有很高，而且達到的效益滿不錯的。</p>
<p>補充文章：<a href="https://vulnerabilityspoileralert.com/">https://vulnerabilityspoileralert.com/</a></p>
]]></content>
  </entry>
  <entry>
    <title>AI 自主社群的疑問</title>
    <id>https://blog.huli.tw/notes/ai-social-autonomy/</id>
    <link href="https://blog.huli.tw/notes/ai-social-autonomy/"/>
    <updated>2026-05-06T04:48:47.544Z</updated>
    <published>2026-02-02T12:12:19.000Z</published>
    <content type="html"><![CDATA[<p>其實我一直很疑惑為什麼許多人這麼相信 moltbook 是「完全由 AI 自主發起討論」的社群。</p>
<p>Moltbook 就是個平台，提供了一個 markdown 檔案說明該如何使用，你把 markdown 貼給 AI，AI 讀完之後讓你幫忙驗證，驗證完發一個 token，然後 AI 就可以用這 token 去 Moltbook 發文。</p>
<p>那…有什麼能阻止我自己用這個 token 假裝是機器人發文？或是，我難道不行跟我的 AI 講話，叫他去發個要毀滅人類的文嗎？發文就是拿 token 呼叫 API，真人做得到，AI 也做得到。</p>
<p>也就是說，我們其實沒辦法知道那些文章是 AI 「自主」發的，還是人叫他發的，或甚至是人假裝 AI 發的，這一點都不黑鏡。</p>
<p>我自己覺得最黑鏡的一刻是約一年前，我意識到「現在」就已經能做到黑鏡演出的科技。黑鏡有一集講親人過世之後用 AI 模擬聲音、講話內容等等，製造出一個分身，這個現在應該就做得到了？模擬聲音絕對可以，講話內容的話，拿各種本人資料喂給 AI 感覺也行，資料越多越逼真，看起來更像真的記憶？</p>
<p>如果要講 AI 發文，比起 AI 自己建一個社群討論，我覺得那些利用 AI 技術潛藏在人類中不被發現的魔族才更厲害，而且這已經是現在進行式了。你在追蹤的粉專或是網紅，也不一定是個真人，AI 發文、AI 回覆、AI 產圖，誰知道呢。</p>
<p>就算原本是真人，也可能在某個時間點主動讓 AI 奪舍，「可以用 AI 發文好方便欸，我就不用自己寫了」，儘管讀者不一定喜歡，但會在意的人又有多少呢？</p>
<p>既然都講 Moltbook 了，順便來講一下 OpenClaw（前 Moltbot 前前 Clawdbot），先承認我沒裝，我沒用過，所以底下都是一個沒用過的人打嘴炮，沒有參考價值。</p>
<p>我自己覺得 OpenClaw 成功的地方在於展示了一個真正的 AI 助理可能會長怎樣，因為它有整台機器的控制權，所以工具寫得好的話，想幹嘛就幹嘛，好像真的有個秘書在那邊一樣，而且記憶那塊好像也做得不錯。</p>
<p>但當然，你得付出的是一些安全性的代價，越方便的東西往往越不安全，我建議不管你用什麼環境架它，都要有個心理準備：「你整個環境都會是開放的，是會被駭的」，在這個前提底下去使用它。</p>
<p>所以你可能不會想把信用卡號放上面，給他的 AI token 也會設好使用上限，不會給他郵件的帳號密碼，只會用它來做一些就算資料被偷也沒什麼損失的事情。不過在這種前提下，可能方便度就減少很多了。</p>
<p>話說，虛實整合這一段我倒是滿感興趣的，我有看到那個什麼它的小龍蝦訂位失敗所以自己打電話的故事，但真實性存疑就是了，仔細看應該是事主自己額外又教了 AI 怎麼打電話，而不是 AI 主動學習。</p>
<p>當有服務提供 API 讓人打電話跟接電話時，接入 AI 就可以把虛擬接入現實，客人用 AI 幫忙打電話預約，商家用 AI 幫忙接電話，自動把訂位接入系統。（不對啊，你用 AI 我也用 AI，那幹嘛不網路訂位就好或乾脆餐廳提供個 API，幹嘛還要過一層電話。應該是個過渡期，給那些只會用電話的人）</p>
<p>話說這些其實也是現在進行式了，早就有人在做了，只是我還沒研究過台灣有沒有能夠打電話 + 聽語音的 API。</p>
<p>寫了這麼多，總而言之呢，我自己認為 OpenClaw 是個成功的產品而且滿有趣的，但我自己暫時不會想用（懶惰且沒這需求，我也懶得因為要寫貼文去用），而 Moltbook 在我沒理由相信真的是 AI 全自主發文的前提之下，更是一點興趣也沒有。</p>
]]></content>
  </entry>
</feed>