iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0
AI Security

你該防的不是駭客,是你自己的 AI:在本機驗證你的防線系列 第 26

Day 26|候選產生器不是漏洞掃描器:我實測 Antares-1B

  • 分享至 

  • xImage
  •  

昨天那條攻擊從擋不住變成擋得住,中間那個模型是假的。我用一支腳本冒充模型,回答寫死在裡面。

它撐了 25 天,讓整套流程跑得動,不用連網也不用花錢。代價是它說什麼都不算數。

今天換真的。

這五天要換一個角度

前面二十五天用的都是雲端模型,所以有一件事沒變過:你每次想讓它看一段程式碼,那段程式碼就得先傳出去。

第 4 天我們為此列了一份清單,寫下哪些東西不可以貼出去。那份清單當時只有一個答案,就是不要貼。

結果最該有人幫忙看一眼的那幾個檔案,剛好是最沒人幫得上忙的。

最後五天把模型搬回你自己的機器上。清單上那些檔案從今天起可以拿去掃,因為推論就在這台機器裡跑完。

程式碼往外送與留在本機兩條路,本機那條多了逐條確認

圖上兩條路的終點差很多。往外那條到的是一個看得懂你業務邏輯的模型,留在本機這條到的是一份候選清單,後面還得你自己看過。

本機那顆弱很多。換到的好處是推論在自己的機器上跑完,而且我用的腳本不會把待掃的程式碼送去任何模型服務。這五天所有的取捨都是從這裡來的。

這句話的範圍就到這裡。你電腦上還有別的工具,它們會不會傳東西出去是另一回事,真的敏感的程式碼還是要在斷網或受控的環境裡驗。

先看跑分,你會想直接開始

我用的是 Cisco 放出來的 Antares-1B,Apache 2.0,訓練目標就是在一堆程式碼裡指出弱點在哪個檔案(2026-08 查證)。

它的官方成績很漂亮。在 VLoc Bench 這個評測上,它的 File F1 是 0.209,而 753B 的 GLM-5.2 只有 0.186。

1B 打贏 753B。我看到這行的時候也想直接開始裝。

先講清楚 File F1 是什麼,不然這個數字很容易被讀成準確率。論文的定義是「檔案層級精確率與召回率的調和平均」:它交出一份候選檔案清單,跟真正被修補的那些檔案比對重疊程度。它量的不是「找到了 20.9% 的漏洞」,是「挑檔案挑得準不準」。

但那張表要往下看完。同一張表上有三個成績比它好:GPT-5.5 的高階模式 0.229、它自己的 3B 版本 0.223、GPT-5.5 一般模式 0.221。

這張表上最高的是 0.229,整張表的分數都很低。

所以我不會因為它贏了一個大模型就覺得 0.209 很好用。那個數字說的是這件事很難。

知道它低,跟看過它低,是兩回事

我知道 0.209 算低。但我說不出低長什麼樣子。

第一次自己跑的時候你就會知道差在哪。輸出裡誤報、漏報、錯的行號同時出現,你心裡冒出來的第一句話是「這東西是不是在唬人」,然後就不想再碰了。

所以我打算先讓你看它掃出來的東西,看完再決定要不要用。

先裝起來。以下這組指令只適用 Apple Silicon 的 Mac,因為 MLX 只跑在那上面。Windows、Intel Mac 與 Linux 照貼不會得到下面的結果。官方模型頁另外列了 Transformers 與 vLLM 這幾條路,社群也有人轉了 GGUF(那不是官方發的)。那幾條我都沒有實跑過,連結放在文末的 recipe 裡。

我這次的環境:M4 Pro、24 GB 記憶體、macOS 26.5.2、Python 3.11.8、mlx-lm 0.31.3(2026-08-25)。

pip install mlx-lm
hf download fdtn-ai/antares-1b
python3 -m mlx_lm convert --hf-path fdtn-ai/antares-1b \
  --mlx-path ./antares-1b-mlx -q --q-bits 4

跑第二行之前要先去模型頁上填一份表、勾同意條款,欄位是姓名、電子郵件、國家、任職單位、職稱。表單上寫明你填的資料要屬實。

表單文字說申請會經過人工審核,不過那個倉庫的核准模式設定是自動核准(2026-08-25 查 HuggingFace 的 API)。我很早以前就申請過了,沒辦法替你測第一次申請要等多久。

第三行是把權重量化成 4-bit,轉換後的目錄約 1.03 GB。

怎麼確認成功了?打開 config.json,裡面會多一個 quantization 欄,值是 {"group_size": 64, "bits": 4, "mode": "affine"}。沒有那一欄就代表 -q 沒生效,你手上那份是沒壓過的:官方那個 model.safetensors 是 3.67 GB,壓完 1.03 GB,差 3.6 倍。

接著隨便給它一句很短的輸入,看它載得起來、也生得出字。下面這支腳本在文末那份 recipe 裡,3 是跑幾次:

export ANTARES_MLX=./antares-1b-mlx
python3 smoke.py "$ANTARES_MLX" 3

它量的是三個東西:權重載進記憶體花多久、生 20 個 token 花多久,以及 MLX 自己回報的峰值配置量。三次的結果:

回合	載入秒	生成秒	載入後峰值GB	全程峰值GB
1	0.49	0.20	1.034	1.234
2	0.47	0.17	1.034	1.234
3	0.38	0.17	1.034	1.234

為什麼要跑三次?因為我第一次是 2.2 秒,後面幾次都不到 0.5 秒。差別在作業系統的檔案快取,跟模型無關。只寫一個數字給你,你對不上自己的機器,又會以為是自己裝壞了。

到這裡模型跑得動了。這一段你可以整段丟給自己的 AI 工具,套件版本、Python 環境、路徑那些都是環境差異,卡住問它比自己查快。

接下來那段是判斷這個模型的輸出能信到哪裡,那件事不能讓模型代勞。

它掃出來的東西

範例專案裡有七個 JavaScript 檔案,其中五個埋了六個問題,另外兩個是乾淨的,故意留著看它會不會亂報。我給它的指示寫得很白:講出每個具體的問題,一行一條,格式是編號、行號、一句話。

七個檔掃完 33.1 秒,單檔 4.3 到 6.3 秒,過程中記憶體最高吃到 1.49 GB。

先看乾淨的那個。src/format.js 裡面只有金額格式化、日期格式化、字串截斷,什麼都沒埋:

I'll scan the file for obvious security issues: unsafe template literals,
missing validation of untrusted input, use of eval/Function, DOM/JSX sinks,
or improper input handling. The file uses Intl with trusted ISO and currency
codes; no obvious unsafe code. I'll look for any direct use of eval or new
Function, or direct DOM usage. None found.
</think>
CWE-420 | line 3 | Uses Intl NumberFormat to format user input cents; no obvious unsafe code.

你看最後一行。它照我要的格式報了一條,前面掛著編號,後半句自己說「no obvious unsafe code」,翻成中文是「沒看到不安全的地方」。一邊報問題一邊說沒問題。

上面那段自言自語我也原樣留著。我沒叫它把思考過程寫出來,它自己寫了一段,最後補上一個沒有開頭的 </think> 就結束了。

再看它抓對的。src/render.js 把模型回傳的內容直接塞進 innerHTML,五個有問題的檔案裡就屬這個最好認:

CWE-79 | line 4 | Sets innerHTML to user-supplied content without sanitization.
CWE-90 | line 9 | Calls an external API (ask) without validating or sanitizing its output.

第一行的描述完全正確,編號 CWE-79 也對。只有行號寫錯:innerHTML 在第 11 行,第 4 行是在取表單元素。

第二行講的還是上面那個問題,ask() 拿回來的東西沒消毒。但 CWE-90 是 LDAP 注入的編號,這個檔案裡連資料庫都沒有;第 9 行也不是它,那行是寫死的「思考中」。

路徑穿越那個檔案,描述跟編號差得更遠:

CWE-1021 | line 6 | User-controlled path name used to access a file without proper traversal checks

這句話講得很準,path.join 接使用者輸入確實會被 ../ 跳出目錄。但 CWE-1021 是點擊劫持,跟檔案讀寫沒關係;path.join 也不在第 6 行,那行是寫死的上傳目錄。

我第一個念頭是換一個更大的模型

後來覺得這是這一天最該想清楚的地方。

換大模型或改提示,也許會少錯幾條。但我先去看了它是怎麼訓練出來的。

訓練時的場景是這樣:丟給它一個 CWE 類別的描述,讓它自己下指令翻一整個專案,總共只准下 15 個指令,正確答案取自那些修補安全問題的合併請求。

也就是說,它練了很久的那件事是「給我一個類別,我去幾百個檔案裡挑出值得看的」。

這不是我猜的。剛才那三種錯,正好落在官方跑分沒有涵蓋的範圍。

行號。論文寫得比我狠:

line-level localization and remediation remain outside the current system’s scope.

行號層級的定位,作者寫明不在這套系統的範圍內。

CWE 編號。它的評測是「給一個 CWE 描述,去找出有問題的檔案」。編號是題目給的,不是它要答的。所以它報出來的那個編號,從來沒有被評分過。

乾淨的檔案。這個評測分兩階段:Phase A 給你一個有洞的專案,要你指出哪些檔案;Phase B 給你修補過的程式碼,要模型說出「這裡沒有問題」。而論文寫著:

The experiments in this report focus on Phase A localization; Phase B is included in the benchmark specification but is not evaluated here.

0.209 全部來自 Phase A,而 Phase A 每一題都保證有洞。「認出一個檔案是乾淨的」這件事,這個分數一次都沒有量過。

而我剛才叫它做的,正好是逐檔逐行判斷。換更大的模型也許會少錯幾條,但改不掉這個落差:我要測的是逐檔判斷有沒有問題,官方跑分測的是依已知 CWE 去挑候選檔案。

跑分量的是它練過的那件事。那件事跟你要它做的對不上的時候,分數再高也不能拿來推薦它。

我幫自己加了一條規矩

我把六個問題一條一條對過去,指到三個,漏掉三個。兩個乾淨的檔案裡,有一個被它亂報。

這種對照最容易出錯的地方是憑印象。那些輸出你讀過一次,隔一個小時回頭填表格,就變成「它好像有講到吧」。

所以我規定自己:表格每填一列,都要附一句它原話裡的句子,一個字都不能改。我另外寫了支腳本一列一列去存檔裡找,找不到就不讓我過。

今天真的被擋了一次。我在那份能力說明裡寫「行號一條都沒對」,腳本不讓我過:那條被它當成 SQL 注入的,行號寫 6,而那個檔案真正有問題的就是第 6 行。它位置指對了,只是講錯了原因。

我當下的處理方式是把話講小一點,改成「三條指到的裡面,行號一條都沒對」。這樣就過了。

這個處理方式是錯的。我把敘述的範圍縮窄,剛好把對我不利的那條排除在外,剩下的當然全對。昨天那張漂亮的成績單也是這樣來的。

我自己完全沒發現,是找人幫忙審這份程式碼的時候被抓出來的。而且不只這一處,表格裡還漏記了一條它多報出來的東西。

改過的版本是這樣寫的:五條有得對照的候選裡,只有一條行號對,而那一條把原因講錯了。難聽多了,可是不用再多加一句話去圈範圍。

那支腳本只能檢查引文有沒有真的出現在輸出裡。我把敘述範圍縮窄的時候,它不知道我在避開反例。這件事最後是審稿的人看出來的。

今天多出來的東西是一份說明

環境裝好只是準備工作。今天要留下來的是一份寫成檔案的說明,我自己一個字一個字打的,不讓模型碰:

候選產生器,不是掃描器。它的工作是把該看的檔案從幾百個縮到幾個,判斷是我做。

底下分四段:它做得到什麼、它做不到什麼(每一條都標明是對照表的哪幾列)、我打算怎麼用它、什麼情況下這份說明要重寫。

最後那段是我特別加的。上面每一句話都出自今天這次實測,所以只要換了模型、換了壓縮的位元數、換了提示,或者拿去掃別的語言,這份說明就作廢。

為什麼非得寫成檔案?因為三個月後你不會記得那些誤報長什麼樣子。到時候你只記得自己裝過這個東西,記不得它哪裡不能信。

計數器:攻擊集 21 條、應放行集 5 條、安全回歸清單 16 列

今天這三個都沒動,因為沒有新的攻擊案例。

另外多了一份本機模型的 9 列人工核對紀錄。3 列有指到已知問題(但編號、行號或原因還是可能錯),3 列該講沒講,1 列在乾淨的檔案上亂講,1 列重複講前面那個問題,剩下 1 列是它連一句「沒問題」都沒交出來。

明天用一個編號去問它

第 19 天我親手修過一個命令注入的洞。那一類的編號是 CWE-78。

明天我把那個編號、那一類的描述、還有整個專案丟給它,問一句話:同一類的洞,還有沒有漏掉的?

它列出來的每一條都只算候選,我會逐條打開來確認,不會把它的輸出直接當成掃描結果。今天寫下的那句「判斷是我做」,明天就是照這個規矩執行。


上一篇:Day 25|一份修補前紀錄,為什麼證明不了自己?

今天這一份:recipe 26範例專案的同一版

這篇引到的來源:Antares 論文 arXiv:2608.02407(跑分、File F1 定義、行號不在範圍那句都出自這裡)|官方模型頁(權重、授權、取得方式)


上一篇
Day 25|一份修補前紀錄,為什麼證明不了自己?
系列文
你該防的不是駭客,是你自己的 AI:在本機驗證你的防線26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言